| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 | 
							- <!DOCTYPE html>
 
- <html>
 
- <head>
 
-   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
-   <title>The source code</title>
 
-   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
 
-   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
 
-   <style type="text/css">
 
-     .highlight { display: block; background-color: #ddd; }
 
-   </style>
 
-   <script type="text/javascript">
 
-     function highlight() {
 
-       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
 
-     }
 
-   </script>
 
- </head>
 
- <body onload="prettyPrint(); highlight();">
 
-   <pre class="prettyprint lang-js"><span id='Ext-ux-form-MultiSelect'>/**
 
- </span> * A control that allows selection of multiple items in a list
 
-  */
 
- Ext.define('Ext.ux.form.MultiSelect', {
 
-     
 
-     extend: 'Ext.form.FieldContainer',
 
-     
 
-     mixins: {
 
-         bindable: 'Ext.util.Bindable',
 
-         field: 'Ext.form.field.Field'    
 
-     },
 
-     
 
-     alternateClassName: 'Ext.ux.Multiselect',
 
-     alias: ['widget.multiselectfield', 'widget.multiselect'],
 
-     
 
-     requires: ['Ext.panel.Panel', 'Ext.view.BoundList', 'Ext.layout.container.Fit'],
 
-     
 
-     uses: ['Ext.view.DragZone', 'Ext.view.DropZone'],
 
-     
 
-     layout: 'fit',
 
-     
 
- <span id='Ext-ux-form-MultiSelect-cfg-dragGroup'>    /**
 
- </span>     * @cfg {String} [dragGroup=""] The ddgroup name for the MultiSelect DragZone.
 
-      */
 
- <span id='Ext-ux-form-MultiSelect-cfg-dropGroup'>    /**
 
- </span>     * @cfg {String} [dropGroup=""] The ddgroup name for the MultiSelect DropZone.
 
-      */
 
-     
 
- <span id='Ext-ux-form-MultiSelect-cfg-title'>    /**
 
- </span>     * @cfg {String} [title=""] A title for the underlying panel.
 
-      */
 
-     
 
- <span id='Ext-ux-form-MultiSelect-cfg-ddReorder'>    /**
 
- </span>     * @cfg {Boolean} [ddReorder=false] Whether the items in the MultiSelect list are drag/drop reorderable.
 
-      */
 
-     ddReorder: false,
 
- <span id='Ext-ux-form-MultiSelect-cfg-tbar'>    /**
 
- </span>     * @cfg {Object/Array} tbar An optional toolbar to be inserted at the top of the control's selection list.
 
-      * This can be a {@link Ext.toolbar.Toolbar} object, a toolbar config, or an array of buttons/button configs
 
-      * to be added to the toolbar. See {@link Ext.panel.Panel#tbar}.
 
-      */
 
- <span id='Ext-ux-form-MultiSelect-cfg-appendOnly'>    /**
 
- </span>     * @cfg {String} [appendOnly=false] True if the list should only allow append drops when drag/drop is enabled.
 
-      * This is useful for lists which are sorted.
 
-      */
 
-     appendOnly: false,
 
- <span id='Ext-ux-form-MultiSelect-cfg-displayField'>    /**
 
- </span>     * @cfg {String} [displayField="text"] Name of the desired display field in the dataset.
 
-      */
 
-     displayField: 'text',
 
- <span id='Ext-ux-form-MultiSelect-cfg-valueField'>    /**
 
- </span>     * @cfg {String} [valueField="text"] Name of the desired value field in the dataset.
 
-      */
 
- <span id='Ext-ux-form-MultiSelect-cfg-allowBlank'>    /**
 
- </span>     * @cfg {Boolean} [allowBlank=true] False to require at least one item in the list to be selected, true to allow no
 
-      * selection.
 
-      */
 
-     allowBlank: true,
 
- <span id='Ext-ux-form-MultiSelect-cfg-minSelections'>    /**
 
- </span>     * @cfg {Number} [minSelections=0] Minimum number of selections allowed.
 
-      */
 
-     minSelections: 0,
 
- <span id='Ext-ux-form-MultiSelect-cfg-maxSelections'>    /**
 
- </span>     * @cfg {Number} [maxSelections=Number.MAX_VALUE] Maximum number of selections allowed.
 
-      */
 
-     maxSelections: Number.MAX_VALUE,
 
- <span id='Ext-ux-form-MultiSelect-cfg-blankText'>    /**
 
- </span>     * @cfg {String} [blankText="This field is required"] Default text displayed when the control contains no items.
 
-      */
 
-     blankText: 'This field is required',
 
- <span id='Ext-ux-form-MultiSelect-cfg-minSelectionsText'>    /**
 
- </span>     * @cfg {String} [minSelectionsText="Minimum {0}item(s) required"] 
 
-      * Validation message displayed when {@link #minSelections} is not met. 
 
-      * The {0} token will be replaced by the value of {@link #minSelections}.
 
-      */
 
-     minSelectionsText: 'Minimum {0} item(s) required',
 
-     
 
- <span id='Ext-ux-form-MultiSelect-cfg-maxSelectionsText'>    /**
 
- </span>     * @cfg {String} [maxSelectionsText="Maximum {0}item(s) allowed"] 
 
-      * Validation message displayed when {@link #maxSelections} is not met
 
-      * The {0} token will be replaced by the value of {@link #maxSelections}.
 
-      */
 
-     maxSelectionsText: 'Minimum {0} item(s) required',
 
- <span id='Ext-ux-form-MultiSelect-cfg-delimiter'>    /**
 
- </span>     * @cfg {String} [delimiter=","] The string used to delimit the selected values when {@link #getSubmitValue submitting}
 
-      * the field as part of a form. If you wish to have the selected values submitted as separate
 
-      * parameters rather than a single delimited parameter, set this to <tt>null</tt>.
 
-      */
 
-     delimiter: ',',
 
- <span id='Ext-ux-form-MultiSelect-cfg-store'>    /**
 
- </span>     * @cfg {Ext.data.Store/Array} store The data source to which this MultiSelect is bound (defaults to <tt>undefined</tt>).
 
-      * Acceptable values for this property are:
 
-      * <div class="mdetail-params"><ul>
 
-      * <li><b>any {@link Ext.data.Store Store} subclass</b></li>
 
-      * <li><b>an Array</b> : Arrays will be converted to a {@link Ext.data.ArrayStore} internally.
 
-      * <div class="mdetail-params"><ul>
 
-      * <li><b>1-dimensional array</b> : (e.g., <tt>['Foo','Bar']</tt>)<div class="sub-desc">
 
-      * A 1-dimensional array will automatically be expanded (each array item will be the combo
 
-      * {@link #valueField value} and {@link #displayField text})</div></li>
 
-      * <li><b>2-dimensional array</b> : (e.g., <tt>[['f','Foo'],['b','Bar']]</tt>)<div class="sub-desc">
 
-      * For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo
 
-      * {@link #valueField value}, while the value at index 1 is assumed to be the combo {@link #displayField text}.
 
-      * </div></li></ul></div></li></ul></div>
 
-      */
 
-     
 
-     ignoreSelectChange: 0,
 
- <span id='Ext-ux-form-MultiSelect-cfg-listConfig'>    /**
 
- </span>     * @cfg {Object} listConfig
 
-      * An optional set of configuration properties that will be passed to the {@link Ext.view.BoundList}'s constructor.
 
-      * Any configuration that is valid for BoundList can be included.
 
-      */
 
-     initComponent: function(){
 
-         var me = this;
 
-         me.bindStore(me.store, true);
 
-         if (me.store.autoCreated) {
 
-             me.valueField = me.displayField = 'field1';
 
-             if (!me.store.expanded) {
 
-                 me.displayField = 'field2';
 
-             }
 
-         }
 
-         if (!Ext.isDefined(me.valueField)) {
 
-             me.valueField = me.displayField;
 
-         }
 
-         me.items = me.setupItems();
 
-         
 
-         
 
-         me.callParent();
 
-         me.initField();
 
-         me.addEvents('drop');    
 
-     },
 
-     
 
-     setupItems: function() {
 
-         var me = this;
 
-         
 
-         me.boundList = Ext.create('Ext.view.BoundList', Ext.apply({
 
-             deferInitialRefresh: false,
 
-             border: false,
 
-             multiSelect: true,
 
-             store: me.store,
 
-             displayField: me.displayField,
 
-             disabled: me.disabled
 
-         }, me.listConfig));
 
-         
 
-         me.boundList.getSelectionModel().on('selectionchange', me.onSelectChange, me);
 
-         return {
 
-             border: true,
 
-             layout: 'fit',
 
-             title: me.title,
 
-             tbar: me.tbar,
 
-             items: me.boundList
 
-         };
 
-     },
 
-     
 
-     onSelectChange: function(selModel, selections){
 
-         if (!this.ignoreSelectChange) {
 
-             this.setValue(selections);
 
-         }    
 
-     },
 
-     
 
-     getSelected: function(){
 
-         return this.boundList.getSelectionModel().getSelection();
 
-     },
 
-     
 
-     // compare array values
 
-     isEqual: function(v1, v2) {
 
-         var fromArray = Ext.Array.from,
 
-             i = 0, 
 
-             len;
 
-         v1 = fromArray(v1);
 
-         v2 = fromArray(v2);
 
-         len = v1.length;
 
-         if (len !== v2.length) {
 
-             return false;
 
-         }
 
-         for(; i < len; i++) {
 
-             if (v2[i] !== v1[i]) {
 
-                 return false;
 
-             }
 
-         }
 
-         return true;
 
-     },
 
-     
 
-     afterRender: function(){
 
-         var me = this;
 
-         
 
-         me.callParent();
 
-         if (me.selectOnRender) {
 
-             ++me.ignoreSelectChange;
 
-             me.boundList.getSelectionModel().select(me.getRecordsForValue(me.value));
 
-             --me.ignoreSelectChange;
 
-             delete me.toSelect;
 
-         }    
 
-         
 
-         if (me.ddReorder && !me.dragGroup && !me.dropGroup){
 
-             me.dragGroup = me.dropGroup = 'MultiselectDD-' + Ext.id();
 
-         }
 
-         if (me.draggable || me.dragGroup){
 
-             me.dragZone = Ext.create('Ext.view.DragZone', {
 
-                 view: me.boundList,
 
-                 ddGroup: me.dragGroup,
 
-                 dragText: '{0} Item{1}'
 
-             });
 
-         }
 
-         if (me.droppable || me.dropGroup){
 
-             me.dropZone = Ext.create('Ext.view.DropZone', {
 
-                 view: me.boundList,
 
-                 ddGroup: me.dropGroup,
 
-                 handleNodeDrop: function(data, dropRecord, position) {
 
-                     var view = this.view,
 
-                         store = view.getStore(),
 
-                         records = data.records,
 
-                         index;
 
-                     // remove the Models from the source Store
 
-                     data.view.store.remove(records);
 
-                     index = store.indexOf(dropRecord);
 
-                     if (position === 'after') {
 
-                         index++;
 
-                     }
 
-                     store.insert(index, records);
 
-                     view.getSelectionModel().select(records);
 
-                     me.fireEvent('drop', me, records);
 
-                 }
 
-             });
 
-         }
 
-     },
 
-     
 
-     isValid : function() {
 
-         var me = this,
 
-             disabled = me.disabled,
 
-             validate = me.forceValidation || !disabled;
 
-             
 
-         
 
-         return validate ? me.validateValue(me.value) : disabled;
 
-     },
 
-     
 
-     validateValue: function(value) {
 
-         var me = this,
 
-             errors = me.getErrors(value),
 
-             isValid = Ext.isEmpty(errors);
 
-             
 
-         if (!me.preventMark) {
 
-             if (isValid) {
 
-                 me.clearInvalid();
 
-             } else {
 
-                 me.markInvalid(errors);
 
-             }
 
-         }
 
-         return isValid;
 
-     },
 
-     
 
-     markInvalid : function(errors) {
 
-         // Save the message and fire the 'invalid' event
 
-         var me = this,
 
-             oldMsg = me.getActiveError();
 
-         me.setActiveErrors(Ext.Array.from(errors));
 
-         if (oldMsg !== me.getActiveError()) {
 
-             me.updateLayout();
 
-         }
 
-     },
 
- <span id='Ext-ux-form-MultiSelect-method-clearInvalid'>    /**
 
- </span>     * Clear any invalid styles/messages for this field.
 
-      *
 
-      * **Note**: this method does not cause the Field's {@link #validate} or {@link #isValid} methods to return `true`
 
-      * if the value does not _pass_ validation. So simply clearing a field's errors will not necessarily allow
 
-      * submission of forms submitted with the {@link Ext.form.action.Submit#clientValidation} option set.
 
-      */
 
-     clearInvalid : function() {
 
-         // Clear the message and fire the 'valid' event
 
-         var me = this,
 
-             hadError = me.hasActiveError();
 
-         me.unsetActiveError();
 
-         if (hadError) {
 
-             me.updateLayout();
 
-         }
 
-     },
 
-     
 
-     getSubmitData: function() {
 
-         var me = this,
 
-             data = null,
 
-             val;
 
-         if (!me.disabled && me.submitValue && !me.isFileUpload()) {
 
-             val = me.getSubmitValue();
 
-             if (val !== null) {
 
-                 data = {};
 
-                 data[me.getName()] = val;
 
-             }
 
-         }
 
-         return data;
 
-     },
 
- <span id='Ext-ux-form-MultiSelect-method-getSubmitValue'>    /**
 
- </span>     * Returns the value that would be included in a standard form submit for this field.
 
-      *
 
-      * @return {String} The value to be submitted, or null.
 
-      */
 
-     getSubmitValue: function() {
 
-         var me = this,
 
-             delimiter = me.delimiter,
 
-             val = me.getValue();
 
-             
 
-         return Ext.isString(delimiter) ? val.join(delimiter) : val;
 
-     },
 
-     
 
-     getValue: function(){
 
-         return this.value;
 
-     },
 
-     
 
-     getRecordsForValue: function(value){
 
-         var me = this,
 
-             records = [],
 
-             all = me.store.getRange(),
 
-             valueField = me.valueField,
 
-             i = 0,
 
-             allLen = all.length,
 
-             rec,
 
-             j,
 
-             valueLen;
 
-             
 
-         for (valueLen = value.length; i < valueLen; ++i) {
 
-             for (j = 0; j < allLen; ++j) {
 
-                 rec = all[j];   
 
-                 if (rec.get(valueField) == value[i]) {
 
-                     records.push(rec);
 
-                 }
 
-             }    
 
-         }
 
-             
 
-         return records;
 
-     },
 
-     
 
-     setupValue: function(value){
 
-         var delimiter = this.delimiter,
 
-             valueField = this.valueField,
 
-             i = 0,
 
-             out,
 
-             len,
 
-             item;
 
-             
 
-         if (Ext.isDefined(value)) {
 
-             if (delimiter && Ext.isString(value)) {
 
-                 value = value.split(delimiter);
 
-             } else if (!Ext.isArray(value)) {
 
-                 value = [value];
 
-             }
 
-         
 
-             for (len = value.length; i < len; ++i) {
 
-                 item = value[i];
 
-                 if (item && item.isModel) {
 
-                     value[i] = item.get(valueField);
 
-                 }
 
-             }
 
-             out = Ext.Array.unique(value);
 
-         } else {
 
-             out = [];
 
-         }
 
-         return out;
 
-     },
 
-     
 
-     setValue: function(value){
 
-         var me = this,
 
-             selModel = me.boundList.getSelectionModel();
 
-         // Store not loaded yet - we cannot set the value
 
-         if (!me.store.getCount()) {
 
-             me.store.on({
 
-                 load: Ext.Function.bind(me.setValue, me, [value]),
 
-                 single: true
 
-             });
 
-             return;
 
-         }
 
-         value = me.setupValue(value);
 
-         me.mixins.field.setValue.call(me, value);
 
-         
 
-         if (me.rendered) {
 
-             ++me.ignoreSelectChange;
 
-             selModel.deselectAll();
 
-             selModel.select(me.getRecordsForValue(value));
 
-             --me.ignoreSelectChange;
 
-         } else {
 
-             me.selectOnRender = true;
 
-         }
 
-     },
 
-     
 
-     clearValue: function(){
 
-         this.setValue([]);    
 
-     },
 
-     
 
-     onEnable: function(){
 
-         var list = this.boundList;
 
-         this.callParent();
 
-         if (list) {
 
-             list.enable();
 
-         }
 
-     },
 
-     
 
-     onDisable: function(){
 
-         var list = this.boundList;
 
-         this.callParent();
 
-         if (list) {
 
-             list.disable();
 
-         }
 
-     },
 
-     
 
-     getErrors : function(value) {
 
-         var me = this,
 
-             format = Ext.String.format,
 
-             errors = [],
 
-             numSelected;
 
-         value = Ext.Array.from(value || me.getValue());
 
-         numSelected = value.length;
 
-         if (!me.allowBlank && numSelected < 1) {
 
-             errors.push(me.blankText);
 
-         }
 
-         if (numSelected < me.minSelections) {
 
-             errors.push(format(me.minSelectionsText, me.minSelections));
 
-         }
 
-         if (numSelected > me.maxSelections) {
 
-             errors.push(format(me.maxSelectionsText, me.maxSelections));
 
-         }
 
-         return errors;
 
-     },
 
-     
 
-     onDestroy: function(){
 
-         var me = this;
 
-         
 
-         me.bindStore(null);
 
-         Ext.destroy(me.dragZone, me.dropZone);
 
-         me.callParent();
 
-     },
 
-     
 
-     onBindStore: function(store){
 
-         var boundList = this.boundList;
 
-         
 
-         if (boundList) {
 
-             boundList.bindStore(store);
 
-         }
 
-     }
 
-     
 
- });
 
- </pre>
 
- </body>
 
- </html>
 
 
  |