Blog Archive

ExtJs 4 Grid Editing Tutorial based on CellEditing plugin using Java Servlet, JSON and MySQL database

The Ext.grid.plugin.CellEditing plugin injects editing at a cell level for a Grid. Only a single cell will be editable at a time. The field that will be used for the editor is defined at the editor. If an editor is not specified for a particular column then that cell will not be editable and it will be skipped when activated via the mouse or the keyboard.

This tutorial will cover the following topics ...
  • Connection to a Customer Table in MySQL database
  • Get list of customers as JSON array from Java Servlet
  • Edit a customer information using the Grid Cells
  • Add a new customer using the Grid after all validation passes
  • CheckColumn to make the customer record active or inactive
  • Automatically Sync data as soon as the changes are made using AJAX

ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL
ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL
ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL

Application starting point index.html

    <title>ExtJs 4 Grid Editing Example </title>

    <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
    <link rel="stylesheet" type="text/css" href="extjs/ux/css/CheckHeader.css">
    <script type="text/javascript" src="extjs/ext-all-debug.js"></script>
    <script type="text/javascript" src="app.js"></script>


Application JavaScript file app.js

Ext.Loader.setPath('Ext.ux', 'extjs/ux');

    enabled: true 


    name: 'GRIDEDITING',

    appFolder: 'app',
    controllers: [

    launch: function() {
        Ext.create('Ext.container.Viewport', {
            items: [
                    xtype: 'customerList',

JavaScript source file for the Model Customer.js

Ext.define('GRIDEDITING.model.Customer', {
    extend: '',
    fields: [
             {name: 'active', type: 'bool'}
                  {type: 'presence',  field: 'firstName'},
                  {type: 'presence',  field: 'lastName'},
                  {type: 'presence',  field: 'email'}

JavaScript source file for the Store Customers.js

Ext.define('', {
    extend: '',
    model: 'GRIDEDITING.model.Customer',
    autoLoad: true,
    pageSize: 20,
    proxy: {
        type: 'ajax',
        url: 'CustomerServlet',
        extraParams: {
            store_id: 1
        reader: {
            type: 'json',
            totalProperty: 'totalCount',
            root: 'customers',
            successProperty: 'success'
     listeners: {
         load : function(store) {
             //if need something to do after the store loads


JavaScript source file for Editable Grid view CustomerList.js

Ext.define('GRIDEDITING.view.CustomerList' ,{
    extend: 'Ext.grid.Panel',
    alias : 'widget.customerList',
    title : 'List of Customers',
    store : 'Customers',
    loadMask: true,
    autoheight: true,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: 'Customers',  
        dock: 'bottom',
        displayInfo: true,
        items: [
                    xtype: 'tbseparator' 
                    xtype : 'button',
                    text: 'Add Customer',
                    action: 'add'
    plugins: [
              Ext.create('Ext.grid.plugin.CellEditing', {
                  clicksToEdit: 1
    selModel: {
        selType: 'cellmodel'
    initComponent: function() {
        this.columns = [{
            header: 'Customer Id', 
            dataIndex: 'customerId',
            flex: 1,
        }, {
            header: 'Active',
            dataIndex: 'active',
            flex: 1,
            xtype: 'checkcolumn',
        }, {
            header: 'First Name',
            dataIndex: 'firstName',
            flex: 1,
            editor: {
                allowBlank: false
        }, {
            header: 'Last Name',
            dataIndex: 'lastName',
            flex: 1,
            editor: {
                allowBlank: false
        }, {
            header: 'Email Address', 
            dataIndex: 'email', 
            flex: 1,
            editor: {
                allowBlank: false,
                vtype: 'email'


JavaScript source file for the application controller Customers.js

Ext.define('GRIDEDITING.controller.Customers', {
            extend : '',

            //define the stores
            stores : ['Customers'],
            //define the models
            models : ['Customer'],
            //define the views
            views : ['CustomerList'],
            init : function() {
                    'viewport' : {
                        render : this.onPanelRendered
                    'customerList': {
                        edit: this.editCustomer
                    'checkcolumn': {
                        checkchange: this.checkboxChanged
                    'customerList button[action=add]' : {
                        click : this.addCustomer   

            onPanelRendered : function() {
                //just a console log to show when the panel is rendered
                console.log('The panel was rendered');
            editCustomer : function(editor, obj) {
                //check if record is dirty 
                    //check if the record is valid   
                        //Make your Ajax request to sync data
                        mode = (obj.record.get('customerId') === "") ? 'insert': 'update';
                        this.syncData(obj.rowIdx, mode);
            checkboxChanged : function(column,rowIndex,checked) {
                console.log('Checkbox changed');
                //grid column information
                //grid row number
                //the checkbox value
                //Make your Ajax request to sync data
            //Sync data with the server 
            syncData : function(rowIndex, mode) {
                       url: 'CustomerServlet',
                    params: {
                            store_id: 1,
                            action: mode,
                            rowIndex: rowIndex,
                            recordInfo: Ext.encode(this.getCustomersStore().getAt(rowIndex).data)
                    //method to call when the request is successful
                    success: this.onSaveSuccess,
                    //method to call when the request is a failure
                    failure: this.onSaveFailure
            onSaveFailure: function(err){
                //Alert the user about communication error
                Ext.MessageBox.alert('Status', 'Error occured during update');
            onSaveSuccess: function(response,opts){
                //Remove dirty
                var ajaxResponse = Ext.decode(response.responseText);
                    //if we are doing an insert then get the new customerId 
                    //and update the store record
                    if(opts.params.action === 'insert'){
                        customerId = ajaxResponse.customerId;
                else {
                    Ext.MessageBox.alert('Status', 'Error occured during update');
            addCustomer : function(button) {
                var customer = new GRIDEDITING.model.Customer({
                                        'customerId': '',
                                        'firstName': '',
                                         'lastName': '',
                var panel = button.up('panel');
                editor = panel.editingPlugin;   
                this.getCustomersStore().insert(0, customer);
                editor.startEditByPosition({row: 0, column: 2});

Click here for next Chapter

Recommended Reading

1 comment :

  1. Thanks for the document and that helped me greatly. Further; i wanted to add a image(edit icon just to inform user that this field is editable) and it's doing great. The mess starts when i double-click on the field. No doubt the textbox is coming but it holds both image tag and the original value(email in this case). Could you please guide me.