KendoUI DataSources + Dropbox DataStore: Change Listener


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:

Advertisements

2 thoughts on “KendoUI DataSources + Dropbox DataStore: Change Listener

  1. Hello! I am new to Kendo Environment. I was searching for a replacement of older ajax & asp.net controls. First I found Radcontrols. Now I am exploring KenbdoUI. Now I have a doubt. How can I add a SEQUEL SERVER database data as a datasource to Kendo Grid. I have surfed and read many blogs. But everything was vain. It would help me alot if you guide me with a simple application that contains a Kendo Grid retriving data from SEQUEL server and displaying it.

    • Hi,
      Kendo UI is about the User Interface, how to present data. It does not say nothing about how the data is stored in the server, they don’t care if it is MySQL, SQL Server, Plain Data Files or Document Oriented Data Stores as Documentum, Couchbase, CouchDB,…
      Now, you have two pieces: Storage (Model), Presentation (View). This is where Kendo UI “imposes” JSON or ODataSource as way for transfer data.
      Kendo UI runs on the browser.
      SQL Server in the server (back-end).
      I hope that this clarifies a little why you hear about JSON but not about what you have in the server or how to store data.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s