My last posts were about Dropbox DataStore and Kendo UI DataSource. I have demonstrated how to read, create, delete and update records.
And I have shown how the original example provided with Dropbox was able to listen for changes in my application and automatically synchronize those changes.
I want to do the same! When Dropbox sample code changes the DataStore content, I want that my grid automatically gets updated.
Event listeners in DataStore Dropbox
We have seen in previous videos how when we create, update or delete a record from our Grid, the HTML sample code from Dropbox magically gets updated. This is because Dropbox provide a mechanism for registering a function (a listener) to changes in the DataStore. What Dropbox library does is that when you updates the copy in Dropbox server, it notifies the library and this calls you.
dataStore.recordsChanged.addListener(function(ev) { // Event handler code... });
What we do in this event handler is either getting the changes and update the affected rows or fully update the table.
In my case and for simplicity, I’m going to update the complete Grid by invoking `DataSource.read()` method. Something like:
// Add listener for changes dataStore.recordsChanged.addListener(function(ev) { taskTableDS.read() });
NOTE: If I just add these lines of code to what I have in my previous post, I will get an error because in the current implementation I was expecting that the DataStore was opened only one: so I was not closing it and I could try opening it twice if DataStore.read happen to be called twice.
So I need to slightly change readTask code to control that the DataStore is alreayd open and not try to do it again.
function readTasks(op) { if (client.isAuthenticated()) { // Client is authenticated. Display UI. if (dataStore === null) { var datastoreManager = client.getDatastoreManager(); datastoreManager.openDefaultDatastore(function (error, datastore) { if (error) { alert('Error opening default datastore: ' + error); } dataStore = datastore; // Add listener for changes dataStore.recordsChanged.addListener(function (ev) { taskTableDS.read() }); taskTable = datastore.getTable('tasks'); op.success(taskTable.query()); }); } else { op.success(taskTable.query()); } } }
And the complete code is:
// Insert your Dropbox app key here: var DROPBOX_APP_KEY = '0sh....'; // Exposed for easy access in the browser console. var client = new Dropbox.Client({key: DROPBOX_APP_KEY}); var taskTable = null; var dataStore = null; // Try to finish OAuth authorization. client.authenticate({interactive: true}, function (error) { if (error) { alert('Authentication error: ' + error); } }); function parseItem(elem) { return { id : elem.getId(), taskname : elem.get("taskname"), created : elem.get("created"), completed: elem.get("completed") }; } function readTasks(op) { if (client.isAuthenticated()) { // Client is authenticated. Display UI. if (dataStore === null) { var datastoreManager = client.getDatastoreManager(); datastoreManager.openDefaultDatastore(function (error, datastore) { if (error) { alert('Error opening default datastore: ' + error); } dataStore = datastore; // Add listener for changes dataStore.recordsChanged.addListener(function (ev) { taskTableDS.read() }); taskTable = datastore.getTable('tasks'); op.success(taskTable.query()); }); } else { op.success(taskTable.query()); } } } function parseDropboxRecords(d) { var res = []; $.each(d, function (idx, elem) { res.push(parseItem(elem)); }); return (res); } var taskTableDS = new kendo.data.DataSource({ transport: { read : function (op) { readTasks(op); }, update : function (op) { var data = op.data; var id = data.id; // Remove id to do not have it duplicated delete op.data.id; var record = taskTable.get(id).update(data); op.success([record]); }, destroy: function (op) { taskTable.get(op.data.id).deleteRecord(); op.success(); }, create : function (op) { // Remove id to do not have it duplicated delete op.data.id; var record = taskTable.insert(op.data); op.success([record]); } }, schema : { model: { id : "id", fields: { id : { type: "string" }, taskname : { type: "string" }, created : { type: "date", editable: false }, completed: { type: "boolean" } } }, parse: parseDropboxRecords } }); $("#grid").kendoGrid({ dataSource: taskTableDS, editable : "popup", toolbar : ["create"], columns : [ { command: ["edit", "destroy"], width: 180 }, { field: "taskname", width: 80 }, { field: "created", format: "{0:G}", width: 200 }, { field: "completed", width: 70 } ] });
Which looks like: