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

<html>
<head>
    <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>

</head>
<body></body>
</html>

Application JavaScript file app.js

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

Ext.Loader.setConfig({ 
    enabled: true 
    });

Ext.require([
             'Ext.data.*',
             'Ext.grid.*',
             'Ext.ux.CheckColumn'
         ]);

Ext.application({
    name: 'GRIDEDITING',

    appFolder: 'app',
   
    controllers: [
                  'Customers'
              ],

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

JavaScript source file for the Model Customer.js

Ext.define('GRIDEDITING.model.Customer', {
    extend: 'Ext.data.Model',
    fields: [
             'customerId',
             'firstName',
             'lastName',
             'email',
             {name: 'active', type: 'bool'}
            ],
    validations: 
            [
                  {type: 'presence',  field: 'firstName'},
                  {type: 'presence',  field: 'lastName'},
                  {type: 'presence',  field: 'email'}
             ]
});

JavaScript source file for the Store Customers.js

Ext.define('GRIDEDITING.store.Customers', {
    extend: 'Ext.data.Store',
    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'
            }
        }];

        this.callParent(arguments);
    }
  
  
});

JavaScript source file for the application controller Customers.js

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

            //define the stores
            stores : ['Customers'],
            //define the models
            models : ['Customer'],
            //define the views
            views : ['CustomerList'],
           
            init : function() {
                this.control({
                   
                    '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 
                if(obj.record.dirty){
                    //check if the record is valid   
                    console.log(obj.record.validate());
                    if(obj.record.validate().isValid()){
                        //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
                console.log(column);
                //grid row number
                console.log(rowIndex);
                //the checkbox value
                console.log(checked);
                console.log(this.getCustomersStore().getAt(rowIndex));
                //Make your Ajax request to sync data
                this.syncData(rowIndex,'update');
            },
           
            //Sync data with the server 
            syncData : function(rowIndex, mode) {
                Ext.Ajax.request({
                       url: 'CustomerServlet',
                    params: {
                            store_id: 1,
                            action: mode,
                            rowIndex: rowIndex,
                            recordInfo: Ext.encode(this.getCustomersStore().getAt(rowIndex).data)
                    },
                    scope:this,
                    //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(ajaxResponse.success){
                    //if we are doing an insert then get the new customerId 
                    //and update the store record
                    if(opts.params.action === 'insert'){
                        customerId = ajaxResponse.customerId;
                        this.getCustomersStore().getAt(opts.params.rowIndex).set('customerId',customerId);
                    }
                    this.getCustomersStore().getAt(opts.params.rowIndex).commit();
                }
                else {
                    Ext.MessageBox.alert('Status', 'Error occured during update');
                }
            },
           
            addCustomer : function(button) {
                var customer = new GRIDEDITING.model.Customer({
                                        'customerId': '',
                                        'firstName': '',
                                         'lastName': '',
                                         'email':'',
                                         'active':true
                                    });
                                   
                var panel = button.up('panel');
                editor = panel.editingPlugin;   
                editor.cancelEdit();
                this.getCustomersStore().insert(0, customer);
                editor.startEditByPosition({row: 0, column: 2});
            }
                          
    });

Click here for next Chapter

Recommended Reading


No comments :

Post a Comment