Zafu: CouchDB and KendoUI (part 3)


In the previous posts I’ve explained how to deploy Kendo UI in CouchDB (here) and the four CRUD operations using CouchDB’s Standard JavaScript API (here).
On this post I will explain how to implement KendoUI DataSource transport commands using CouchDB.

Kendo UI DataSource Transport Read

1. Define map function for the view

Create in the root of your project a views and views/getTicks folders:

mkdir views
mkdir views/getTicks

and create a file named map.js as follow:

function(doc) {
  if (doc.type && doc.type === "tick") {
    emit(doc._id, doc);
  }
}

This map function emits each document in this DataBase that has type defined and equals ‘tick’. The key for the map function is the _id of the document and the value is the document itself.

2. Define the HTML for holding the grid

I will create a minimum HTML as follows

<div id="grid"></div>

3. Create Kendo UI Grid

Lets use the following code:

var grid = $("#grid").kendoGrid({
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

Where I define a grid showing two columns: Tick and Company and using a ticksDataSource as Data Source.

4. Create Ticks Model for using in Kendo UI DataSource

This is the Model for holding the information.

// Ticks Model
var ticksModel = {
    id:"_id",
    fields:{
        type:{ defaultValue:"tick", editable:false },
        tick:{ editable:true},
        name:{ editable:true }
    }
};

Where id define that the id is the same that CouchDB uses, plus three additional fields:

  1. type: The type of record (here it is always tick).
    This is a trick quite commonly used in CouchDB for knowing the type of information saved on each record. This is not like other DataBase Systems where I have one separate table for each type of record.
  2. tick: The tick of the company
  3. name: The Company name.

5. Create Kendo DataSource

I create ticksDataSource as follow:

// Create Grid for displaying data
var ticksDataSource = new kendo.data.DataSource({
    transport:{
        read:function (operation) {
            // Read data and populate it
            db.view("app1/getTicks", {
                        success:function (data) {
                            if (data.rows) {
                                var res = [];
                                $.each(data.rows, function (i, val) {
                                    res.push(val.value);
                                });
                                operation.success(res);
                            }
                        }
                    }
            );
        }
    },
    schema:{
        model:ticksModel
    }
});

Where I set the schema model to ticksModel that I have defined above and I define a read callback for Kendo Data Source transport. This callback is invoked each time the system needs to populate the grid.

For reading the data, I use view method of jquery.couch.js API that executes the view that I have defined above (app1/getTicks).

On success, I will get a JSON object containing an array with the records. So, I copy them into an auxiliar variable res and the return res as result by invoking operation.success(res).

And I get something like this:

Kendo UI Grid populated using DataSource transport read callback
Kendo UI Grid populated using DataSource transport read callback

Kendo UI DataSource Transport Create

Once I have implemented the callback for filling the grid, lets add the capacity for creating a new record.

1. Add button to the toolbar for creating record

I added a toolbar array containing an element equal to “create” to kendoGrid creation and specified the editable mode as popup:

var grid = $("#grid").kendoGrid({
    toolbar: [ "create" ],
    editable: "popup",
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

And I got:

"Add record" button in Kendo UI Grid toolbar.
“Add new record” button in Kendo UI Grid toolbar.

And if I click on “Add new record” button I get a popup window for introducing a new record:

Popup window for adding new record
Popup window for adding new record

But I did not implemented create callback into ticksDataSource transport so even I fill the form and click on update, the record is not saved in CouchDB.

2. Implement create callback

As well as I defined a create callback, I implement a callback for saving the form in CouchDB.

create:function (operation) {
    var data = operation.data;
    delete data._id;
    db.saveDoc(data,
            {
                success:function () {
                    operation.success();
                    dataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while creating document.");
                }
            }
    );
},

What I do is invoking saveDoc and if succeed then refresh the grid by invoking dataSource.read() and if it fails I inform the DataSource that it failed by finishing with an operation.error.

What I get is:

Result of adding a record
Result of adding a record

NOTE: that I delete _id before saving the document. This is important since KendoUI created this field as an empty string (“”) and if  I save a document with _id defined, CouchDB believes that this is the actual value for the _id but an empty string is not a valid identifier. Conclusion: I delete it before saving the document.

Kendo UI DataSource Transport Update

What I’m going to do is add an edit button to the toolbar and on click open a popup window with the document that is selected.

1. Add Edit button

Add a button to the toolbar for editing: change toolbar definition in grid to match:

toolbar:[ "create", "edit" ]

Getting:

Kendo UI toolbar with edit button
Kendo UI toolbar with edit button

But if you click on it it actually does nothing since KendoUI does not define a default callback for an edit button in the toolbar but in a row. That would look something like this:

KendoUI in row edit button
KendoUI in row edit button

And this time if I click on edit button I actually get:

Kendo UI grid with in-row edit button
Kendo UI grid with in-row edit button

But I don’t like this edit buttons using space on each row, so lets go back to the original one and add code for making it work.

2. Add callback to toolbar edit button

What I do is bind a click event to the button such as:

$(".k-grid-edit", "#grid").click(function () {
    alert("hello");
})

Clicking on edit button I actually get the alert with a hello message.

3. Make rows selectable.

To make a row selectable I added selectable:”row” but if in addition I want to be able to navigate using the mouse then in addition I include: navigatable:true. Now my grid definition is something like:

var grid = $("#grid").kendoGrid({
    toolbar:[ "create", "edit" ],
    editable:"popup",
    selectable:"row",
    navigatable:true,
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

And if I select a row it looks like:

Kendo UI grid with row selected
Kendo UI grid with row selected

4. Popup edit window for selected row

Previously I just open an alert when clicking on edit. Now, I’m going to find the selected row and open a popup with the actual content of the row.

// Edit implementation
$(".k-grid-edit").click(function (e) {
    var selected = grid.select();
    if (selected && selected.length > 0) {
        $.each(selected, function (idx, elem) {
            grid.editRow(grid.select());
        });
    }
});

And when I click on editbutton I get:

Kendo UI edit popup triggered by edit button in toolbar
Kendo UI edit popup triggered by edit button in toolbar

If I modify the company name from Apple to Apple Incand click on update I will see:

Row edited but marked as not synchronized
Row edited but marked as not synchronized

Where the company name is marked as modified but not saved in the database I can actually verify this by refreshing the page.

4. Implement transport update

I need to implement Kendo UI DataSource transport update for persisting the information in the database.

update:function (operation) {
    db.saveDoc(operation.data,
            {
                success:function () {
                    operation.success();
                    ticksDataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while updating document.");
                }
            });
}

If I do now edit a record and click on update I will see that the change becomes permanente and refreshing the page will show the information updated.

Kendo UI DataSource Transport Delete

Only one last callback to implement to have a full CRUD KendoUI DataSource implemented on CouchDB.

1. Add delete button

As for edit, Kendo UI library only implements the callback for delete buttons included in a row. But I will do the same that I did for edit.

The toolbar definition is:

toolbar:[ "create", "edit", "destroy" ],

The callback for when pressing the delete button (same code that edit but invoking grid.removeRow instead of grid.editRow):

// Delete implementation

// Delete implementation
$(".k-grid-delete").click(function (e) {
    var selected = grid.select();
    if (selected && selected.length > 0) {
        $.each(selected, function (idx, elem) {
            grid.removeRow(grid.select());
        });
    }
});

And the delete implementation in Kendo UI DataSource transport is:

// Delete implementation
destroy:function (operation) {
    db.removeDoc(operation.data,
            {
                success:function () {
                    operation.success();
                    dataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while deleting document.");
                }
            });
}

If I select a row and click on delete button I will get a prompt window asking for confirmation and I click ok the record is deleted.

If you liked this post please click on “like” in order to let me know that you are interested and keep writing about Zafu.

If you would like to propose some subject, you are also welcome!

And that’s it!!!

Advertisements

3 thoughts on “Zafu: CouchDB and KendoUI (part 3)

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