可编辑的网格(Editable Grid)


前一节跟大家介绍了 JSON网格(JSON Grid)以JSON格式的数据绑定.相信大家都有用过excel的,很怀念excel点击单元格即可以编辑的功能,现在好了,ExtJs框架已经为我们提供了这样的功能,下面我们一起来领略一下吧。

演示(demo)地址在文章最后.

效果图如下:

用到的有三个文件plants.xml、edit-grid.html和edit-grid.js。如果没有特别声明,.html跟.js文件名是一样的。

plants.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
  <plant>
    <common>Bloodroot</common>
    <botanical>Sanguinaria canadensis</botanical>
    <zone>4</zone>
    <light>Mostly Shady</light>
    <price>2.44</price>
    <availability>03/15/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Columbine</common>
    <botanical>Aquilegia canadensis</botanical>
    <zone>3</zone>
    <light>Mostly Shady</light>
    <price>9.37</price>
    <availability>03/06/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Marsh Marigold</common>
    <botanical>Caltha palustris</botanical>
    <zone>4</zone>
    <light>Mostly Sunny</light>
    <price>6.81</price>
    <availability>05/17/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Cowslip</common>
    <botanical>Caltha palustris</botanical>
    <zone>4</zone>
    <light>Mostly Shady</light>
    <price>9.90</price>
    <availability>03/06/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Dutchman's-Breeches</common>
    <botanical>Dicentra cucullaria</botanical>
    <zone>3</zone>
    <light>Mostly Shady</light>
    <price>6.44</price>
    <availability>01/20/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Ginger, Wild</common>
    <botanical>Asarum canadense</botanical>
    <zone>3</zone>
    <light>Mostly Shady</light>
    <price>9.03</price>
    <availability>04/18/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Hepatica</common>
    <botanical>Hepatica americana</botanical>
    <zone>4</zone>
    <light>Mostly Shady</light>
    <price>4.45</price>
    <availability>01/26/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Liverleaf</common>
    <botanical>Hepatica americana</botanical>
    <zone>4</zone>
    <light>Mostly Shady</light>
    <price>3.99</price>
    <availability>01/02/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Jack-In-The-Pulpit</common>
    <botanical>Arisaema triphyllum</botanical>
    <zone>4</zone>
    <light>Mostly Shady</light>
    <price>3.23</price>
    <availability>02/01/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Mayapple</common>
    <botanical>Podophyllum peltatum</botanical>
    <zone>3</zone>
    <light>Mostly Shady</light>
    <price>2.98</price>
    <availability>06/05/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Phlox, Woodland</common>
    <botanical>Phlox divaricata</botanical>
    <zone>3</zone>
    <light>Sun or Shade</light>
    <price>2.80</price>
    <availability>01/22/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Phlox, Blue</common>
    <botanical>Phlox divaricata</botanical>
    <zone>3</zone>
    <light>Sun or Shade</light>
    <price>5.59</price>
    <availability>02/16/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Spring-Beauty</common>
    <botanical>Claytonia Virginica</botanical>
    <zone>7</zone>
    <light>Mostly Shady</light>
    <price>6.59</price>
    <availability>02/01/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Trillium</common>
    <botanical>Trillium grandiflorum</botanical>
    <zone>5</zone>
    <light>Sun or Shade</light>
    <price>3.90</price>
    <availability>04/29/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Wake Robin</common>
    <botanical>Trillium grandiflorum</botanical>
    <zone>5</zone>
    <light>Sun or Shade</light>
    <price>3.20</price>
    <availability>02/21/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Violet, Dog-Tooth</common>
    <botanical>Erythronium americanum</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>9.04</price>
    <availability>02/01/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Trout Lily</common>
    <botanical>Erythronium americanum</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>6.94</price>
    <availability>03/24/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Adder's-Tongue</common>
    <botanical>Erythronium americanum</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>9.58</price>
    <availability>04/13/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Anemone</common>
    <botanical>Anemone blanda</botanical>
    <zone>6</zone>
    <light>Mostly Shady</light>
    <price>8.86</price>
    <availability>12/26/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Grecian Windflower</common>
    <botanical>Anemone blanda</botanical>
    <zone>6</zone>
    <light>Mostly Shady</light>
    <price>9.16</price>
    <availability>07/10/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Bee Balm</common>
    <botanical>Monarda didyma</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>4.59</price>
    <availability>05/03/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Bergamot</common>
    <botanical>Monarda didyma</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>7.16</price>
    <availability>04/27/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Black-Eyed Susan</common>
    <botanical>Rudbeckia hirta</botanical>
    <zone>Annual</zone>
    <light>Sunny</light>
    <price>9.80</price>
    <availability>06/18/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Buttercup</common>
    <botanical>Ranunculus</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>2.57</price>
    <availability>06/10/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Crowfoot</common>
    <botanical>Ranunculus</botanical>
    <zone>4</zone>
    <light>Shade</light>
    <price>9.34</price>
    <availability>04/03/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Butterfly Weed</common>
    <botanical>Asclepias tuberosa</botanical>
    <zone>Annual</zone>
    <light>Sunny</light>
    <price>2.78</price>
    <availability>06/30/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Cinquefoil</common>
    <botanical>Potentilla</botanical>
    <zone>Annual</zone>
    <light>Shade</light>
    <price>7.06</price>
    <availability>05/25/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Primrose</common>
    <botanical>Oenothera</botanical>
    <zone>3 - 5</zone>
    <light>Sunny</light>
    <price>6.56</price>
    <availability>01/30/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Gentian</common>
    <botanical>Gentiana</botanical>
    <zone>4</zone>
    <light>Sun or Shade</light>
    <price>7.81</price>
    <availability>05/18/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Blue Gentian</common>
    <botanical>Gentiana</botanical>
    <zone>4</zone>
    <light>Sun or Shade</light>
    <price>8.56</price>
    <availability>05/02/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Jacob's Ladder</common>
    <botanical>Polemonium caeruleum</botanical>
    <zone>Annual</zone>
    <light>Shade</light>
    <price>9.26</price>
    <availability>02/21/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Greek Valerian</common>
    <botanical>Polemonium caeruleum</botanical>
    <zone>Annual</zone>
    <light>Shade</light>
    <price>4.36</price>
    <availability>07/14/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>California Poppy</common>
    <botanical>Eschscholzia californica</botanical>
    <zone>Annual</zone>
    <light>Sunny</light>
    <price>7.89</price>
    <availability>03/27/2006</availability>
    <indoor>false</indoor>
  </plant>
  <plant>
    <common>Shooting Star</common>
    <botanical>Dodecatheon</botanical>
    <zone>Annual</zone>
    <light>Mostly Shady</light>
    <price>8.60</price>
    <availability>05/13/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Snakeroot</common>
    <botanical>Cimicifuga</botanical>
    <zone>Annual</zone>
    <light>Shade</light>
    <price>5.63</price>
    <availability>07/11/2006</availability>
    <indoor>true</indoor>
  </plant>
  <plant>
    <common>Cardinal Flower</common>
    <botanical>Lobelia cardinalis</botanical>
    <zone>2</zone>
    <light>Shade</light>
    <price>3.02</price>
    <availability>02/22/2006</availability>
    <indoor>true</indoor>
  </plant>
</catalog>

edit-grid.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Editor Grid Example</title>

<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />

    <!-- GC -->
 	<!-- LIBS -->
 	<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
 	<!-- ENDLIBS -->

    <script type="text/javascript" src="../../ext-all.js"></script>

    <script type="text/javascript" src="GroupingView.js"></script>
    <script type="text/javascript" src="edit-grid.js"></script>
    <link rel="stylesheet" type="text/css" href="grid-examples.css" />

<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../examples.css" />
</head>
<body>
<script type="text/javascript" src="../examples.js"></script><!-- EXAMPLES -->
<h1>Editor Grid Example</h1>
<p>This example shows how to create a grid with inline editing.</p>
<p>Note that the js is not minified so it is readable. See <a href="edit-grid.js">edit-grid.js</a>.</p>

<p>The data in the grid is loaded from <a href="plants.xml">plants.xml</a>.</p>

<!-- you must define the select box here, as the custom editor for the 'Light' column will require it -->
<select name="light" id="light" style="display: none;">
	<option value="Shade">Shade</option>
	<option value="Mostly Shady">Mostly Shady</option>
	<option value="Sun or Shade">Sun or Shade</option>

	<option value="Mostly Sunny">Mostly Sunny</option>

	<option value="Sunny">Sunny</option>
</select>

<div id="editor-grid"></div>
</body>
</html>

edit-grid.js


/*
 * Ext JS Library 2.0.2
 * Copyright(c) 2006-2008, Ext JS, LLC.
 * licensing@extjs.com
 * 
 * extjs.com/license
 */

Ext.onReady(function(){
    Ext.QuickTips.init();

    function formatDate(value){
        return value ? value.dateFormat('M d, Y') : '';
    };
    // shorthand alias
    var fm = Ext.form;

    // custom column plugin example
    var checkColumn = new Ext.grid.CheckColumn({
       header: "Indoor?",
       dataIndex: 'indoor',
       width: 55
    });

    // the column model has information about grid columns
    // dataIndex maps the column to the specific data field in
    // the data store (created below)
    var cm = new Ext.grid.ColumnModel([{
           id:'common',
           header: "Common Name",
           dataIndex: 'common',
           width: 220,
           editor: new fm.TextField({
               allowBlank: false
           })
        },{
           header: "Light",
           dataIndex: 'light',
           width: 130,
           editor: new Ext.form.ComboBox({
               typeAhead: true,
               triggerAction: 'all',
               transform:'light',
               lazyRender:true,
               listClass: 'x-combo-list-small'
            })
        },{
           header: "Price",
           dataIndex: 'price',
           width: 70,
           align: 'right',
           renderer: 'usMoney',
           editor: new fm.NumberField({
               allowBlank: false,
               allowNegative: false,
               maxValue: 100000
           })
        },{
           header: "Available",
           dataIndex: 'availDate',
           width: 95,
           renderer: formatDate,
           editor: new fm.DateField({
                format: 'm/d/y',
                minValue: '01/01/06',
                disabledDays: [0, 6],
                disabledDaysText: 'Plants are not available on the weekends'
            })
        },
        checkColumn
    ]);

    // by default columns are sortable
    cm.defaultSortable = true;

    // this could be inline, but we want to define the Plant record
    // type so we can add records dynamically
    var Plant = Ext.data.Record.create([
           // the "name" below matches the tag name to read, except "availDate"
           // which is mapped to the tag "availability"
           {name: 'common', type: 'string'},
           {name: 'botanical', type: 'string'},
           {name: 'light'},
           {name: 'price', type: 'float'},             // automatic date conversions
           {name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y'},
           {name: 'indoor', type: 'bool'}
      ]);

    // create the Data Store
    var store = new Ext.data.Store({
        // load using HTTP
        url: 'plants.xml',

        // the return will be XML, so lets set up a reader
        reader: new Ext.data.XmlReader({
               // records will have a "plant" tag
               record: 'plant'
           }, Plant),

        sortInfo:{field:'common', direction:'ASC'}
    });

    // create the editor grid
    var grid = new Ext.grid.EditorGridPanel({
        store: store,
        cm: cm,
        renderTo: 'editor-grid',
        width:600,
        height:300,
        autoExpandColumn:'common',
        title:'Edit Plants?',
        frame:true,
        plugins:checkColumn,
        clicksToEdit:1,

        tbar: [{
            text: 'Add Plant',
            handler : function(){
                var p = new Plant({
                    common: 'New Plant 1',
                    light: 'Mostly Shade',
                    price: 0,
                    availDate: (new Date()).clearTime(),
                    indoor: false
                });
                grid.stopEditing();
                store.insert(0, p);
                grid.startEditing(0, 0);
            }
        }]
    });

    // trigger the data store load
    store.load();
});

Ext.grid.CheckColumn = function(config){
    Ext.apply(this, config);
    if(!this.id){
        this.id = Ext.id();
    }
    this.renderer = this.renderer.createDelegate(this);
};

Ext.grid.CheckColumn.prototype ={
    init : function(grid){
        this.grid = grid;
        this.grid.on('render', function(){
            var view = this.grid.getView();
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    onMouseDown : function(e, t){
        if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);
            record.set(this.dataIndex, !record.data[this.dataIndex]);
        }
    },

    renderer : function(v, p, record){
        p.css += ' x-grid3-check-col-td'; 
        return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'"> </div>';
    }
};

演示地址:http://extjs.org.cn/extjs/examples/grid/edit-grid.html