ExtJS and ASP.NET MVC 3: CRUD DataGrid

This short tutorial will walk though the implementation of DataGrid using ExtJS 3.3.1 and ASP.NET MVC 3. In this tutorial I focus more on the integration of the front-end, so you will not find any database code. Whenever we deal with data we usually create, read/retrieve, update or delete them. ExtJS provides a great data grid component and the ability to perform CRUD operation with very little coding. I used JSON as data format in the example below.

ExtJS DataGrid
ExtJS DataGrid

Let’s start with the server-side by developing the data model and controller.

Controller:

    public class ContactController : Controller
    {
        //
        // GET: /Contact/

        public ActionResult Index()
        {
            return View();
        }

        public JsonResult Load()
        {
            var contact = new List<Contact> {
                new Contact("Smith","95746325","smith@me.com"),
                new Contact("Adam","87291034","adam@me.com"),
                new Contact("Eve","98271345","eve@me.com"),
                new Contact("Chun Li","81728312","chun.li@me.com")
            };
            return Json(new
            {
                total = contact.Count,
                data = contact,
            }, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult Create(List<Contact> data)
        {
            //insert Create code
            return Json(new
            {
                data = new Contact(data[0].Name, data[0].Phone, data[0].Email),
                success = true,
                message = "Create method called successfully"
            });
        }

        [HttpPost]
        public JsonResult Update(List<Contact> data)
        {
            //insert Update code
            return Json(new
            {
                success = true,
                message = "Update method called successfully"
            });
        }

        [HttpPost]
        public JsonResult Delete(List<string> data)
        {
            //insert Delete code
            return Json(new
            {
                success = true,
                message = "Delete method called successfully"
            });
        }
    }

Data Model:

    public class Contact
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }

        public Contact(string pName, string pPhone, string pEmail)
        {
            this.Id = System.Guid.NewGuid().ToString();
            this.Name = pName;
            this.Phone = pPhone;
            this.Email = pEmail;
        }

        public Contact() { }
    }

ExtJS:

Now, you move on to the view and work on the ExtJS. First, you define the record type which matches the server-side object.

        var Contact = Ext.data.Record.create([
            {
                name: 'Id',
                type: 'string'
            }, {
                name: 'Name',
                type: 'string'
            }, {
                name: 'Phone',
                type: 'string'
            }, {
                name: 'Email',
                type: 'string'
            }
        ]);

Now you need to setup the Writer and Reader

        var writer = new Ext.data.JsonWriter({
            encode: false,
            listful: true,
            writeAllFields: true
        });

        var reader = new Ext.data.JsonReader({
            totalProperty: 'total',
            successProperty: 'success',
            idProperty: 'Id',
            root: 'data',
            messageProperty: 'message'  // <-- New "messageProperty" meta-data
        }, Contact);

Then, setup a proxy to define the connection to the controller.

        var proxy = new Ext.data.HttpProxy({
            api: {
                read: '/Contact/Load',
                create: '/Contact/Create',
                update: '/Contact/Update',
                destroy: '/Contact/Delete'
            },
            headers: { 'Content-Type': 'application/json; charset=UTF-8' }
        });

Hooks the above components (reader, writer, proxy) to the store.

        var store = new Ext.data.Store({
            id: 'user',
            proxy: proxy,
            reader: reader,
            writer: writer,
            autoSave: false
        });

Add the data grid declaration

        var grid = new Ext.grid.GridPanel({
            store: store,
            columns: [
                { header: "Name",
                    width: 170,
                    sortable: true,
                    dataIndex: 'Name',
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }
                },
                { header: "Phone No.",
                    width: 160,
                    sortable: true,
                    dataIndex: 'Phone',
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }
                },
                { header: "EMail",
                    width: 170,
                    sortable: true,
                    dataIndex: 'Email',
                    editor: {
                        xtype: 'textfield',
                        allowBlank: false
                    }
                }
            ],
            plugins: [editor],
            title: 'Contacts DataGrid',
            height: 300,
            width: 510,
            tbar: [{
                iconCls: 'icon-user-add',
                text: 'Add Contact',
                handler: function () {
                    var e = new Contact({
                        Name: 'New Friend',
                        Phone: '(65) 89182736',
                        Email: 'new@google.com'
                    });
                    editor.stopEditing();
                    store.insert(0, e);
                    grid.getView().refresh();
                    grid.getSelectionModel().selectRow(0);
                    editor.startEditing(0);
                }
            }, {
                ref: '../removeBtn',
                iconCls: 'icon-user-delete',
                text: 'Remove Contact',
                handler: function () {
                    editor.stopEditing();
                    var s = grid.getSelectionModel().getSelections();
                    for (var i = 0, r; r = s[i]; i++) {
                        store.remove(r);
                    }
                }
            }, {
                iconCls: 'icon-user-save',
                text: 'Save All Modifications',
                handler: function () {
                    store.save();
                }
            }]
        });

Some observations:

  • When submitting data as JSON, set the headers “Content-Type” to “application/json” in the proxy object and set the encoding to false in the JsonWriter. If not, it will be treated as form submission.
  • Since I set the auto save to false. DataGrid will submit list of contact when there are 2 or more changes, however it will send a single object when there is 1 change. In order to make it consistent to send as list, set list full to true in the JsonWriter.
  • ASP.NET MVC 3 able to recognize the JSON without additional coding.

If you want to see the complete source code, download it from here. Hope it’s useful. 🙂

Happy hacking!

Advertisements