Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/ext/pkgs/pkg-toolbars-debug.js @ 76

Revision 76, 38.7 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

  • Property svn:executable set to *
Line 
1/*!
2 * Ext JS Library 3.4.0
3 * Copyright(c) 2006-2011 Sencha Inc.
4 * licensing@sencha.com
5 * http://www.sencha.com/license
6 */
7/**
8 * @class Ext.Toolbar
9 * @extends Ext.Container
10 * <p>Basic Toolbar class. Although the <tt>{@link Ext.Container#defaultType defaultType}</tt> for Toolbar
11 * is <tt>{@link Ext.Button button}</tt>, Toolbar elements (child items for the Toolbar container) may
12 * be virtually any type of Component. Toolbar elements can be created explicitly via their constructors,
13 * or implicitly via their xtypes, and can be <tt>{@link #add}</tt>ed dynamically.</p>
14 * <p>Some items have shortcut strings for creation:</p>
15 * <pre>
16<u>Shortcut</u>  <u>xtype</u>          <u>Class</u>                  <u>Description</u>
17'->'      'tbfill'       {@link Ext.Toolbar.Fill}       begin using the right-justified button container
18'-'       'tbseparator'  {@link Ext.Toolbar.Separator}  add a vertical separator bar between toolbar items
19' '       'tbspacer'     {@link Ext.Toolbar.Spacer}     add horiztonal space between elements
20 * </pre>
21 *
22 * Example usage of various elements:
23 * <pre><code>
24var tb = new Ext.Toolbar({
25    renderTo: document.body,
26    width: 600,
27    height: 100,
28    items: [
29        {
30            // xtype: 'button', // default for Toolbars, same as 'tbbutton'
31            text: 'Button'
32        },
33        {
34            xtype: 'splitbutton', // same as 'tbsplitbutton'
35            text: 'Split Button'
36        },
37        // begin using the right-justified button container
38        '->', // same as {xtype: 'tbfill'}, // Ext.Toolbar.Fill
39        {
40            xtype: 'textfield',
41            name: 'field1',
42            emptyText: 'enter search term'
43        },
44        // add a vertical separator bar between toolbar items
45        '-', // same as {xtype: 'tbseparator'} to create Ext.Toolbar.Separator
46        'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.Toolbar.TextItem
47        {xtype: 'tbspacer'},// same as ' ' to create Ext.Toolbar.Spacer
48        'text 2',
49        {xtype: 'tbspacer', width: 50}, // add a 50px space
50        'text 3'
51    ]
52});
53 * </code></pre>
54 * Example adding a ComboBox within a menu of a button:
55 * <pre><code>
56// ComboBox creation
57var combo = new Ext.form.ComboBox({
58    store: new Ext.data.ArrayStore({
59        autoDestroy: true,
60        fields: ['initials', 'fullname'],
61        data : [
62            ['FF', 'Fred Flintstone'],
63            ['BR', 'Barney Rubble']
64        ]
65    }),
66    displayField: 'fullname',
67    typeAhead: true,
68    mode: 'local',
69    forceSelection: true,
70    triggerAction: 'all',
71    emptyText: 'Select a name...',
72    selectOnFocus: true,
73    width: 135,
74    getListParent: function() {
75        return this.el.up('.x-menu');
76    },
77    iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu
78});
79
80// put ComboBox in a Menu
81var menu = new Ext.menu.Menu({
82    id: 'mainMenu',
83    items: [
84        combo // A Field in a Menu
85    ]
86});
87
88// add a Button with the menu
89tb.add({
90        text:'Button w/ Menu',
91        menu: menu  // assign menu by instance
92    });
93tb.doLayout();
94 * </code></pre>
95 * @constructor
96 * Creates a new Toolbar
97 * @param {Object/Array} config A config object or an array of buttons to <tt>{@link #add}</tt>
98 * @xtype toolbar
99 */
100Ext.Toolbar = function(config){
101    if(Ext.isArray(config)){
102        config = {items: config, layout: 'toolbar'};
103    } else {
104        config = Ext.apply({
105            layout: 'toolbar'
106        }, config);
107        if(config.buttons) {
108            config.items = config.buttons;
109        }
110    }
111    Ext.Toolbar.superclass.constructor.call(this, config);
112};
113
114(function(){
115
116var T = Ext.Toolbar;
117
118Ext.extend(T, Ext.Container, {
119
120    defaultType: 'button',
121
122    /**
123     * @cfg {String/Object} layout
124     * This class assigns a default layout (<code>layout:'<b>toolbar</b>'</code>).
125     * Developers <i>may</i> override this configuration option if another layout
126     * is required (the constructor must be passed a configuration object in this
127     * case instead of an array).
128     * See {@link Ext.Container#layout} for additional information.
129     */
130
131    enableOverflow : false,
132
133    /**
134     * @cfg {Boolean} enableOverflow
135     * Defaults to false. Configure <tt>true</tt> to make the toolbar provide a button
136     * which activates a dropdown Menu to show items which overflow the Toolbar's width.
137     */
138    /**
139     * @cfg {String} buttonAlign
140     * <p>The default position at which to align child items. Defaults to <code>"left"</code></p>
141     * <p>May be specified as <code>"center"</code> to cause items added before a Fill (A <code>"->"</code>) item
142     * to be centered in the Toolbar. Items added after a Fill are still right-aligned.</p>
143     * <p>Specify as <code>"right"</code> to right align all child items.</p>
144     */
145
146    trackMenus : true,
147    internalDefaults: {removeMode: 'container', hideParent: true},
148    toolbarCls: 'x-toolbar',
149
150    initComponent : function(){
151        T.superclass.initComponent.call(this);
152
153        /**
154         * @event overflowchange
155         * Fires after the overflow state has changed.
156         * @param {Object} c The Container
157         * @param {Boolean} lastOverflow overflow state
158         */
159        this.addEvents('overflowchange');
160    },
161
162    // private
163    onRender : function(ct, position){
164        if(!this.el){
165            if(!this.autoCreate){
166                this.autoCreate = {
167                    cls: this.toolbarCls + ' x-small-editor'
168                };
169            }
170            this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
171            Ext.Toolbar.superclass.onRender.apply(this, arguments);
172        }
173    },
174
175    /**
176     * <p>Adds element(s) to the toolbar -- this function takes a variable number of
177     * arguments of mixed type and adds them to the toolbar.</p>
178     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
179     * @param {Mixed} arg1 The following types of arguments are all valid:<br />
180     * <ul>
181     * <li>{@link Ext.Button} config: A valid button config object (equivalent to {@link #addButton})</li>
182     * <li>HtmlElement: Any standard HTML element (equivalent to {@link #addElement})</li>
183     * <li>Field: Any form field (equivalent to {@link #addField})</li>
184     * <li>Item: Any subclass of {@link Ext.Toolbar.Item} (equivalent to {@link #addItem})</li>
185     * <li>String: Any generic string (gets wrapped in a {@link Ext.Toolbar.TextItem}, equivalent to {@link #addText}).
186     * Note that there are a few special strings that are treated differently as explained next.</li>
187     * <li>'-': Creates a separator element (equivalent to {@link #addSeparator})</li>
188     * <li>' ': Creates a spacer element (equivalent to {@link #addSpacer})</li>
189     * <li>'->': Creates a fill element (equivalent to {@link #addFill})</li>
190     * </ul>
191     * @param {Mixed} arg2
192     * @param {Mixed} etc.
193     * @method add
194     */
195
196    // private
197    lookupComponent : function(c){
198        if(Ext.isString(c)){
199            if(c == '-'){
200                c = new T.Separator();
201            }else if(c == ' '){
202                c = new T.Spacer();
203            }else if(c == '->'){
204                c = new T.Fill();
205            }else{
206                c = new T.TextItem(c);
207            }
208            this.applyDefaults(c);
209        }else{
210            if(c.isFormField || c.render){ // some kind of form field, some kind of Toolbar.Item
211                c = this.createComponent(c);
212            }else if(c.tag){ // DomHelper spec
213                c = new T.Item({autoEl: c});
214            }else if(c.tagName){ // element
215                c = new T.Item({el:c});
216            }else if(Ext.isObject(c)){ // must be button config?
217                c = c.xtype ? this.createComponent(c) : this.constructButton(c);
218            }
219        }
220        return c;
221    },
222
223    // private
224    applyDefaults : function(c){
225        if(!Ext.isString(c)){
226            c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
227            var d = this.internalDefaults;
228            if(c.events){
229                Ext.applyIf(c.initialConfig, d);
230                Ext.apply(c, d);
231            }else{
232                Ext.applyIf(c, d);
233            }
234        }
235        return c;
236    },
237
238    /**
239     * Adds a separator
240     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
241     * @return {Ext.Toolbar.Item} The separator {@link Ext.Toolbar.Item item}
242     */
243    addSeparator : function(){
244        return this.add(new T.Separator());
245    },
246
247    /**
248     * Adds a spacer element
249     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
250     * @return {Ext.Toolbar.Spacer} The spacer item
251     */
252    addSpacer : function(){
253        return this.add(new T.Spacer());
254    },
255
256    /**
257     * Forces subsequent additions into the float:right toolbar
258     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
259     */
260    addFill : function(){
261        this.add(new T.Fill());
262    },
263
264    /**
265     * Adds any standard HTML element to the toolbar
266     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
267     * @param {Mixed} el The element or id of the element to add
268     * @return {Ext.Toolbar.Item} The element's item
269     */
270    addElement : function(el){
271        return this.addItem(new T.Item({el:el}));
272    },
273
274    /**
275     * Adds any Toolbar.Item or subclass
276     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
277     * @param {Ext.Toolbar.Item} item
278     * @return {Ext.Toolbar.Item} The item
279     */
280    addItem : function(item){
281        return this.add.apply(this, arguments);
282    },
283
284    /**
285     * Adds a button (or buttons). See {@link Ext.Button} for more info on the config.
286     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
287     * @param {Object/Array} config A button config or array of configs
288     * @return {Ext.Button/Array}
289     */
290    addButton : function(config){
291        if(Ext.isArray(config)){
292            var buttons = [];
293            for(var i = 0, len = config.length; i < len; i++) {
294                buttons.push(this.addButton(config[i]));
295            }
296            return buttons;
297        }
298        return this.add(this.constructButton(config));
299    },
300
301    /**
302     * Adds text to the toolbar
303     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
304     * @param {String} text The text to add
305     * @return {Ext.Toolbar.Item} The element's item
306     */
307    addText : function(text){
308        return this.addItem(new T.TextItem(text));
309    },
310
311    /**
312     * Adds a new element to the toolbar from the passed {@link Ext.DomHelper} config
313     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
314     * @param {Object} config
315     * @return {Ext.Toolbar.Item} The element's item
316     */
317    addDom : function(config){
318        return this.add(new T.Item({autoEl: config}));
319    },
320
321    /**
322     * Adds a dynamically rendered Ext.form field (TextField, ComboBox, etc). Note: the field should not have
323     * been rendered yet. For a field that has already been rendered, use {@link #addElement}.
324     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
325     * @param {Ext.form.Field} field
326     * @return {Ext.Toolbar.Item}
327     */
328    addField : function(field){
329        return this.add(field);
330    },
331
332    /**
333     * Inserts any {@link Ext.Toolbar.Item}/{@link Ext.Button} at the specified index.
334     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>
335     * @param {Number} index The index where the item is to be inserted
336     * @param {Object/Ext.Toolbar.Item/Ext.Button/Array} item The button, or button config object to be
337     * inserted, or an array of buttons/configs.
338     * @return {Ext.Button/Item}
339     */
340    insertButton : function(index, item){
341        if(Ext.isArray(item)){
342            var buttons = [];
343            for(var i = 0, len = item.length; i < len; i++) {
344               buttons.push(this.insertButton(index + i, item[i]));
345            }
346            return buttons;
347        }
348        return Ext.Toolbar.superclass.insert.call(this, index, item);
349    },
350
351    // private
352    trackMenu : function(item, remove){
353        if(this.trackMenus && item.menu){
354            var method = remove ? 'mun' : 'mon';
355            this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
356            this[method](item, 'menushow', this.onButtonMenuShow, this);
357            this[method](item, 'menuhide', this.onButtonMenuHide, this);
358        }
359    },
360
361    // private
362    constructButton : function(item){
363        var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
364        return b;
365    },
366
367    // private
368    onAdd : function(c){
369        Ext.Toolbar.superclass.onAdd.call(this);
370        this.trackMenu(c);
371        if(this.disabled){
372            c.disable();
373        }
374    },
375
376    // private
377    onRemove : function(c){
378        Ext.Toolbar.superclass.onRemove.call(this);
379        if (c == this.activeMenuBtn) {
380            delete this.activeMenuBtn;
381        }
382        this.trackMenu(c, true);
383    },
384
385    // private
386    onDisable : function(){
387        this.items.each(function(item){
388             if(item.disable){
389                 item.disable();
390             }
391        });
392    },
393
394    // private
395    onEnable : function(){
396        this.items.each(function(item){
397             if(item.enable){
398                 item.enable();
399             }
400        });
401    },
402
403    // private
404    onButtonTriggerOver : function(btn){
405        if(this.activeMenuBtn && this.activeMenuBtn != btn){
406            this.activeMenuBtn.hideMenu();
407            btn.showMenu();
408            this.activeMenuBtn = btn;
409        }
410    },
411
412    // private
413    onButtonMenuShow : function(btn){
414        this.activeMenuBtn = btn;
415    },
416
417    // private
418    onButtonMenuHide : function(btn){
419        delete this.activeMenuBtn;
420    }
421});
422Ext.reg('toolbar', Ext.Toolbar);
423
424/**
425 * @class Ext.Toolbar.Item
426 * @extends Ext.BoxComponent
427 * The base class that other non-interacting Toolbar Item classes should extend in order to
428 * get some basic common toolbar item functionality.
429 * @constructor
430 * Creates a new Item
431 * @param {HTMLElement} el
432 * @xtype tbitem
433 */
434T.Item = Ext.extend(Ext.BoxComponent, {
435    hideParent: true, //  Hiding a Toolbar.Item hides its containing TD
436    enable:Ext.emptyFn,
437    disable:Ext.emptyFn,
438    focus:Ext.emptyFn
439    /**
440     * @cfg {String} overflowText Text to be used for the menu if the item is overflowed.
441     */
442});
443Ext.reg('tbitem', T.Item);
444
445/**
446 * @class Ext.Toolbar.Separator
447 * @extends Ext.Toolbar.Item
448 * A simple class that adds a vertical separator bar between toolbar items
449 * (css class:<tt>'xtb-sep'</tt>). Example usage:
450 * <pre><code>
451new Ext.Panel({
452    tbar : [
453        'Item 1',
454        {xtype: 'tbseparator'}, // or '-'
455        'Item 2'
456    ]
457});
458</code></pre>
459 * @constructor
460 * Creates a new Separator
461 * @xtype tbseparator
462 */
463T.Separator = Ext.extend(T.Item, {
464    onRender : function(ct, position){
465        this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
466    }
467});
468Ext.reg('tbseparator', T.Separator);
469
470/**
471 * @class Ext.Toolbar.Spacer
472 * @extends Ext.Toolbar.Item
473 * A simple element that adds extra horizontal space between items in a toolbar.
474 * By default a 2px wide space is added via css specification:<pre><code>
475.x-toolbar .xtb-spacer {
476    width:2px;
477}
478 * </code></pre>
479 * <p>Example usage:</p>
480 * <pre><code>
481new Ext.Panel({
482    tbar : [
483        'Item 1',
484        {xtype: 'tbspacer'}, // or ' '
485        'Item 2',
486        // space width is also configurable via javascript
487        {xtype: 'tbspacer', width: 50}, // add a 50px space
488        'Item 3'
489    ]
490});
491</code></pre>
492 * @constructor
493 * Creates a new Spacer
494 * @xtype tbspacer
495 */
496T.Spacer = Ext.extend(T.Item, {
497    /**
498     * @cfg {Number} width
499     * The width of the spacer in pixels (defaults to 2px via css style <tt>.x-toolbar .xtb-spacer</tt>).
500     */
501
502    onRender : function(ct, position){
503        this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
504    }
505});
506Ext.reg('tbspacer', T.Spacer);
507
508/**
509 * @class Ext.Toolbar.Fill
510 * @extends Ext.Toolbar.Spacer
511 * A non-rendering placeholder item which instructs the Toolbar's Layout to begin using
512 * the right-justified button container.
513 * <pre><code>
514new Ext.Panel({
515    tbar : [
516        'Item 1',
517        {xtype: 'tbfill'}, // or '->'
518        'Item 2'
519    ]
520});
521</code></pre>
522 * @constructor
523 * Creates a new Fill
524 * @xtype tbfill
525 */
526T.Fill = Ext.extend(T.Item, {
527    // private
528    render : Ext.emptyFn,
529    isFill : true
530});
531Ext.reg('tbfill', T.Fill);
532
533/**
534 * @class Ext.Toolbar.TextItem
535 * @extends Ext.Toolbar.Item
536 * A simple class that renders text directly into a toolbar
537 * (with css class:<tt>'xtb-text'</tt>). Example usage:
538 * <pre><code>
539new Ext.Panel({
540    tbar : [
541        {xtype: 'tbtext', text: 'Item 1'} // or simply 'Item 1'
542    ]
543});
544</code></pre>
545 * @constructor
546 * Creates a new TextItem
547 * @param {String/Object} text A text string, or a config object containing a <tt>text</tt> property
548 * @xtype tbtext
549 */
550T.TextItem = Ext.extend(T.Item, {
551    /**
552     * @cfg {String} text The text to be used as innerHTML (html tags are accepted)
553     */
554
555    constructor: function(config){
556        T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
557    },
558
559    // private
560    onRender : function(ct, position) {
561        this.autoEl = {cls: 'xtb-text', html: this.text || ''};
562        T.TextItem.superclass.onRender.call(this, ct, position);
563    },
564
565    /**
566     * Updates this item's text, setting the text to be used as innerHTML.
567     * @param {String} t The text to display (html accepted).
568     */
569    setText : function(t) {
570        if(this.rendered){
571            this.el.update(t);
572        }else{
573            this.text = t;
574        }
575    }
576});
577Ext.reg('tbtext', T.TextItem);
578
579// backwards compat
580T.Button = Ext.extend(Ext.Button, {});
581T.SplitButton = Ext.extend(Ext.SplitButton, {});
582Ext.reg('tbbutton', T.Button);
583Ext.reg('tbsplit', T.SplitButton);
584
585})();
586/**
587 * @class Ext.ButtonGroup
588 * @extends Ext.Panel
589 * Container for a group of buttons. Example usage:
590 * <pre><code>
591var p = new Ext.Panel({
592    title: 'Panel with Button Group',
593    width: 300,
594    height:200,
595    renderTo: document.body,
596    html: 'whatever',
597    tbar: [{
598        xtype: 'buttongroup',
599        {@link #columns}: 3,
600        title: 'Clipboard',
601        items: [{
602            text: 'Paste',
603            scale: 'large',
604            rowspan: 3, iconCls: 'add',
605            iconAlign: 'top',
606            cls: 'x-btn-as-arrow'
607        },{
608            xtype:'splitbutton',
609            text: 'Menu Button',
610            scale: 'large',
611            rowspan: 3,
612            iconCls: 'add',
613            iconAlign: 'top',
614            arrowAlign:'bottom',
615            menu: [{text: 'Menu Item 1'}]
616        },{
617            xtype:'splitbutton', text: 'Cut', iconCls: 'add16', menu: [{text: 'Cut Menu Item'}]
618        },{
619            text: 'Copy', iconCls: 'add16'
620        },{
621            text: 'Format', iconCls: 'add16'
622        }]
623    }]
624});
625 * </code></pre>
626 * @constructor
627 * Create a new ButtonGroup.
628 * @param {Object} config The config object
629 * @xtype buttongroup
630 */
631Ext.ButtonGroup = Ext.extend(Ext.Panel, {
632    /**
633     * @cfg {Number} columns The <tt>columns</tt> configuration property passed to the
634     * {@link #layout configured layout manager}. See {@link Ext.layout.TableLayout#columns}.
635     */
636    /**
637     * @cfg {String} baseCls  Defaults to <tt>'x-btn-group'</tt>.  See {@link Ext.Panel#baseCls}.
638     */
639    baseCls: 'x-btn-group',
640    /**
641     * @cfg {String} layout  Defaults to <tt>'table'</tt>.  See {@link Ext.Container#layout}.
642     */
643    layout:'table',
644    defaultType: 'button',
645    /**
646     * @cfg {Boolean} frame  Defaults to <tt>true</tt>.  See {@link Ext.Panel#frame}.
647     */
648    frame: true,
649    internalDefaults: {removeMode: 'container', hideParent: true},
650
651    initComponent : function(){
652        this.layoutConfig = this.layoutConfig || {};
653        Ext.applyIf(this.layoutConfig, {
654            columns : this.columns
655        });
656        if(!this.title){
657            this.addClass('x-btn-group-notitle');
658        }
659        this.on('afterlayout', this.onAfterLayout, this);
660        Ext.ButtonGroup.superclass.initComponent.call(this);
661    },
662
663    applyDefaults : function(c){
664        c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
665        var d = this.internalDefaults;
666        if(c.events){
667            Ext.applyIf(c.initialConfig, d);
668            Ext.apply(c, d);
669        }else{
670            Ext.applyIf(c, d);
671        }
672        return c;
673    },
674
675    onAfterLayout : function(){
676        var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
677        this.body.setWidth(bodyWidth);
678        this.el.setWidth(bodyWidth + this.getFrameWidth());
679    }
680    /**
681     * @cfg {Array} tools  @hide
682     */
683});
684
685Ext.reg('buttongroup', Ext.ButtonGroup);
686/**
687 * @class Ext.PagingToolbar
688 * @extends Ext.Toolbar
689 * <p>As the amount of records increases, the time required for the browser to render
690 * them increases. Paging is used to reduce the amount of data exchanged with the client.
691 * Note: if there are more records/rows than can be viewed in the available screen area, vertical
692 * scrollbars will be added.</p>
693 * <p>Paging is typically handled on the server side (see exception below). The client sends
694 * parameters to the server side, which the server needs to interpret and then respond with the
695 * approprate data.</p>
696 * <p><b>Ext.PagingToolbar</b> is a specialized toolbar that is bound to a {@link Ext.data.Store}
697 * and provides automatic paging control. This Component {@link Ext.data.Store#load load}s blocks
698 * of data into the <tt>{@link #store}</tt> by passing {@link Ext.data.Store#paramNames paramNames} used for
699 * paging criteria.</p>
700 * <p>PagingToolbar is typically used as one of the Grid's toolbars:</p>
701 * <pre><code>
702Ext.QuickTips.init(); // to display button quicktips
703
704var myStore = new Ext.data.Store({
705    reader: new Ext.data.JsonReader({
706        {@link Ext.data.JsonReader#totalProperty totalProperty}: 'results',
707        ...
708    }),
709    ...
710});
711
712var myPageSize = 25;  // server script should only send back 25 items at a time
713
714var grid = new Ext.grid.GridPanel({
715    ...
716    store: myStore,
717    bbar: new Ext.PagingToolbar({
718        {@link #store}: myStore,       // grid and PagingToolbar using same store
719        {@link #displayInfo}: true,
720        {@link #pageSize}: myPageSize,
721        {@link #prependButtons}: true,
722        items: [
723            'text 1'
724        ]
725    })
726});
727 * </code></pre>
728 *
729 * <p>To use paging, pass the paging requirements to the server when the store is first loaded.</p>
730 * <pre><code>
731store.load({
732    params: {
733        // specify params for the first page load if using paging
734        start: 0,         
735        limit: myPageSize,
736        // other params
737        foo:   'bar'
738    }
739});
740 * </code></pre>
741 *
742 * <p>If using {@link Ext.data.Store#autoLoad store's autoLoad} configuration:</p>
743 * <pre><code>
744var myStore = new Ext.data.Store({
745    {@link Ext.data.Store#autoLoad autoLoad}: {params:{start: 0, limit: 25}},
746    ...
747});
748 * </code></pre>
749 *
750 * <p>The packet sent back from the server would have this form:</p>
751 * <pre><code>
752{
753    "success": true,
754    "results": 2000,
755    "rows": [ // <b>*Note:</b> this must be an Array
756        { "id":  1, "name": "Bill", "occupation": "Gardener" },
757        { "id":  2, "name":  "Ben", "occupation": "Horticulturalist" },
758        ...
759        { "id": 25, "name":  "Sue", "occupation": "Botanist" }
760    ]
761}
762 * </code></pre>
763 * <p><u>Paging with Local Data</u></p>
764 * <p>Paging can also be accomplished with local data using extensions:</p>
765 * <div class="mdetail-params"><ul>
766 * <li><a href="http://extjs.com/forum/showthread.php?t=71532">Ext.ux.data.PagingStore</a></li>
767 * <li>Paging Memory Proxy (examples/ux/PagingMemoryProxy.js)</li>
768 * </ul></div>
769 * @constructor Create a new PagingToolbar
770 * @param {Object} config The config object
771 * @xtype paging
772 */
773(function() {
774
775var T = Ext.Toolbar;
776
777Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
778    /**
779     * @cfg {Ext.data.Store} store
780     * The {@link Ext.data.Store} the paging toolbar should use as its data source (required).
781     */
782    /**
783     * @cfg {Boolean} displayInfo
784     * <tt>true</tt> to display the displayMsg (defaults to <tt>false</tt>)
785     */
786    /**
787     * @cfg {Number} pageSize
788     * The number of records to display per page (defaults to <tt>20</tt>)
789     */
790    pageSize : 20,
791    /**
792     * @cfg {Boolean} prependButtons
793     * <tt>true</tt> to insert any configured <tt>items</tt> <i>before</i> the paging buttons.
794     * Defaults to <tt>false</tt>.
795     */
796    /**
797     * @cfg {String} displayMsg
798     * The paging status message to display (defaults to <tt>'Displaying {0} - {1} of {2}'</tt>).
799     * Note that this string is formatted using the braced numbers <tt>{0}-{2}</tt> as tokens
800     * that are replaced by the values for start, end and total respectively. These tokens should
801     * be preserved when overriding this string if showing those values is desired.
802     */
803    displayMsg : 'Displaying {0} - {1} of {2}',
804    /**
805     * @cfg {String} emptyMsg
806     * The message to display when no records are found (defaults to 'No data to display')
807     */
808    emptyMsg : 'No data to display',
809    /**
810     * @cfg {String} beforePageText
811     * The text displayed before the input item (defaults to <tt>'Page'</tt>).
812     */
813    beforePageText : 'Page',
814    /**
815     * @cfg {String} afterPageText
816     * Customizable piece of the default paging text (defaults to <tt>'of {0}'</tt>). Note that
817     * this string is formatted using <tt>{0}</tt> as a token that is replaced by the number of
818     * total pages. This token should be preserved when overriding this string if showing the
819     * total page count is desired.
820     */
821    afterPageText : 'of {0}',
822    /**
823     * @cfg {String} firstText
824     * The quicktip text displayed for the first page button (defaults to <tt>'First Page'</tt>).
825     * <b>Note</b>: quick tips must be initialized for the quicktip to show.
826     */
827    firstText : 'First Page',
828    /**
829     * @cfg {String} prevText
830     * The quicktip text displayed for the previous page button (defaults to <tt>'Previous Page'</tt>).
831     * <b>Note</b>: quick tips must be initialized for the quicktip to show.
832     */
833    prevText : 'Previous Page',
834    /**
835     * @cfg {String} nextText
836     * The quicktip text displayed for the next page button (defaults to <tt>'Next Page'</tt>).
837     * <b>Note</b>: quick tips must be initialized for the quicktip to show.
838     */
839    nextText : 'Next Page',
840    /**
841     * @cfg {String} lastText
842     * The quicktip text displayed for the last page button (defaults to <tt>'Last Page'</tt>).
843     * <b>Note</b>: quick tips must be initialized for the quicktip to show.
844     */
845    lastText : 'Last Page',
846    /**
847     * @cfg {String} refreshText
848     * The quicktip text displayed for the Refresh button (defaults to <tt>'Refresh'</tt>).
849     * <b>Note</b>: quick tips must be initialized for the quicktip to show.
850     */
851    refreshText : 'Refresh',
852
853    /**
854     * <p><b>Deprecated</b>. <code>paramNames</code> should be set in the <b>data store</b>
855     * (see {@link Ext.data.Store#paramNames}).</p>
856     * <br><p>Object mapping of parameter names used for load calls, initially set to:</p>
857     * <pre>{start: 'start', limit: 'limit'}</pre>
858     * @type Object
859     * @property paramNames
860     * @deprecated
861     */
862
863    /**
864     * The number of records to display per page.  See also <tt>{@link #cursor}</tt>.
865     * @type Number
866     * @property pageSize
867     */
868
869    /**
870     * Indicator for the record position.  This property might be used to get the active page
871     * number for example:<pre><code>
872     * // t is reference to the paging toolbar instance
873     * var activePage = Math.ceil((t.cursor + t.pageSize) / t.pageSize);
874     * </code></pre>
875     * @type Number
876     * @property cursor
877     */
878
879    initComponent : function(){
880        var pagingItems = [this.first = new T.Button({
881            tooltip: this.firstText,
882            overflowText: this.firstText,
883            iconCls: 'x-tbar-page-first',
884            disabled: true,
885            handler: this.moveFirst,
886            scope: this
887        }), this.prev = new T.Button({
888            tooltip: this.prevText,
889            overflowText: this.prevText,
890            iconCls: 'x-tbar-page-prev',
891            disabled: true,
892            handler: this.movePrevious,
893            scope: this
894        }), '-', this.beforePageText,
895        this.inputItem = new Ext.form.NumberField({
896            cls: 'x-tbar-page-number',
897            allowDecimals: false,
898            allowNegative: false,
899            enableKeyEvents: true,
900            selectOnFocus: true,
901            submitValue: false,
902            listeners: {
903                scope: this,
904                keydown: this.onPagingKeyDown,
905                blur: this.onPagingBlur
906            }
907        }), this.afterTextItem = new T.TextItem({
908            text: String.format(this.afterPageText, 1)
909        }), '-', this.next = new T.Button({
910            tooltip: this.nextText,
911            overflowText: this.nextText,
912            iconCls: 'x-tbar-page-next',
913            disabled: true,
914            handler: this.moveNext,
915            scope: this
916        }), this.last = new T.Button({
917            tooltip: this.lastText,
918            overflowText: this.lastText,
919            iconCls: 'x-tbar-page-last',
920            disabled: true,
921            handler: this.moveLast,
922            scope: this
923        }), '-', this.refresh = new T.Button({
924            tooltip: this.refreshText,
925            overflowText: this.refreshText,
926            iconCls: 'x-tbar-loading',
927            handler: this.doRefresh,
928            scope: this
929        })];
930
931
932        var userItems = this.items || this.buttons || [];
933        if (this.prependButtons) {
934            this.items = userItems.concat(pagingItems);
935        }else{
936            this.items = pagingItems.concat(userItems);
937        }
938        delete this.buttons;
939        if(this.displayInfo){
940            this.items.push('->');
941            this.items.push(this.displayItem = new T.TextItem({}));
942        }
943        Ext.PagingToolbar.superclass.initComponent.call(this);
944        this.addEvents(
945            /**
946             * @event change
947             * Fires after the active page has been changed.
948             * @param {Ext.PagingToolbar} this
949             * @param {Object} pageData An object that has these properties:<ul>
950             * <li><code>total</code> : Number <div class="sub-desc">The total number of records in the dataset as
951             * returned by the server</div></li>
952             * <li><code>activePage</code> : Number <div class="sub-desc">The current page number</div></li>
953             * <li><code>pages</code> : Number <div class="sub-desc">The total number of pages (calculated from
954             * the total number of records in the dataset as returned by the server and the current {@link #pageSize})</div></li>
955             * </ul>
956             */
957            'change',
958            /**
959             * @event beforechange
960             * Fires just before the active page is changed.
961             * Return false to prevent the active page from being changed.
962             * @param {Ext.PagingToolbar} this
963             * @param {Object} params An object hash of the parameters which the PagingToolbar will send when
964             * loading the required page. This will contain:<ul>
965             * <li><code>start</code> : Number <div class="sub-desc">The starting row number for the next page of records to
966             * be retrieved from the server</div></li>
967             * <li><code>limit</code> : Number <div class="sub-desc">The number of records to be retrieved from the server</div></li>
968             * </ul>
969             * <p>(note: the names of the <b>start</b> and <b>limit</b> properties are determined
970             * by the store's {@link Ext.data.Store#paramNames paramNames} property.)</p>
971             * <p>Parameters may be added as required in the event handler.</p>
972             */
973            'beforechange'
974        );
975        this.on('afterlayout', this.onFirstLayout, this, {single: true});
976        this.cursor = 0;
977        this.bindStore(this.store, true);
978    },
979
980    // private
981    onFirstLayout : function(){
982        if(this.dsLoaded){
983            this.onLoad.apply(this, this.dsLoaded);
984        }
985    },
986
987    // private
988    updateInfo : function(){
989        if(this.displayItem){
990            var count = this.store.getCount();
991            var msg = count == 0 ?
992                this.emptyMsg :
993                String.format(
994                    this.displayMsg,
995                    this.cursor+1, this.cursor+count, this.store.getTotalCount()
996                );
997            this.displayItem.setText(msg);
998        }
999    },
1000
1001    // private
1002    onLoad : function(store, r, o){
1003        if(!this.rendered){
1004            this.dsLoaded = [store, r, o];
1005            return;
1006        }
1007        var p = this.getParams();
1008        this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
1009        var d = this.getPageData(), ap = d.activePage, ps = d.pages;
1010
1011        this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
1012        this.inputItem.setValue(ap);
1013        this.first.setDisabled(ap == 1);
1014        this.prev.setDisabled(ap == 1);
1015        this.next.setDisabled(ap == ps);
1016        this.last.setDisabled(ap == ps);
1017        this.refresh.enable();
1018        this.updateInfo();
1019        this.fireEvent('change', this, d);
1020    },
1021
1022    // private
1023    getPageData : function(){
1024        var total = this.store.getTotalCount();
1025        return {
1026            total : total,
1027            activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
1028            pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
1029        };
1030    },
1031
1032    /**
1033     * Change the active page
1034     * @param {Integer} page The page to display
1035     */
1036    changePage : function(page){
1037        this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
1038    },
1039
1040    // private
1041    onLoadError : function(){
1042        if(!this.rendered){
1043            return;
1044        }
1045        this.refresh.enable();
1046    },
1047
1048    // private
1049    readPage : function(d){
1050        var v = this.inputItem.getValue(), pageNum;
1051        if (!v || isNaN(pageNum = parseInt(v, 10))) {
1052            this.inputItem.setValue(d.activePage);
1053            return false;
1054        }
1055        return pageNum;
1056    },
1057
1058    onPagingFocus : function(){
1059        this.inputItem.select();
1060    },
1061
1062    //private
1063    onPagingBlur : function(e){
1064        this.inputItem.setValue(this.getPageData().activePage);
1065    },
1066
1067    // private
1068    onPagingKeyDown : function(field, e){
1069        var k = e.getKey(), d = this.getPageData(), pageNum;
1070        if (k == e.RETURN) {
1071            e.stopEvent();
1072            pageNum = this.readPage(d);
1073            if(pageNum !== false){
1074                pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
1075                this.doLoad(pageNum * this.pageSize);
1076            }
1077        }else if (k == e.HOME || k == e.END){
1078            e.stopEvent();
1079            pageNum = k == e.HOME ? 1 : d.pages;
1080            field.setValue(pageNum);
1081        }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
1082            e.stopEvent();
1083            if((pageNum = this.readPage(d))){
1084                var increment = e.shiftKey ? 10 : 1;
1085                if(k == e.DOWN || k == e.PAGEDOWN){
1086                    increment *= -1;
1087                }
1088                pageNum += increment;
1089                if(pageNum >= 1 & pageNum <= d.pages){
1090                    field.setValue(pageNum);
1091                }
1092            }
1093        }
1094    },
1095
1096    // private
1097    getParams : function(){
1098        //retain backwards compat, allow params on the toolbar itself, if they exist.
1099        return this.paramNames || this.store.paramNames;
1100    },
1101
1102    // private
1103    beforeLoad : function(){
1104        if(this.rendered && this.refresh){
1105            this.refresh.disable();
1106        }
1107    },
1108
1109    // private
1110    doLoad : function(start){
1111        var o = {}, pn = this.getParams();
1112        o[pn.start] = start;
1113        o[pn.limit] = this.pageSize;
1114        if(this.fireEvent('beforechange', this, o) !== false){
1115            this.store.load({params:o});
1116        }
1117    },
1118
1119    /**
1120     * Move to the first page, has the same effect as clicking the 'first' button.
1121     */
1122    moveFirst : function(){
1123        this.doLoad(0);
1124    },
1125
1126    /**
1127     * Move to the previous page, has the same effect as clicking the 'previous' button.
1128     */
1129    movePrevious : function(){
1130        this.doLoad(Math.max(0, this.cursor-this.pageSize));
1131    },
1132
1133    /**
1134     * Move to the next page, has the same effect as clicking the 'next' button.
1135     */
1136    moveNext : function(){
1137        this.doLoad(this.cursor+this.pageSize);
1138    },
1139
1140    /**
1141     * Move to the last page, has the same effect as clicking the 'last' button.
1142     */
1143    moveLast : function(){
1144        var total = this.store.getTotalCount(),
1145            extra = total % this.pageSize;
1146
1147        this.doLoad(extra ? (total - extra) : total - this.pageSize);
1148    },
1149
1150    /**
1151     * Refresh the current page, has the same effect as clicking the 'refresh' button.
1152     */
1153    doRefresh : function(){
1154        this.doLoad(this.cursor);
1155    },
1156
1157    /**
1158     * Binds the paging toolbar to the specified {@link Ext.data.Store}
1159     * @param {Store} store The store to bind to this toolbar
1160     * @param {Boolean} initial (Optional) true to not remove listeners
1161     */
1162    bindStore : function(store, initial){
1163        var doLoad;
1164        if(!initial && this.store){
1165            if(store !== this.store && this.store.autoDestroy){
1166                this.store.destroy();
1167            }else{
1168                this.store.un('beforeload', this.beforeLoad, this);
1169                this.store.un('load', this.onLoad, this);
1170                this.store.un('exception', this.onLoadError, this);
1171            }
1172            if(!store){
1173                this.store = null;
1174            }
1175        }
1176        if(store){
1177            store = Ext.StoreMgr.lookup(store);
1178            store.on({
1179                scope: this,
1180                beforeload: this.beforeLoad,
1181                load: this.onLoad,
1182                exception: this.onLoadError
1183            });
1184            doLoad = true;
1185        }
1186        this.store = store;
1187        if(doLoad){
1188            this.onLoad(store, null, {});
1189        }
1190    },
1191
1192    /**
1193     * Unbinds the paging toolbar from the specified {@link Ext.data.Store} <b>(deprecated)</b>
1194     * @param {Ext.data.Store} store The data store to unbind
1195     */
1196    unbind : function(store){
1197        this.bindStore(null);
1198    },
1199
1200    /**
1201     * Binds the paging toolbar to the specified {@link Ext.data.Store} <b>(deprecated)</b>
1202     * @param {Ext.data.Store} store The data store to bind
1203     */
1204    bind : function(store){
1205        this.bindStore(store);
1206    },
1207
1208    // private
1209    onDestroy : function(){
1210        this.bindStore(null);
1211        Ext.PagingToolbar.superclass.onDestroy.call(this);
1212    }
1213});
1214
1215})();
1216Ext.reg('paging', Ext.PagingToolbar);
Note: See TracBrowser for help on using the repository browser.