~cdparra/gelee/trunk

« back to all changes in this revision

Viewing changes to webui/web/extjs/source/widgets/list/ListView.js

  • Committer: parra
  • Date: 2010-03-15 15:56:56 UTC
  • Revision ID: svn-v4:ac5bba68-f036-4e09-846e-8f32731cc928:trunk/gelee:1448
merged gelee at svn

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Ext JS Library 3.0 RC2
 
3
 * Copyright(c) 2006-2009, Ext JS, LLC.
 
4
 * licensing@extjs.com
 
5
 * 
 
6
 * http://extjs.com/license
 
7
 */
 
8
 
 
9
/**
 
10
 * @class Ext.ListView
 
11
 * @extends Ext.DataView
 
12
 * <p>Built using the {@link Ext.XTemplate} Class, Ext.ListView offers a fast and light-weight implentation
 
13
 * of a {@link Ext.grid.GridPanel Grid} like view with resizable columns. This view has no horizontal scrolling
 
14
 * as column widths are initially proportioned by percentage based on the container width and number of columns.</p>
 
15
 * <p>Example usage:</p>
 
16
 * <pre><code>
 
17
// consume JSON of this form:
 
18
{
 
19
   "images":[
 
20
      {
 
21
         "name":"dance_fever.jpg",
 
22
         "size":2067,
 
23
         "lastmod":1236974993000,
 
24
         "url":"images\/thumbs\/dance_fever.jpg"
 
25
      },
 
26
      {
 
27
         "name":"zack_sink.jpg",
 
28
         "size":2303,
 
29
         "lastmod":1236974993000,
 
30
         "url":"images\/thumbs\/zack_sink.jpg"
 
31
      }
 
32
   ]
 
33
 
34
var store = new Ext.data.JsonStore({
 
35
    url: 'get-images.php',
 
36
    root: 'images',
 
37
    fields: [
 
38
        'name', 'url',
 
39
        {name:'size', type: 'float'},
 
40
        {name:'lastmod', type:'date', dateFormat:'timestamp'}
 
41
    ]
 
42
});
 
43
store.load();
 
44
 
 
45
var listView = new Ext.ListView({
 
46
    store: store,
 
47
    multiSelect: true,
 
48
    emptyText: 'No images to display',
 
49
    reserveScrollOffset: true,
 
50
    columns: [{
 
51
        header: 'File',
 
52
        width: .5,
 
53
        dataIndex: 'name'
 
54
    },{
 
55
        header: 'Last Modified',
 
56
        width: .35, 
 
57
        dataIndex: 'lastmod',
 
58
        tpl: '{lastmod:date("m-d h:i a")}'
 
59
    },{
 
60
        header: 'Size',
 
61
        dataIndex: 'size',
 
62
        tpl: '{size:fileSize}', // format using Ext.util.Format.fileSize()
 
63
        align: 'right'
 
64
    }]
 
65
});
 
66
 
 
67
// put it in a Panel so it looks pretty
 
68
var panel = new Ext.Panel({
 
69
    id:'images-view',
 
70
    width:425,
 
71
    height:250,
 
72
    collapsible:true,
 
73
    layout:'fit',
 
74
    title:'Simple ListView <i>(0 items selected)</i>',
 
75
    items: listView
 
76
});
 
77
panel.render(document.body);
 
78
 
 
79
// little bit of feedback
 
80
listView.on('selectionchange', function(view, nodes){
 
81
    var l = nodes.length;
 
82
    var s = l != 1 ? 's' : '';
 
83
    panel.setTitle('Simple ListView <i>('+l+' item'+s+' selected)</i>');
 
84
});
 
85
 * </code></pre>
 
86
 * @constructor
 
87
 * @param {Object} config
 
88
 * @xtype listview
 
89
 */
 
90
Ext.ListView = Ext.extend(Ext.DataView, {
 
91
    /**
 
92
     * Set this property to <tt>true</tt> to disable the header click handler disabling sort
 
93
     * (defaults to <tt>false</tt>).
 
94
     * @type Boolean
 
95
     * @property disableHeaders
 
96
     */
 
97
    /**
 
98
     * @cfg {Boolean} hideHeaders
 
99
     * <tt>true</tt> to hide the {@link #internalTpl header row} (defaults to <tt>false</tt> so
 
100
     * the {@link #internalTpl header row} will be shown).
 
101
     */
 
102
    /**
 
103
     * @cfg {String} itemSelector
 
104
     * Defaults to <tt>'dl'</tt> to work with the preconfigured <b><tt>{@link Ext.DataView#tpl tpl}</tt></b>.
 
105
     * This setting specifies the CSS selector (e.g. <tt>div.some-class</tt> or <tt>span:first-child</tt>)
 
106
     * that will be used to determine what nodes the ListView will be working with.   
 
107
     */
 
108
    itemSelector: 'dl',
 
109
    /**
 
110
     * @cfg {String} selectedClass The CSS class applied to a selected row (defaults to
 
111
     * <tt>'x-list-selected'</tt>). An example overriding the default styling:
 
112
    <pre><code>
 
113
    .x-list-selected {background-color: yellow;}
 
114
    </code></pre>
 
115
     * @type String
 
116
     */
 
117
    selectedClass:'x-list-selected',
 
118
    /**
 
119
     * @cfg {String} overClass The CSS class applied when over a row (defaults to
 
120
     * <tt>'x-list-over'</tt>). An example overriding the default styling:
 
121
    <pre><code>
 
122
    .x-list-over {background-color: orange;}
 
123
    </code></pre>
 
124
     * @type String
 
125
     */
 
126
    overClass:'x-list-over',
 
127
    /**
 
128
     * @cfg {Boolean} reserveScrollOffset
 
129
     * By default will defer accounting for the configured <b><tt>{@link #scrollOffset}</tt></b>
 
130
     * for 10 milliseconds.  Specify <tt>true</tt> to account for the configured
 
131
     * <b><tt>{@link #scrollOffset}</tt></b> immediately.
 
132
     */
 
133
    /**
 
134
     * @cfg {Number} scrollOffset The amount of space to reserve for the scrollbar (defaults to
 
135
     * <tt>19</tt> pixels)
 
136
     */
 
137
    scrollOffset : 19,
 
138
    /**
 
139
     * @cfg {Boolean/Object} columnResize
 
140
     * Specify <tt>true</tt> or specify a configuration object for {@link Ext.ListView.ColumnResizer}
 
141
     * to enable the columns to be resizable (defaults to <tt>true</tt>).
 
142
     */
 
143
    columnResize: true,
 
144
    /**
 
145
     * @cfg {Array} columns An array of column configuration objects, for example:
 
146
     * <pre><code>
 
147
{
 
148
    align: 'right',
 
149
    dataIndex: 'size',
 
150
    header: 'Size',
 
151
    tpl: '{size:fileSize}',
 
152
    width: .35
 
153
}
 
154
     * </code></pre> 
 
155
     * Acceptable properties for each column configuration object are:
 
156
     * <div class="mdetail-params"><ul>
 
157
     * <li><b><tt>align</tt></b> : String<div class="sub-desc">Set the CSS text-align property
 
158
     * of the column. Defaults to <tt>'left'</tt>.</div></li>
 
159
     * <li><b><tt>dataIndex</tt></b> : String<div class="sub-desc">See {@link Ext.grid.Column}.
 
160
     * {@link Ext.grid.Column#dataIndex dataIndex} for details.</div></li>
 
161
     * <li><b><tt>header</tt></b> : String<div class="sub-desc">See {@link Ext.grid.Column}.
 
162
     * {@link Ext.grid.Column#header header} for details.</div></li>
 
163
     * <li><b><tt>tpl</tt></b> : String<div class="sub-desc">Specify a string to pass as the
 
164
     * configuration string for {@link Ext.XTemplate}.  By default an {@link Ext.XTemplate}
 
165
     * will be implicitly created using the <tt>dataIndex</tt>.</div></li>
 
166
     * <li><b><tt>width</tt></b> : Number<div class="sub-desc">Percentage of the container width
 
167
     * this column should be allocated.  Columns that have no width specified will be
 
168
     * allocated with an equal percentage to fill 100% of the container width.  To easily take
 
169
     * advantage of the full container width, leave the width of at least one column undefined.
 
170
     * Note that if you do not want to take up the full width of the container, the width of
 
171
     * every column needs to be explicitly defined.</div></li>
 
172
     * </ul></div>
 
173
     */
 
174
    /**
 
175
     * @cfg {Boolean/Object} columnSort
 
176
     * Specify <tt>true</tt> or specify a configuration object for {@link Ext.ListView.Sorter}
 
177
     * to enable the columns to be sortable (defaults to <tt>true</tt>).
 
178
     */
 
179
    columnSort: true,
 
180
    /**
 
181
     * @cfg {String/Array} internalTpl
 
182
     * The template to be used for the header row.  See {@link #tpl} for more details.
 
183
     */
 
184
 
 
185
    initComponent : function(){
 
186
        if(this.columnResize){
 
187
            this.colResizer = new Ext.ListView.ColumnResizer(this.colResizer);
 
188
            this.colResizer.init(this);
 
189
        }
 
190
        if(this.columnSort){
 
191
            this.colSorter = new Ext.ListView.Sorter(this.columnSort);
 
192
            this.colSorter.init(this);
 
193
        }
 
194
        if(!this.internalTpl){
 
195
            this.internalTpl = new Ext.XTemplate(
 
196
                '<div class="x-list-header"><div class="x-list-header-inner">',
 
197
                    '<tpl for="columns">',
 
198
                    '<div style="width:{width}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
 
199
                        '{header}',
 
200
                    '</em></div>',
 
201
                    '</tpl>',
 
202
                    '<div class="x-clear"></div>',
 
203
                '</div></div>',
 
204
                '<div class="x-list-body"><div class="x-list-body-inner">',
 
205
                '</div></div>'
 
206
            );
 
207
        }
 
208
        if(!this.tpl){
 
209
            this.tpl = new Ext.XTemplate(
 
210
                '<tpl for="rows">',
 
211
                    '<dl>',
 
212
                        '<tpl for="parent.columns">',
 
213
                        '<dt style="width:{width}%;text-align:{align};"><em unselectable="on">',
 
214
                            '{[values.tpl.apply(parent)]}',
 
215
                        '</em></dt>',
 
216
                        '</tpl>',
 
217
                        '<div class="x-clear"></div>',
 
218
                    '</dl>',
 
219
                '</tpl>'
 
220
            );
 
221
        };
 
222
        var cs = this.columns, allocatedWidth = 0, colsWithWidth = 0, len = cs.length;
 
223
        for(var i = 0; i < len; i++){
 
224
            var c = cs[i];
 
225
            if(!c.tpl){
 
226
                c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
 
227
            }else if(typeof c.tpl == 'string'){
 
228
                c.tpl = new Ext.XTemplate(c.tpl);
 
229
            }
 
230
            c.align = c.align || 'left';
 
231
            if(typeof c.width == 'number'){
 
232
                c.width *= 100;
 
233
                allocatedWidth += c.width;
 
234
                colsWithWidth++;
 
235
            }
 
236
        }
 
237
        // auto calculate missing column widths
 
238
        if(colsWithWidth < len){
 
239
            var remaining = len - colsWithWidth;
 
240
            if(allocatedWidth < 100){
 
241
                var perCol = ((100-allocatedWidth) / remaining);
 
242
                for(var j = 0; j < len; j++){
 
243
                    var c = cs[j];
 
244
                    if(typeof c.width != 'number'){
 
245
                        c.width = perCol;
 
246
                    }
 
247
                }
 
248
            }
 
249
        }
 
250
        Ext.ListView.superclass.initComponent.call(this);
 
251
    },
 
252
 
 
253
    onRender : function(){
 
254
        Ext.ListView.superclass.onRender.apply(this, arguments);
 
255
 
 
256
        this.internalTpl.overwrite(this.el, {columns: this.columns});
 
257
        
 
258
        this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
 
259
        this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
 
260
 
 
261
        if(this.hideHeaders){
 
262
            this.el.dom.firstChild.style.display = 'none';
 
263
        }
 
264
    },
 
265
 
 
266
    getTemplateTarget : function(){
 
267
        return this.innerBody;
 
268
    },
 
269
 
 
270
    /**
 
271
     * <p>Function which can be overridden which returns the data object passed to this
 
272
     * view's {@link #tpl template} to render the whole ListView. The returned object 
 
273
     * shall contain the following properties:</p>
 
274
     * <div class="mdetail-params"><ul>
 
275
     * <li><b>columns</b> : String<div class="sub-desc">See <tt>{@link #columns}</tt></div></li>
 
276
     * <li><b>rows</b> : String<div class="sub-desc">See
 
277
     * <tt>{@link Ext.DataView}.{@link Ext.DataView#collectData collectData}</div></li>
 
278
     * </ul></div>
 
279
     * @param {Array} records An Array of {@link Ext.data.Record}s to be rendered into the DataView.
 
280
     * @param {Number} startIndex the index number of the Record being prepared for rendering.
 
281
     * @return {Object} A data object containing properties to be processed by a repeating
 
282
     * XTemplate as described above.
 
283
     */
 
284
    collectData : function(){
 
285
        var rs = Ext.ListView.superclass.collectData.apply(this, arguments);
 
286
        return {
 
287
            columns: this.columns,
 
288
            rows: rs
 
289
        }
 
290
    },
 
291
 
 
292
    verifyInternalSize : function(){
 
293
        if(this.lastSize){
 
294
            this.onResize(this.lastSize.width, this.lastSize.height);
 
295
        }
 
296
    },
 
297
 
 
298
    // private
 
299
    onResize : function(w, h){
 
300
        var bd = this.innerBody.dom;
 
301
        var hd = this.innerHd.dom
 
302
        if(!bd){
 
303
            return;
 
304
        }
 
305
        var bdp = bd.parentNode;
 
306
        if(typeof w == 'number'){
 
307
            var sw = w - this.scrollOffset;
 
308
            if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){
 
309
                bd.style.width = sw + 'px';
 
310
                hd.style.width = sw + 'px';
 
311
            }else{
 
312
                bd.style.width = w + 'px';
 
313
                hd.style.width = w + 'px';
 
314
                setTimeout(function(){
 
315
                    if((bdp.offsetWidth - bdp.clientWidth) > 10){
 
316
                        bd.style.width = sw + 'px';
 
317
                        hd.style.width = sw + 'px';
 
318
                    }
 
319
                }, 10);
 
320
            }
 
321
        }
 
322
        if(typeof h == 'number'){
 
323
            bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';
 
324
        }
 
325
    },
 
326
 
 
327
    updateIndexes : function(){
 
328
        Ext.ListView.superclass.updateIndexes.apply(this, arguments);
 
329
        this.verifyInternalSize();
 
330
    },
 
331
 
 
332
    findHeaderIndex : function(hd){
 
333
        hd = hd.dom || hd;
 
334
        var pn = hd.parentNode, cs = pn.parentNode.childNodes;
 
335
        for(var i = 0, c; c = cs[i]; i++){
 
336
            if(c == pn){
 
337
                return i;
 
338
            }
 
339
        }
 
340
        return -1;
 
341
    },
 
342
 
 
343
    setHdWidths : function(){
 
344
        var els = this.innerHd.dom.getElementsByTagName('div');
 
345
        for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){
 
346
            els[i].style.width = cs[i].width + '%';
 
347
        }
 
348
    }
 
349
});
 
350
 
 
351
Ext.reg('listview', Ext.ListView);
 
 
b'\\ No newline at end of file'