3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">Ext.ns('Ext.ux');
10 <div id="prop-Ext.ux.TaskBar.TaskButton-MultiCombo"></div>/**
13 Ext.ux.MultiCombo = Ext.extend(Ext.form.ComboBox, {
15 <div id="cfg-Ext.ux.TaskBar.TaskButton-overClass"></div>/**
16 * @cfg {String} overClass [x-grid3-row-over]
18 overClass : 'x-grid3-row-over',
19 <div id="cfg-Ext.ux.TaskBar.TaskButton-enableKeyEvents"></div>/**
20 * @cfg {Boolean} enableKeyEvents for typeAhead
22 enableKeyEvents: true,
23 <div id="cfg-Ext.ux.TaskBar.TaskButton-selectedClass"></div>/**
24 * @cfg {String} selectedClass [x-grid3-row-selected]
26 selectedClass: 'x-grid3-row-selected',
27 <div id="cfg-Ext.ux.TaskBar.TaskButton-highlightClass"></div>/**
28 * @cfg {String} highlightClass The css class applied to rows which are hovered with mouse
29 * selected via key-nav, or highlighted when a text-query matches a single item.
31 highlightClass: 'x-grid3-row-over',
32 <div id="cfg-Ext.ux.TaskBar.TaskButton-autoSelectKey"></div>/**
33 * @cfg {Number} autoSelectKey [44] COMMA Sets the key used to auto-select an auto-suggest
34 * highlighted query. When pressed, the highlighted text-item will be selected as if the user
35 * selected the row with a mouse click.
38 <div id="cfg-Ext.ux.TaskBar.TaskButton-allSelectedText"></div>/**
39 * @cfg {String} allSelectedText Text to display when all items are selected
41 allSelectedText : 'All selected',
42 <div id="cfg-Ext.ux.TaskBar.TaskButton-maxDisplayRows"></div>/**
43 * @cfg {Number} maxDisplayRows The maximum number of rows to show before applying vscroll
52 highlightIndex : null,
53 highlightIndexPrev : null,
58 <div id="cfg-Ext.ux.TaskBar.TaskButton-value"></div>/**
59 * @cfg {Array} value CheckboxCombo expresses its value as an array.
63 <div id="cfg-Ext.ux.TaskBar.TaskButton-minChars"></div>/**
64 * @cfg {Integer} minChars [0]
68 initComponent : function() {
69 var cls = 'x-combo-list';
71 // when blurring out of field, ensure that rawValue contains ONLY items contained in Store.
72 this.on('blur', this.validateSelections.createDelegate(this));
74 // create an auto-select key handler, like *nix-based console [tab] key behaviour
75 this.on('keypress', function(field, ev) {
76 if (ev.getKey() == this.autoSelectKey) { // COMMA
82 <div id="event-Ext.ux.TaskBar.TaskButton-initview"></div>/**
83 * @event initview Fires when Combo#initView is called.
84 * gives plugins a chance to interact with DataView
87 * @param {DataView} dv
93 // when list expands, constrain the height with @cfg maxDisplayRows
94 if (this.maxDisplayRows) {
95 this.on('expand', function(){
96 var cnt = this.store.getCount();
97 if (cnt > this.maxDisplayRows) {
98 var children = this.view.getNodes();
100 for (var n = 0; n < this.maxDisplayRows; n++) {
101 h += Ext.fly(children[n]).getHeight();
110 this.on('beforequery', this.onQuery, this);
112 // Enforce that plugins is an Array.
113 if (typeof(this.plugins) == 'undefined'){
116 else if (!Ext.isArray(this.plugins)) {
117 this.plugins = [this.plugins];
120 var tmp = this.value; // for case where transform is set.
121 Ext.ux.MultiCombo.superclass.initComponent.call(this);
122 if (this.transform) {
123 if (typeof(tmp) == 'undefined') {
131 onViewClick : function(dv, index, node, ev){
132 var rec = this.store.getAt(index);
133 this.onSelect(rec, index);
136 if(doFocus !== false){
142 // onTriggerClick, overrides Ext.form.ComboBox#onTriggerClick
143 onTriggerClick: function() {
144 if (this.highlightIndex != -1) {
145 this.clearHighlight();
147 this.highlightIndex = -1;
152 if(this.isExpanded()){
157 if(this.triggerAction == 'all') {
158 this.doQuery(this.getRawValue(), true);
159 var vlen = this.getValue().length, slen = this.view.getSelectedRecords().length;
160 if (vlen != slen || vlen == 0) {
161 this.selectByValue(this.value, true);
165 this.doQuery(this.getRawValue());
168 this.highlightIndex = -1
169 this.highlightIndexPrev = null;
171 this.scrollIntoView();
176 // onQuery, beforequery listener, @return false
177 onQuery : function(qe) {
179 forceAll = qe.forceAll;
180 if(forceAll === true || (q.length >= this.minChars)){
181 if(this.lastQuery !== q){
182 if (typeof(this.lastQuery) != 'undefined') {
183 if (q.match(new RegExp('^'+this.allSelectedText))) {
184 this.query = this.store.data;
186 else if (this.lastQuery.length > q.length) {
187 var items = q.replace(/\s+/g, '').split(',');
188 if (items[items.length-1].length == 0) {
191 this.query = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+items.join('$|^')+'$', "i"), false, false));
198 if(this.mode == 'local'){
199 var raw = this.getRawValue();
200 if (raw == this.allSelectedText) {
203 var items = raw.replace(/\s+/g, '').split(',');
204 var last = items.pop();
205 this.matches = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+last, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items));
206 if (this.matches.getCount() == 0) {
207 this.clearHighlight();
210 this.view.clearSelections();
211 this.updateValue([]);
216 this.store.baseParams[this.queryParam] = q;
218 params: this.getParams(q)
223 this.selectedIndex = -1;
231 // onLoad, overrides Ext.form.ComboBox#onLoad
237 if(this.store.getCount() > 0){
238 if (!this.isExpanded()) {
240 this.restrictHeight();
242 if(this.lastQuery == this.allQuery){
244 this.el.dom.select();
247 if (this.query != null) {
248 var values = [], indexes = [];
249 this.query.each(function(r){
250 values.push(r.data[this.valueField]);
251 indexes.push(this.store.indexOf(r));
253 this.view.clearSelections();
254 this.updateValue(values, this.getRawValue());
255 this.view.select(indexes);
257 if (this.matches != null) {
258 if (this.matches.getCount() == 1) {
259 this.highlight(this.store.indexOf(this.matches.first()));
260 this.scrollIntoView();
264 // @HACK: If store was configured with a proxy, set its mode to local now that its populated with data.
265 // Re-execute the query now.
267 this.lastQuery = undefined;
268 this.doQuery(this.getRawValue(), true);
270 if(this.typeAhead && this.lastKey != Ext.EventObject.DOWN && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
271 this.taTask.delay(this.typeAheadDelay);
275 this.onEmptyResults();
279 onSelect : function(record, index) {
281 throw new Error('MultiCombo#onSelect did not receive a valid index');
284 // select only when user clicks [apply] button
285 if (this.selectOnApply == true) {
289 if (this.fireEvent('beforeselect', this, record, index) !== false) {
292 var rs = this.view.getSelectedRecords();
293 for (var n = 0, len = rs.length; n < len; n++) {
294 text.push(rs[n].data[this.displayField]);
295 value.push(rs[n].data[this.valueField]);
297 this.updateValue(value, (value.length != this.store.getCount()) ? text.join(', ') : this.allSelectedText);
298 var node = this.view.getNode(index);
299 this.innerList.scrollChildIntoView(node, false);
300 this.fireEvent('select', this, record, index);
305 onViewOver : function(ev, node){
306 var t = ev.getTarget(this.view.itemSelector);
310 this.highlightIndex = this.store.indexOf(this.view.getRecord(t));
311 this.clearHighlight();
312 this.highlight(this.highlightIndex);
313 if(this.inKeyMode){ // prevent key nav and mouse over conflicts
320 onTypeAhead : function(){
321 if(this.store.getCount() > 0){
322 this.inKeyMode = false;
323 var raw = this.getRawValue();
324 var pos = this.getCaretPosition(raw);
327 if (pos !== false && pos < raw.length) {
328 items = raw.substr(0, pos).replace(/\s+/g, '').split(',');
331 items = raw.replace(/\s+/g, '').split(',');
334 var rs = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp(query, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items));
336 if (rs.getCount() == 1) {
338 var rindex = this.store.indexOf(r)
339 if (!this.view.isSelected(rindex)) {
340 this.typeAheadSelected = true;
341 var selStart = raw.length;
342 var len = items.join(',').length;
344 var newValue = r.data[this.displayField];
345 if (pos !== false && pos < raw.length) {
346 var insertIdx = items.length;
348 items = raw.replace(/\s+/g, '').split(',');
349 items.splice(insertIdx, 1, newValue);
350 selEnd = items.slice(0, insertIdx+1).join(', ').length;
351 this.highlight(rindex);
352 this.scrollIntoView();
356 items.push(newValue);
358 var len = items.join(',').length;
360 var lastWord = raw.split(',').pop();
361 if (items.length >1 && lastWord.match(/^\s+/) == null) {
364 this.setRawValue(items.join(', '));
365 this.selectText(selStart, (selEnd!=null) ? selEnd : this.getRawValue().length);
373 var selected = this.view.getSelectedRecords();
375 for (var n=0,len=selected.length;n<len;n++) {
376 value.push(selected[n].data[this.valueField]);
378 this.setValue(value);
381 getCaretPosition : function(raw) {
382 raw = raw || this.getRawValue();
383 if(document.selection) { // <-- IE, ugh: http://parentnode.org/javascript/working-with-the-cursor-position/
384 var range = document.selection.createRange();
385 //Save the current value. We will need this value later to find out, where the text has been changed
386 var orig = obj.value.replace(/rn/g, "n");
389 // Now get the new content and save it into a temporary variable
390 var actual = tmp = obj.value.replace(/rn/g, "n");
391 /* Find the first occurance, where the original differs
392 from the actual content. This could be the startposition
393 of our text selection, but it has not to be. Think of the
394 selection "ab" and replacing it with "ac". The first
395 difference would be the "c", while the start position
398 for(var diff = 0; diff < orig.length; diff++) {
399 if(orig.charAt(diff) != actual.charAt(diff)) break;
402 /* To get the real start position, we iterate through
403 the string searching for the whole replacement
404 text - "abc", as long as the first difference is not
405 reached. If you do not understand that logic - no
406 blame to you, just copy & paste it ;)
408 for(var index = 0, start = 0; tmp.match(text) && (tmp = tmp.replace(text, "")) && index <= diff; index = start + text.length) {
409 start = actual.indexOf(text, index);
411 } else if(this.el.dom.selectionStart) { // <-- Go the Gecko way
412 return this.el.dom.selectionStart;
414 // Fallback for any other browser
419 onAutoSelect : function() {
420 if (!this.isExpanded()) {
421 var vlen = this.getValue().length, slen = this.view.getSelectedRecords().length;
422 if (vlen != slen || vlen == 0) {
423 this.selectByValue(this.value, true);
426 var raw = this.getRawValue();
427 this.selectText(raw.length, raw.length);
429 var pos = this.getCaretPosition(raw);
431 if (pos !== false && pos < raw.length) {
432 word = Ext.util.Format.trim(raw.substr(0, pos).split(',').pop());
434 word = Ext.util.Format.trim(raw.split(',').pop());
436 var idx = this.store.find(this.displayField, word);
437 if (idx > -1 && !this.view.isSelected(idx)) {
438 var rec = this.store.getAt(idx);
442 // filters-out already-selected items from type-ahead queries.
443 // e.g.: if store contains: "betty, barney, bart" and betty is already selected,
444 // when user types "b", only "bart" and "barney" should be returned as possible matches,
445 // since betty is *already* selected
446 createTypeAheadFilterFn : function(items) {
447 var key = this.displayField;
448 return function(rec) {
449 var re = new RegExp(rec.data[key], "i");
451 for (var n=0,len=items.length;n<len;n++) {
452 if (re.test(items[n])) {
461 updateValue : function(value, text) {
463 if(this.hiddenField){
464 this.hiddenField.value = value.join(',');
466 if (typeof(text) == 'string') {
467 this.setRawValue(text);
472 <div id="method-Ext.ux.TaskBar.TaskButton-setValue"></div>/**
474 * Accepts a comma-separated list of ids or an array. if given a string, will conver to Array.
475 * @param {Array, String} v
477 setValue : function(v) {
481 if (typeof(v) == 'string') { // <-- "1,2,3"
482 value = v.match(/\d+/g); // <-- strip multiple spaces and split on ","
484 for (var n=0,len=value.length;n<len;n++) {
485 value[n] = parseInt(value[n]);
489 else if (Ext.isArray(v)) { // <-- [1,2,3]
492 if (value && value.length) {
493 if (this.mode == 'local') {
494 this.updateValue(value);
495 this.setRawValue(this.getTextValue());
498 this.updateValue(value);
500 callback: function() {
501 this.setRawValue(this.getTextValue());
510 getTextValue : function() {
511 if (this.value.length == this.store.getCount()) {
512 return this.allSelectedText;
516 this.store.data.filterBy(this.store.createFilterFn(this.valueField, new RegExp(this.value.join('|'), "i"), false, false)).each(function(r){
517 text.push(r.data[this.displayField]);
519 return text.join(', ');
523 <div id="method-Ext.ux.TaskBar.TaskButton-select"></div>/**
524 * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
525 * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
526 * @param {Number} index The zero-based index of the list item to select
527 * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
528 * selected item if it is not currently in view (defaults to true)
530 select : function(index, scrollIntoView){
531 if (!typeof(index) == 'number') {
532 throw new Error('MultiCombo#select expected @param {Number} index but got: ' + typeof(index));
534 this.view.isSelected(index) ? this.view.deselect(index, true) : this.view.select(index, true);
535 this.onSelect(this.store.getAt(index), index);
538 if(scrollIntoView !== false){
539 var el = this.view.getNode(index);
541 this.innerList.scrollChildIntoView(el, false);
547 getLastValue : function() {
548 return Ext.util.Format.trim(this.getRawValue().split(',').pop());
551 <div id="method-Ext.ux.TaskBar.TaskButton-selectByValue"></div>/**
552 * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
553 * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
554 * @param {String} value The data value of the item to select
555 * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
556 * selected item if it is not currently in view (defaults to true)
557 * @return {Boolean} True if the value matched an item in the list, else false
559 selectByValue : function(v, scrollIntoView){
562 var rs = this.store.data.filterBy(this.store.createFilterFn(this.valueField, new RegExp(v.join('|'), "i"))).each(function(r){
563 indexes.push(this.store.indexOf(r));
565 if (indexes.length) {
566 this.view.select(indexes);
571 this.view.clearSelections();
572 this.setRawValue('');
578 initEvents : function(){
579 Ext.form.ComboBox.superclass.initEvents.call(this);
580 this.keyNav = new Ext.KeyNav(this.el, {
582 this.lastKey = Ext.EventObject.UP;
583 this.inKeyMode = true;
585 this.scrollIntoView();
588 "down" : function(e){
589 this.inKeyMode = true;
590 if(!this.isExpanded()){
591 this.lastKey = Ext.EventObject.DOWN;
592 this.onTriggerClick();
595 this.scrollIntoView();
600 "enter" : function(e){
601 var idx = this.highlightIndex;
602 if (this.inKeyMode === true) {
603 if (this.plugins.length && (idx <= -1)) {
604 if (this.plugins[idx + 1]) {
605 this.plugins[idx + 1].onEnter(this);
609 if (this.plugins.length && this.highlightIndex == 0 && this.highlightIndexPrev == -1) {
610 if (this.plugins[idx]) {
611 this.plugins[idx].onEnter(this);
615 var idx = this.getHighlightedIndex() || 0;
616 if (this.highlightIndex != null && idx != null) {
617 this.select(idx, true);
618 //this.delayedCheck = true;
619 //this.unsetDelayCheck.defer(10, this);
625 var v = this.getLastValue();
626 var raw = this.getRawValue();
628 <div id="prop-Ext.ux.TaskBar.TaskButton-var"></div>/** this block should be moved to method getCurrentWord
631 var pos = this.getCaretPosition(raw);
633 if (pos !== false && pos < raw.length) {
634 word = Ext.util.Format.trim(raw.substr(0, pos).split(',').pop());
636 word = Ext.util.Format.trim(raw.split(',').pop());
638 <div id="prop-Ext.ux.TaskBar.TaskButton-var"></div>/*******************************************************/
640 var idx = this.store.find(this.displayField, word);
642 var rec = this.store.getAt(idx);
643 this.select(idx, true);
645 raw = this.getRawValue();
646 this.selectText(raw.length, raw.length);
656 if (this.matches != null && this.matches.getCount() == 1) {
657 var idx = this.store.indexOf(this.matches.first());
658 if (!this.view.isSelected(idx)) {
659 this.select(this.store.indexOf(this.matches.first()), true);
662 else if (this.value.length == 0 && this.getRawValue().length > 0) {
663 this.setRawValue('');
671 doRelay : function(foo, bar, hname){
672 if(hname == 'down' || this.scope.isExpanded()){
673 return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
680 this.queryDelay = Math.max(this.queryDelay || 10,
681 this.mode == 'local' ? 10 : 250);
682 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
684 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
686 if(this.editable !== false){
687 this.el.on("keyup", this.onKeyUp, this);
689 if(this.forceSelection){
690 this.on('blur', this.doForce, this);
694 // private, blur-handler to ensure that rawValue contains only values from selections, in the same order as selected
695 validateSelections : function(field) {
696 var v = this.getValue();
698 for (var i=0,len=v.length;i<len;i++) {
699 var idx = this.store.find(this.valueField, v[i]);
701 text.push(this.store.getAt(idx).data[this.displayField]);
704 this.setRawValue(text.join(', '));
707 scrollIntoView : function() {
708 var el = this.getHighlightedNode();
710 this.innerList.scrollChildIntoView(el);
715 selectNext : function(){
716 this.clearHighlight();
717 if (this.highlightIndex == null) {
718 this.highlightIndex = -1;
720 if (this.highlightIndex <= -1 && this.highlightIndexPrev != -1) {
721 if (this.plugins.length > 0) {
722 var idx = Math.abs(this.highlightIndex)-1;
723 if (this.plugins.length >= Math.abs(this.highlightIndex)) {
724 this.plugins[idx].selectNext(this);
725 this.highlightIndexPrev = this.highlightIndex;
726 this.highlightIndex++;
731 if (this.highlightIndexPrev == -1 && this.highlightIndex == 0) {
732 this.highlightIndex = -1;
734 var ct = this.store.getCount();
736 if (this.highlightIndex == -1 || this.highlightIndex+1 < ct) {
737 if (this.highlightIndex == -1) {
738 this.highlightIndexPrev = 0;
741 this.highlightIndexPrev = this.highlightIndex -1;
743 this.highlight(++this.highlightIndex);
747 this.highlight(ct-1);
753 selectPrev : function(){
754 this.clearHighlight();
755 if (this.highlightIndex <= 0) {
756 var idx = Math.abs(this.highlightIndex);
757 if (this.plugins.length >= idx+1 && this.highlightIndexPrev >= 0) {
758 this.clearHighlight();
759 this.plugins[idx].selectPrev(this);
760 this.highlightIndexPrev = this.highlightIndex;
761 this.highlightIndex--;
762 if (this.highlightIndex == -1) {
763 this.highlightIndexPrev = -1;
768 this.highlightIndex = -1;
769 this.highlightIndexPrev = -1;
775 this.highlightIndexPrev = this.highlightIndex;
776 var ct = this.store.getCount();
778 if (this.highlighIndex == -1) {
779 this.highlightIndex = 0;
781 else if (this.highlightIndex != 0) {
782 this.highlightIndex--;
784 else if (this.highlightIndex == 0) {
787 this.highlight(this.highlightIndex);
791 collapse : function() {
792 if (this.isExpanded()) {
793 this.highlightIndex = null;
794 this.highlightIndexPrev = null;
796 Ext.ux.MultiCombo.superclass.collapse.call(this);
799 highlight : function(index) {
800 this.view.el.select('.'+this.highlightClass).removeClass(this.highlightClass);
801 var node = Ext.fly(this.view.getNode(index));
803 node.addClass(this.highlightClass);
807 getHighlightedIndex : function() {
808 var node = this.view.el.child('.' + this.highlightClass, true);
809 return (node) ? this.store.indexOf(this.view.getRecord(node)) : this.highlightIndex;
811 getHighlightedNode : function() {
812 return this.view.el.child('.'+this.highlightClass, true);
815 clearHighlight : function() {
816 if (typeof(this.view) != 'object') { return false; }
817 var el = this.view.el.select('.'+this.highlightClass);
819 el.removeClass(this.highlightClass);
824 initList : function(){
826 var cls = 'x-combo-list';
828 this.list = new Ext.Layer({
829 shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
832 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
833 this.list.setWidth(lw);
834 this.list.swallowEvent('mousewheel');
835 this.assetHeight = 0;
836 if(this.syncFont !== false){
837 this.list.setStyle('font-size', this.el.getStyle('font-size'));
840 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
841 this.assetHeight += this.header.getHeight();
844 this.innerList = this.list.createChild({cls:cls+'-inner'});
845 this.innerList.on('mouseover', this.onViewOver, this);
846 this.innerList.on('mousemove', this.onViewMove, this);
847 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
850 this.footer = this.list.createChild({cls:cls+'-ft'});
851 this.pageTb = new Ext.PagingToolbar({
853 pageSize: this.pageSize,
856 this.assetHeight += this.footer.getHeight();
860 <div id="cfg-Ext.ux.TaskBar.TaskButton-tpl"></div>/**
861 * @cfg {String/Ext.XTemplate} tpl The template string, or {@link Ext.XTemplate}
862 * instance to use to display each item in the dropdown list. Use
863 * this to create custom UI layouts for items in the list.
865 * If you wish to preserve the default visual look of list items, add the CSS
866 * class name <pre>x-combo-list-item</pre> to the template's container element.
868 * <b>The template must contain one or more substitution parameters using field
869 * names from the Combo's</b> {@link #store Store}. An example of a custom template
870 * would be adding an <pre>ext:qtip</pre> attribute which might display other fields
873 * The dropdown list is displayed in a DataView. See {@link Ext.DataView} for details.
875 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
876 <div id="cfg-Ext.ux.TaskBar.TaskButton-itemSelector"></div>/**
877 * @cfg {String} itemSelector
878 * <b>This setting is required if a custom XTemplate has been specified in {@link #tpl}
879 * which assigns a class other than <pre>'x-combo-list-item'</pre> to dropdown list items</b>.
880 * A simple CSS selector (e.g. div.some-class or span:first-child) that will be
881 * used to determine what nodes the DataView which handles the dropdown display will
886 <div id="prop-Ext.ux.TaskBar.TaskButton-view"></div>/**
887 * The {@link Ext.DataView DataView} used to display the ComboBox's options.
890 this.view = new Ext.DataView({
891 applyTo: this.innerList,
895 overClass: this.overClass,
896 selectedClass: this.selectedClass,
897 itemSelector: this.itemSelector || '.' + cls + '-item'
899 this.view.on('click', this.onViewClick, this);
900 this.fireEvent('initview', this, this.view);
901 this.bindStore(this.store, true);
904 this.resizer = new Ext.Resizable(this.list, {
905 pinned:true, handles:'se'
907 this.resizer.on('resize', function(r, w, h){
908 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
910 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
911 this.restrictHeight();
913 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
920 Ext.reg('multicombo', Ext.ux.MultiCombo);</pre>
\r