X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/c930e9176a5a85509c5b0230e2bff5c22a591432..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/examples/ux/MultiSelect.js?ds=sidebyside diff --git a/examples/ux/MultiSelect.js b/examples/ux/MultiSelect.js deleted file mode 100644 index 4ded37bf..00000000 --- a/examples/ux/MultiSelect.js +++ /dev/null @@ -1,596 +0,0 @@ -/*! - * Ext JS Library 3.0.0 - * Copyright(c) 2006-2009 Ext JS, LLC - * licensing@extjs.com - * http://www.extjs.com/license - */ -Ext.ns('Ext.ux.form'); - -/** - * @class Ext.ux.form.MultiSelect - * @extends Ext.form.Field - * A control that allows selection and form submission of multiple list items. - * - * @history - * 2008-06-19 bpm Original code contributed by Toby Stuart (with contributions from Robert Williams) - * 2008-06-19 bpm Docs and demo code clean up - * - * @constructor - * Create a new MultiSelect - * @param {Object} config Configuration options - * @xtype multiselect - */ -Ext.ux.form.MultiSelect = Ext.extend(Ext.form.Field, { - /** - * @cfg {String} legend Wraps the object with a fieldset and specified legend. - */ - /** - * @cfg {Ext.ListView} view The {@link Ext.ListView} used to render the multiselect list. - */ - /** - * @cfg {String/Array} dragGroup The ddgroup name(s) for the MultiSelect DragZone (defaults to undefined). - */ - /** - * @cfg {String/Array} dropGroup The ddgroup name(s) for the MultiSelect DropZone (defaults to undefined). - */ - /** - * @cfg {Boolean} ddReorder Whether the items in the MultiSelect list are drag/drop reorderable (defaults to false). - */ - ddReorder:false, - /** - * @cfg {Object/Array} tbar The top toolbar of the control. This can be a {@link Ext.Toolbar} object, a - * toolbar config, or an array of buttons/button configs to be added to the toolbar. - */ - /** - * @cfg {String} appendOnly True if the list should only allow append drops when drag/drop is enabled - * (use for lists which are sorted, defaults to false). - */ - appendOnly:false, - /** - * @cfg {Number} width Width in pixels of the control (defaults to 100). - */ - width:100, - /** - * @cfg {Number} height Height in pixels of the control (defaults to 100). - */ - height:100, - /** - * @cfg {String/Number} displayField Name/Index of the desired display field in the dataset (defaults to 0). - */ - displayField:0, - /** - * @cfg {String/Number} valueField Name/Index of the desired value field in the dataset (defaults to 1). - */ - valueField:1, - /** - * @cfg {Boolean} allowBlank False to require at least one item in the list to be selected, true to allow no - * selection (defaults to true). - */ - allowBlank:true, - /** - * @cfg {Number} minSelections Minimum number of selections allowed (defaults to 0). - */ - minSelections:0, - /** - * @cfg {Number} maxSelections Maximum number of selections allowed (defaults to Number.MAX_VALUE). - */ - maxSelections:Number.MAX_VALUE, - /** - * @cfg {String} blankText Default text displayed when the control contains no items (defaults to the same value as - * {@link Ext.form.TextField#blankText}. - */ - blankText:Ext.form.TextField.prototype.blankText, - /** - * @cfg {String} minSelectionsText Validation message displayed when {@link #minSelections} is not met (defaults to 'Minimum {0} - * item(s) required'). The {0} token will be replaced by the value of {@link #minSelections}. - */ - minSelectionsText:'Minimum {0} item(s) required', - /** - * @cfg {String} maxSelectionsText Validation message displayed when {@link #maxSelections} is not met (defaults to 'Maximum {0} - * item(s) allowed'). The {0} token will be replaced by the value of {@link #maxSelections}. - */ - maxSelectionsText:'Maximum {0} item(s) allowed', - /** - * @cfg {String} delimiter The string used to delimit between items when set or returned as a string of values - * (defaults to ','). - */ - delimiter:',', - /** - * @cfg {Ext.data.Store/Array} store The data source to which this MultiSelect is bound (defaults to undefined). - * Acceptable values for this property are: - *
- */ - - // private - defaultAutoCreate : {tag: "div"}, - - // private - initComponent: function(){ - Ext.ux.form.MultiSelect.superclass.initComponent.call(this); - - if(Ext.isArray(this.store)){ - if (Ext.isArray(this.store[0])){ - this.store = new Ext.data.ArrayStore({ - fields: ['value','text'], - data: this.store - }); - this.valueField = 'value'; - }else{ - this.store = new Ext.data.ArrayStore({ - fields: ['text'], - data: this.store, - expandData: true - }); - this.valueField = 'text'; - } - this.displayField = 'text'; - } else { - this.store = Ext.StoreMgr.lookup(this.store); - } - - this.addEvents({ - 'dblclick' : true, - 'click' : true, - 'change' : true, - 'drop' : true - }); - }, - - // private - onRender: function(ct, position){ - Ext.ux.form.MultiSelect.superclass.onRender.call(this, ct, position); - - var fs = this.fs = new Ext.form.FieldSet({ - renderTo: this.el, - title: this.legend, - height: this.height, - width: this.width, - style: "padding:0;", - tbar: this.tbar, - bodyStyle: 'overflow: auto;' - }); - - this.view = new Ext.ListView({ - multiSelect: true, - store: this.store, - columns: [{ header: 'Value', width: 1, dataIndex: this.displayField }], - hideHeaders: true - }); - - fs.add(this.view); - - this.view.on('click', this.onViewClick, this); - this.view.on('beforeclick', this.onViewBeforeClick, this); - this.view.on('dblclick', this.onViewDblClick, this); - - this.hiddenName = this.name || Ext.id(); - var hiddenTag = { tag: "input", type: "hidden", value: "", name: this.hiddenName }; - this.hiddenField = this.el.createChild(hiddenTag); - this.hiddenField.dom.disabled = this.hiddenName != this.name; - fs.doLayout(); - }, - - // private - afterRender: function(){ - Ext.ux.form.MultiSelect.superclass.afterRender.call(this); - - if (this.ddReorder && !this.dragGroup && !this.dropGroup){ - this.dragGroup = this.dropGroup = 'MultiselectDD-' + Ext.id(); - } - - if (this.draggable || this.dragGroup){ - this.dragZone = new Ext.ux.form.MultiSelect.DragZone(this, { - ddGroup: this.dragGroup - }); - } - if (this.droppable || this.dropGroup){ - this.dropZone = new Ext.ux.form.MultiSelect.DropZone(this, { - ddGroup: this.dropGroup - }); - } - }, - - // private - onViewClick: function(vw, index, node, e) { - this.fireEvent('change', this, this.getValue(), this.hiddenField.dom.value); - this.hiddenField.dom.value = this.getValue(); - this.fireEvent('click', this, e); - this.validate(); - }, - - // private - onViewBeforeClick: function(vw, index, node, e) { - if (this.disabled) {return false;} - }, - - // private - onViewDblClick : function(vw, index, node, e) { - return this.fireEvent('dblclick', vw, index, node, e); - }, - - /** - * Returns an array of data values for the selected items in the list. The values will be separated - * by {@link #delimiter}. - * @return {Array} value An array of string data values - */ - getValue: function(valueField){ - var returnArray = []; - var selectionsArray = this.view.getSelectedIndexes(); - if (selectionsArray.length == 0) {return '';} - for (var i=0; i this.maxSelections) { - this.markInvalid(String.format(this.maxSelectionsText, this.maxSelections)); - return false; - } - return true; - }, - - // inherit docs - disable: function(){ - this.disabled = true; - this.hiddenField.dom.disabled = true; - this.fs.disable(); - }, - - // inherit docs - enable: function(){ - this.disabled = false; - this.hiddenField.dom.disabled = false; - this.fs.enable(); - }, - - // inherit docs - destroy: function(){ - Ext.destroy(this.fs, this.dragZone, this.dropZone); - Ext.ux.form.MultiSelect.superclass.destroy.call(this); - } -}); - - -Ext.reg('multiselect', Ext.ux.form.MultiSelect); - -//backwards compat -Ext.ux.Multiselect = Ext.ux.form.MultiSelect; - - -Ext.ux.form.MultiSelect.DragZone = function(ms, config){ - this.ms = ms; - this.view = ms.view; - var ddGroup = config.ddGroup || 'MultiselectDD'; - var dd; - if (Ext.isArray(ddGroup)){ - dd = ddGroup.shift(); - } else { - dd = ddGroup; - ddGroup = null; - } - Ext.ux.form.MultiSelect.DragZone.superclass.constructor.call(this, this.ms.fs.body, { containerScroll: true, ddGroup: dd }); - this.setDraggable(ddGroup); -}; - -Ext.extend(Ext.ux.form.MultiSelect.DragZone, Ext.dd.DragZone, { - onInitDrag : function(x, y){ - var el = Ext.get(this.dragData.ddel.cloneNode(true)); - this.proxy.update(el.dom); - el.setWidth(el.child('em').getWidth()); - this.onStartDrag(x, y); - return true; - }, - - // private - collectSelection: function(data) { - data.repairXY = Ext.fly(this.view.getSelectedNodes()[0]).getXY(); - var i = 0; - this.view.store.each(function(rec){ - if (this.view.isSelected(i)) { - var n = this.view.getNode(i); - var dragNode = n.cloneNode(true); - dragNode.id = Ext.id(); - data.ddel.appendChild(dragNode); - data.records.push(this.view.store.getAt(i)); - data.viewNodes.push(n); - } - i++; - }, this); - }, - - // override - onEndDrag: function(data, e) { - var d = Ext.get(this.dragData.ddel); - if (d && d.hasClass("multi-proxy")) { - d.remove(); - } - }, - - // override - getDragData: function(e){ - var target = this.view.findItemFromChild(e.getTarget()); - if(target) { - if (!this.view.isSelected(target) && !e.ctrlKey && !e.shiftKey) { - this.view.select(target); - this.ms.setValue(this.ms.getValue()); - } - if (this.view.getSelectionCount() == 0 || e.ctrlKey || e.shiftKey) return false; - var dragData = { - sourceView: this.view, - viewNodes: [], - records: [] - }; - if (this.view.getSelectionCount() == 1) { - var i = this.view.getSelectedIndexes()[0]; - var n = this.view.getNode(i); - dragData.viewNodes.push(dragData.ddel = n); - dragData.records.push(this.view.store.getAt(i)); - dragData.repairXY = Ext.fly(n).getXY(); - } else { - dragData.ddel = document.createElement('div'); - dragData.ddel.className = 'multi-proxy'; - this.collectSelection(dragData); - } - return dragData; - } - return false; - }, - - // override the default repairXY. - getRepairXY : function(e){ - return this.dragData.repairXY; - }, - - // private - setDraggable: function(ddGroup){ - if (!ddGroup) return; - if (Ext.isArray(ddGroup)) { - Ext.each(ddGroup, this.setDraggable, this); - return; - } - this.addToGroup(ddGroup); - } -}); - -Ext.ux.form.MultiSelect.DropZone = function(ms, config){ - this.ms = ms; - this.view = ms.view; - var ddGroup = config.ddGroup || 'MultiselectDD'; - var dd; - if (Ext.isArray(ddGroup)){ - dd = ddGroup.shift(); - } else { - dd = ddGroup; - ddGroup = null; - } - Ext.ux.form.MultiSelect.DropZone.superclass.constructor.call(this, this.ms.fs.body, { containerScroll: true, ddGroup: dd }); - this.setDroppable(ddGroup); -}; - -Ext.extend(Ext.ux.form.MultiSelect.DropZone, Ext.dd.DropZone, { - /** - * Part of the Ext.dd.DropZone interface. If no target node is found, the - * whole Element becomes the target, and this causes the drop gesture to append. - */ - getTargetFromEvent : function(e) { - var target = e.getTarget(); - return target; - }, - - // private - getDropPoint : function(e, n, dd){ - if (n == this.ms.fs.body.dom) { return "below"; } - var t = Ext.lib.Dom.getY(n), b = t + n.offsetHeight; - var c = t + (b - t) / 2; - var y = Ext.lib.Event.getPageY(e); - if(y <= c) { - return "above"; - }else{ - return "below"; - } - }, - - // private - isValidDropPoint: function(pt, n, data) { - if (!data.viewNodes || (data.viewNodes.length != 1)) { - return true; - } - var d = data.viewNodes[0]; - if (d == n) { - return false; - } - if ((pt == "below") && (n.nextSibling == d)) { - return false; - } - if ((pt == "above") && (n.previousSibling == d)) { - return false; - } - return true; - }, - - // override - onNodeEnter : function(n, dd, e, data){ - return false; - }, - - // override - onNodeOver : function(n, dd, e, data){ - var dragElClass = this.dropNotAllowed; - var pt = this.getDropPoint(e, n, dd); - if (this.isValidDropPoint(pt, n, data)) { - if (this.ms.appendOnly) { - return "x-tree-drop-ok-below"; - } - - // set the insert point style on the target node - if (pt) { - var targetElClass; - if (pt == "above"){ - dragElClass = n.previousSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-above"; - targetElClass = "x-view-drag-insert-above"; - } else { - dragElClass = n.nextSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-below"; - targetElClass = "x-view-drag-insert-below"; - } - if (this.lastInsertClass != targetElClass){ - Ext.fly(n).replaceClass(this.lastInsertClass, targetElClass); - this.lastInsertClass = targetElClass; - } - } - } - return dragElClass; - }, - - // private - onNodeOut : function(n, dd, e, data){ - this.removeDropIndicators(n); - }, - - // private - onNodeDrop : function(n, dd, e, data){ - if (this.ms.fireEvent("drop", this, n, dd, e, data) === false) { - return false; - } - var pt = this.getDropPoint(e, n, dd); - if (n != this.ms.fs.body.dom) - n = this.view.findItemFromChild(n); - var insertAt = (this.ms.appendOnly || (n == this.ms.fs.body.dom)) ? this.view.store.getCount() : this.view.indexOf(n); - if (pt == "below") { - insertAt++; - } - - var dir = false; - - // Validate if dragging within the same MultiSelect - if (data.sourceView == this.view) { - // If the first element to be inserted below is the target node, remove it - if (pt == "below") { - if (data.viewNodes[0] == n) { - data.viewNodes.shift(); - } - } else { // If the last element to be inserted above is the target node, remove it - if (data.viewNodes[data.viewNodes.length - 1] == n) { - data.viewNodes.pop(); - } - } - - // Nothing to drop... - if (!data.viewNodes.length) { - return false; - } - - // If we are moving DOWN, then because a store.remove() takes place first, - // the insertAt must be decremented. - if (insertAt > this.view.store.indexOf(data.records[0])) { - dir = 'down'; - insertAt--; - } - } - - for (var i = 0; i < data.records.length; i++) { - var r = data.records[i]; - if (data.sourceView) { - data.sourceView.store.remove(r); - } - this.view.store.insert(dir == 'down' ? insertAt : insertAt++, r); - var si = this.view.store.sortInfo; - if(si){ - this.view.store.sort(si.field, si.direction); - } - } - return true; - }, - - // private - removeDropIndicators : function(n){ - if(n){ - Ext.fly(n).removeClass([ - "x-view-drag-insert-above", - "x-view-drag-insert-left", - "x-view-drag-insert-right", - "x-view-drag-insert-below"]); - this.lastInsertClass = "_noclass"; - } - }, - - // private - setDroppable: function(ddGroup){ - if (!ddGroup) return; - if (Ext.isArray(ddGroup)) { - Ext.each(ddGroup, this.setDroppable, this); - return; - } - this.addToGroup(ddGroup); - } -});