ExtJS 4 MVC Example: Binding a Grid to a Form

May 23, 2012 | By

Another ExtJS 4 MVC Example. Today we are going to port the  Binding a Grid to a Form to MVC.

Let’s get started!

extjs4 mvc grid binded form loiane ExtJS 4 MVC Example: Binding a Grid to a Form

Project’s Structure

extjs4 mvc grid binded form loiane 01 ExtJS 4 MVC Example: Binding a Grid to a Form

Model

Ext.define('Ext4Example.model.Stock', {
	extend: 'Ext.data.Model',
	fields: [
	    {name: 'company'},
        {name: 'price',      type: 'float'},
        {name: 'change',     type: 'float'},
        {name: 'pctChange',  type: 'float'},
        {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
        // Rating dependent upon performance 0 = best, 2 = worst
        {name: 'rating', type: 'int', convert: function(value, record) {
            var pct = record.get('pctChange');
            if (pct < 0) return 2;
            if (pct < 1) return 1;
            return 0;
        }}
    ]
});

Store

Ext.define('Ext4Example.store.Stocks', {
    extend: 'Ext.data.ArrayStore',
    model: 'Ext4Example.model.Stock',
    data: [
        ['3m Co',                               71.72, 0.02,  0.03,  '9/1 12:00am'],
        ['Alcoa Inc',                           29.01, 0.42,  1.47,  '9/1 12:00am'],
        ['Altria Group Inc',                    83.81, 0.28,  0.34,  '9/1 12:00am'],
        ['American Express Company',            52.55, 0.01,  0.02,  '9/1 12:00am'],
        ['American International Group, Inc.',  64.13, 0.31,  0.49,  '9/1 12:00am'],
        ['AT&T Inc.',                           31.61, -0.48, -1.54, '9/1 12:00am'],
        ['Boeing Co.',                          75.43, 0.53,  0.71,  '9/1 12:00am'],
        ['Caterpillar Inc.',                    67.27, 0.92,  1.39,  '9/1 12:00am'],
        ['Citigroup, Inc.',                     49.37, 0.02,  0.04,  '9/1 12:00am'],
        ['E.I. du Pont de Nemours and Company', 40.48, 0.51,  1.28,  '9/1 12:00am'],
        ['Exxon Mobil Corp',                    68.1,  -0.43, -0.64, '9/1 12:00am'],
        ['General Electric Company',            34.14, -0.08, -0.23, '9/1 12:00am'],
        ['General Motors Corporation',          30.27, 1.09,  3.74,  '9/1 12:00am'],
        ['Hewlett-Packard Co.',                 36.53, -0.03, -0.08, '9/1 12:00am'],
        ['Honeywell Intl Inc',                  38.77, 0.05,  0.13,  '9/1 12:00am'],
        ['Intel Corporation',                   19.88, 0.31,  1.58,  '9/1 12:00am'],
        ['International Business Machines',     81.41, 0.44,  0.54,  '9/1 12:00am'],
        ['Johnson & Johnson',                   64.72, 0.06,  0.09,  '9/1 12:00am'],
        ['JP Morgan & Chase & Co',              45.73, 0.07,  0.15,  '9/1 12:00am'],
        ['McDonald\'s Corporation',             36.76, 0.86,  2.40,  '9/1 12:00am'],
        ['Merck & Co., Inc.',                   40.96, 0.41,  1.01,  '9/1 12:00am'],
        ['Microsoft Corporation',               25.84, 0.14,  0.54,  '9/1 12:00am'],
        ['Pfizer Inc',                          27.96, 0.4,   1.45,  '9/1 12:00am'],
        ['The Coca-Cola Company',               45.07, 0.26,  0.58,  '9/1 12:00am'],
        ['The Home Depot, Inc.',                34.64, 0.35,  1.02,  '9/1 12:00am'],
        ['The Procter & Gamble Company',        61.91, 0.01,  0.02,  '9/1 12:00am'],
        ['United Technologies Corporation',     63.26, 0.55,  0.88,  '9/1 12:00am'],
        ['Verizon Communications',              35.57, 0.39,  1.11,  '9/1 12:00am'],
        ['Wal-Mart Stores, Inc.',               45.45, 0.73,  1.63,  '9/1 12:00am']
    ]
});

View – Grid

Ext.define('Ext4Example.view.stock.StockGrid' ,{
    extend: 'Ext.grid.Panel',
    alias : 'widget.stockgrid',

    title : 'Company Data',

    /**
     * Custom function used for column renderer
     * @param {Object} val
     */
    change: function(val) {
        if (val > 0) {
            return '<span style="color: green;">' + val + '</span>';
        } else if (val < 0) {
            return '<span style="color: red;">' + val + '</span>';
        }
        return val;
    },

    /**
     * Custom function used for column renderer
     * @param {Object} val
     */
    pctChange: function(val) {
        if (val > 0) {
            return '<span style="color: green;">' + val + '%</span>';
        } else if (val < 0) {
            return '<span style="color: red;">' + val + '%</span>';
        }
        return val;
    },

    // render rating as "A", "B" or "C" depending upon numeric value.
    rating: function(v) {
        if (v == 0) return "A";
        if (v == 1) return "B";
        if (v == 2) return "C";
    },

    viewConfig: {
        stripeRows: true
    },

    initComponent: function() {

    	this.store = 'Stocks';

    	this.columns = [{
            text     : 'Company',
            flex     : 1,
            sortable : false,
            dataIndex: 'company'
        },
        {
            text     : 'Price',
            width    : 75,
            sortable : true,
            renderer : 'usMoney',
            dataIndex: 'price'
        },
        {
            text     : 'Change',
            width    : 75,
            sortable : true,
            renderer : this.change,
            dataIndex: 'change'
        },
        {
            text     : '% Change',
            width    : 75,
            sortable : true,
            renderer : this.pctChange,
            dataIndex: 'pctChange'
        },
        {
            text     : 'Last Updated',
            width    : 85,
            sortable : true,
            renderer : Ext.util.Format.dateRenderer('m/d/Y'),
            dataIndex: 'lastChange'
        },
        {
            text: 'Rating',
            width: 30,
            sortable: true,
            renderer: this.rating,
            dataIndex: 'rating'
        }];

    	this.callParent(arguments);
    }
});

View – Form

Ext.define('Ext4Example.view.stock.StockForm' ,{
    extend: 'Ext.form.FieldSet',
    alias : 'widget.stockform',

    margin: '0 0 0 10',

    title:'Company details',

    defaults: {
        width: 240,
        labelWidth: 90
    },

    defaultType: 'textfield',

    items: [{
        fieldLabel: 'Name',
        name: 'company'
    },{
        fieldLabel: 'Price',
        name: 'price'
    },{
        fieldLabel: '% Change',
        name: 'pctChange'
    },{
        xtype: 'datefield',
        fieldLabel: 'Last Updated',
        name: 'lastChange'
    }, {
        xtype: 'radiogroup',
        fieldLabel: 'Rating',
        columns: 3,
        defaults: {
            name: 'rating' //Each radio has the same name so the browser will make sure only one is checked at once
        },
        items: [{
            inputValue: '0',
            boxLabel: 'A'
        }, {
            inputValue: '1',
            boxLabel: 'B'
        }, {
            inputValue: '2',
            boxLabel: 'C'
        }]
    }]
});

View – Panel

Ext.define('Ext4Example.view.stock.StockPanel' ,{
    extend: 'Ext.form.Panel',
    alias : 'widget.stockpanel',

    frame: true,
    title: 'Company Data',
    bodyPadding: 5,
    layout: 'column',    // Specifies that the items will now be arranged in columns

    fieldDefaults: {
        labelAlign: 'left',
        msgTarget: 'side'
    },

    items: [{
    	xtype: 'stockgrid',
    	columnWidth: .70
    },{
    	xtype: 'stockform',
    	columnWidth: .30
    }]

});

View- Viewport

/**
 * The main application viewport, which displays the whole application
 * @extends Ext.Viewport
 */
Ext.define('Ext4Example.view.Viewport', {
    extend: 'Ext.Viewport',
    layout: 'fit',

    requires: [
        'Ext4Example.view.stock.StockGrid',
        'Ext4Example.view.stock.StockForm'
    ],

    initComponent: function() {
        var me = this;

        Ext.apply(me, {
            items: [
                {
                    xtype: 'stockpanel'
                }
            ]
        });

        me.callParent(arguments);
    }
});

Controller

Ext.define('Ext4Example.controller.Stocks', {
    extend: 'Ext.app.Controller',

    stores: ['Stocks'],

    models: ['Stock'],

    views: ['stock.StockGrid','stock.StockForm','stock.StockPanel'],

    refs: [{
        ref: 'stockForm',
        selector: 'form'
    }],

    init: function() {

        this.control({
        	'stockgrid': {
        		selectionchange: this.gridSelectionChange,
                viewready: this.onViewReady
        	}
        });
    },

    gridSelectionChange: function(model, records) {

        if (records[0]) {
             this.getStockForm().getForm().loadRecord(records[0]);
        }
    },

    onViewReady: function(grid) {
        grid.getSelectionModel().select(0);
    }
});

App.js

Ext.application({
    name: 'Ext4Example',

    controllers: [
        'Stocks'
    ],

    autoCreateViewport: true
});

HTML

<html>
<head>
	<title>Ext JS 4 Examples - loiane.com</title>

	<!-- Ext JS Files -->
	<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
    <script type="text/javascript" src="extjs/ext-debug.js"></script>

    <!-- App Files -->
    <script type="text/javascript" src="app.js"></script>

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

Demo

To see this example running live, please go to:  http://loiane.com/extjs/extjs4-mvc-grid-binded-form

Download the Source Code

You can download the full source code from my Github repository: https://github.com/loiane/extjs4-mvc-grid-binded-form

Happy Coding! icon smile ExtJS 4 MVC Example: Binding a Grid to a Form

Filed in: Ext JS 4 | Tags: ,

Comments (2)

  1. Carlos

    Do you have this same recipe but coded using Sencha Architect?