Finsemble: Sharing Data

Sharing Data

This tutorial will walk you through using the DataTransfer Client to share data between components via drag and drop or via clicking objects.

The basic concept is that the source component needs to setup emitters and the destination component needs to setup receivers. The DataTransfer Client handles everything else.

Setting up Emitters

Here is how we setup the emitters in our premium chart component:

FSBL.Clients.DataTransferClient.setEmitters({
    emitters: [
        {
            type: "symbol",
            data: getSymbol
        },
        {
            type: "chartiq.chart",
            data: getChart
        }
    ]
});

Setting up emitters causes a drag icon to show up on the component:

Setting Up Receivers

Here is how we setup the receivers in our premium chart component:

FSBL.Clients.DataTransferClient.addReceivers({
    receivers: [
        {
            type: 'symbol',
            handler: function (err, response) {
                if (!err) { changeSymbol({ symbol: response.data['symbol'] }); };
            }
        },
        {
            type: 'chartiq.chart',
            handler: function (err, response) {
                if (!err) setChart(response.data['chartiq.chart']);
            }
        }
    ]
});

The receivers can also take regular expressions. Here is how we setup the receivers in a chat component that can receive anything:

FSBL.Clients.DataTransferClient.addReceivers({
    receivers: [
        {
            type: /.*/,
            handler: sendData
        }
    ]
});

If a component has receivers, the DataTransfer Client attemts to turn the body of the component into a drop zone. However this does not always work, especially on complex third party components. In this case, you can setup your own drop zone on document and use DataTransferClient.drop as the handler for the drop:

document.addEventListener('dragover', function(e) { e.preventDefault(); return false; });
document.addEventListener('drop', FSBL.Clients.DataTransferClient.drop);

Once you start dragging from a component, all components that can and cannot receive the data are highlighted with an overlaid scrim:

Dragging Items From Within a Component

Just using emitters and receivers is convenient to share items from a component that shows an individual item like a chart or a report. However, often items inside a component need to be shared, such as a symbol from a blotter, a contact or a report or an item from a list. In this case, the data can be attached to the dragstart event as in the example below:

element.addEventListener('dragstart', fuction(event) {
    var data = {
        'rsrchx.report': {
            url: event.target.href,
        }
    };
    FSBL.Clients.DataTransferClient.dragStartWithData(event, data);
})

If you are using jQuery events, you need to do this:

element.on('dragstart', fuction(event) {
    var data = {
        'rsrchx.report': {
            url: event.target.href,
        }
    };
    FSBL.Clients.DataTransferClient.dragStartWithData(event.originalEvent, data);
})

Automatic Linking and Publishing

The DataTransfer Client also provides the ability to handle shared data using other events like clicks instead of dragging and dropping. This also provides additional features like ability to automatically open components that can deal with a specific kind of data and integration with the Linker Client.

Here is some sample code from the salesforce component in our sales demo:

FSBL.Clients.DataTransferClient.openSharedData({
    data: {
        'salesforce.contact': {
            'objectid': 'salesforceObjectId
        }
    }
});

This code causes the DataTransfer Client to automatically open a component that can receive a data type of salesforce.contact. However, since receivers are only registered when components are launched, this requires that receiving components specify the receiver in their config:

"Salesforce Contact": {
    ...
    "component": {
        ...
        "advertiseReceivers": ["salesforce.contact"],
        ...
    },
    ...
}

If the source component is linked, the newly opened component will have the same linker groups as the source component. Once a linked component is open, subsequent shares automatically open in the linked component instead of opening new windows.

Sometimes it is desirable to not have the components automatically handle all received data. For example a chat component that receives data should not automatically share all published data on the chat, only data that is manually dragged and dropped. For such components, you can disable handling of such data:

FSBL.Clients.DataTransferClient.openLinkerDataByDefault = false;

You can also ignore the data based on the share method in case you want to handle some linked data but not all of it:

function sharedDataHandler(err, response) {
    if(response.shareMethod != FSBL.Clients.DataTransferClient.SHARE_METHOD.DROP) {
        return;
    }
    // Handle dropped data here:
}