X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/src/widgets/list/ListView.js?ds=inline diff --git a/src/widgets/list/ListView.js b/src/widgets/list/ListView.js new file mode 100644 index 00000000..d02bdf77 --- /dev/null +++ b/src/widgets/list/ListView.js @@ -0,0 +1,357 @@ +/*! + * Ext JS Library 3.0.0 + * Copyright(c) 2006-2009 Ext JS, LLC + * licensing@extjs.com + * http://www.extjs.com/license + */ +/** + * @class Ext.ListView + * @extends Ext.DataView + *

Ext.ListView is a fast and light-weight implentation of a + * {@link Ext.grid.GridPanel Grid} like view with the following characteristics:

+ *
+ *

Example usage:

+ *

+// consume JSON of this form:
+{
+   "images":[
+      {
+         "name":"dance_fever.jpg",
+         "size":2067,
+         "lastmod":1236974993000,
+         "url":"images\/thumbs\/dance_fever.jpg"
+      },
+      {
+         "name":"zack_sink.jpg",
+         "size":2303,
+         "lastmod":1236974993000,
+         "url":"images\/thumbs\/zack_sink.jpg"
+      }
+   ]
+} 
+var store = new Ext.data.JsonStore({
+    url: 'get-images.php',
+    root: 'images',
+    fields: [
+        'name', 'url',
+        {name:'size', type: 'float'},
+        {name:'lastmod', type:'date', dateFormat:'timestamp'}
+    ]
+});
+store.load();
+
+var listView = new Ext.ListView({
+    store: store,
+    multiSelect: true,
+    emptyText: 'No images to display',
+    reserveScrollOffset: true,
+    columns: [{
+        header: 'File',
+        width: .5,
+        dataIndex: 'name'
+    },{
+        header: 'Last Modified',
+        width: .35, 
+        dataIndex: 'lastmod',
+        tpl: '{lastmod:date("m-d h:i a")}'
+    },{
+        header: 'Size',
+        dataIndex: 'size',
+        tpl: '{size:fileSize}', // format using Ext.util.Format.fileSize()
+        align: 'right'
+    }]
+});
+
+// put it in a Panel so it looks pretty
+var panel = new Ext.Panel({
+    id:'images-view',
+    width:425,
+    height:250,
+    collapsible:true,
+    layout:'fit',
+    title:'Simple ListView (0 items selected)',
+    items: listView
+});
+panel.render(document.body);
+
+// little bit of feedback
+listView.on('selectionchange', function(view, nodes){
+    var l = nodes.length;
+    var s = l != 1 ? 's' : '';
+    panel.setTitle('Simple ListView ('+l+' item'+s+' selected)');
+});
+ * 
+ * @constructor + * @param {Object} config + * @xtype listview + */ +Ext.ListView = Ext.extend(Ext.DataView, { + /** + * Set this property to true to disable the header click handler disabling sort + * (defaults to false). + * @type Boolean + * @property disableHeaders + */ + /** + * @cfg {Boolean} hideHeaders + * true to hide the {@link #internalTpl header row} (defaults to false so + * the {@link #internalTpl header row} will be shown). + */ + /** + * @cfg {String} itemSelector + * Defaults to 'dl' to work with the preconfigured {@link Ext.DataView#tpl tpl}. + * This setting specifies the CSS selector (e.g. div.some-class or span:first-child) + * that will be used to determine what nodes the ListView will be working with. + */ + itemSelector: 'dl', + /** + * @cfg {String} selectedClass The CSS class applied to a selected row (defaults to + * 'x-list-selected'). An example overriding the default styling: +

+    .x-list-selected {background-color: yellow;}
+    
+ * @type String + */ + selectedClass:'x-list-selected', + /** + * @cfg {String} overClass The CSS class applied when over a row (defaults to + * 'x-list-over'). An example overriding the default styling: +

+    .x-list-over {background-color: orange;}
+    
+ * @type String + */ + overClass:'x-list-over', + /** + * @cfg {Boolean} reserveScrollOffset + * By default will defer accounting for the configured {@link #scrollOffset} + * for 10 milliseconds. Specify true to account for the configured + * {@link #scrollOffset} immediately. + */ + /** + * @cfg {Number} scrollOffset The amount of space to reserve for the scrollbar (defaults to + * 19 pixels) + */ + scrollOffset : 19, + /** + * @cfg {Boolean/Object} columnResize + * Specify true or specify a configuration object for {@link Ext.ListView.ColumnResizer} + * to enable the columns to be resizable (defaults to true). + */ + columnResize: true, + /** + * @cfg {Array} columns An array of column configuration objects, for example: + *

+{
+    align: 'right',
+    dataIndex: 'size',
+    header: 'Size',
+    tpl: '{size:fileSize}',
+    width: .35
+}
+     * 
+ * Acceptable properties for each column configuration object are: + *
+ */ + /** + * @cfg {Boolean/Object} columnSort + * Specify true or specify a configuration object for {@link Ext.ListView.Sorter} + * to enable the columns to be sortable (defaults to true). + */ + columnSort: true, + /** + * @cfg {String/Array} internalTpl + * The template to be used for the header row. See {@link #tpl} for more details. + */ + + initComponent : function(){ + if(this.columnResize){ + this.colResizer = new Ext.ListView.ColumnResizer(this.colResizer); + this.colResizer.init(this); + } + if(this.columnSort){ + this.colSorter = new Ext.ListView.Sorter(this.columnSort); + this.colSorter.init(this); + } + if(!this.internalTpl){ + this.internalTpl = new Ext.XTemplate( + '
', + '', + '
', + '{header}', + '
', + '
', + '
', + '
', + '
', + '
' + ); + } + if(!this.tpl){ + this.tpl = new Ext.XTemplate( + '', + '
', + '', + '
', + '{[values.tpl.apply(parent)]}', + '
', + '
', + '
', + '
', + '
' + ); + }; + var cs = this.columns, allocatedWidth = 0, colsWithWidth = 0, len = cs.length; + for(var i = 0; i < len; i++){ + var c = cs[i]; + if(!c.tpl){ + c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}'); + }else if(Ext.isString(c.tpl)){ + c.tpl = new Ext.XTemplate(c.tpl); + } + c.align = c.align || 'left'; + if(Ext.isNumber(c.width)){ + c.width *= 100; + allocatedWidth += c.width; + colsWithWidth++; + } + } + // auto calculate missing column widths + if(colsWithWidth < len){ + var remaining = len - colsWithWidth; + if(allocatedWidth < 100){ + var perCol = ((100-allocatedWidth) / remaining); + for(var j = 0; j < len; j++){ + var c = cs[j]; + if(!Ext.isNumber(c.width)){ + c.width = perCol; + } + } + } + } + Ext.ListView.superclass.initComponent.call(this); + }, + + onRender : function(){ + Ext.ListView.superclass.onRender.apply(this, arguments); + + this.internalTpl.overwrite(this.el, {columns: this.columns}); + + this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild); + this.innerHd = Ext.get(this.el.dom.firstChild.firstChild); + + if(this.hideHeaders){ + this.el.dom.firstChild.style.display = 'none'; + } + }, + + getTemplateTarget : function(){ + return this.innerBody; + }, + + /** + *

Function which can be overridden which returns the data object passed to this + * view's {@link #tpl template} to render the whole ListView. The returned object + * shall contain the following properties:

+ *
+ * @param {Array} records An Array of {@link Ext.data.Record}s to be rendered into the DataView. + * @param {Number} startIndex the index number of the Record being prepared for rendering. + * @return {Object} A data object containing properties to be processed by a repeating + * XTemplate as described above. + */ + collectData : function(){ + var rs = Ext.ListView.superclass.collectData.apply(this, arguments); + return { + columns: this.columns, + rows: rs + } + }, + + verifyInternalSize : function(){ + if(this.lastSize){ + this.onResize(this.lastSize.width, this.lastSize.height); + } + }, + + // private + onResize : function(w, h){ + var bd = this.innerBody.dom; + var hd = this.innerHd.dom + if(!bd){ + return; + } + var bdp = bd.parentNode; + if(Ext.isNumber(w)){ + var sw = w - this.scrollOffset; + if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){ + bd.style.width = sw + 'px'; + hd.style.width = sw + 'px'; + }else{ + bd.style.width = w + 'px'; + hd.style.width = w + 'px'; + setTimeout(function(){ + if((bdp.offsetWidth - bdp.clientWidth) > 10){ + bd.style.width = sw + 'px'; + hd.style.width = sw + 'px'; + } + }, 10); + } + } + if(Ext.isNumber(h == 'number')){ + bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px'; + } + }, + + updateIndexes : function(){ + Ext.ListView.superclass.updateIndexes.apply(this, arguments); + this.verifyInternalSize(); + }, + + findHeaderIndex : function(hd){ + hd = hd.dom || hd; + var pn = hd.parentNode, cs = pn.parentNode.childNodes; + for(var i = 0, c; c = cs[i]; i++){ + if(c == pn){ + return i; + } + } + return -1; + }, + + setHdWidths : function(){ + var els = this.innerHd.dom.getElementsByTagName('div'); + for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){ + els[i].style.width = cs[i].width + '%'; + } + } +}); + +Ext.reg('listview', Ext.ListView); \ No newline at end of file