1 define("dijit/form/MultiSelect", [
2 "dojo/_base/array", // array.indexOf, array.map
3 "dojo/_base/declare", // declare
4 "dojo/dom-geometry", // domGeometry.setMarginBox
7 ], function(array, declare, domGeometry, query, _FormValueWidget){
10 var _FormValueWidget = dijit.form._FormValueWidget;
14 // dijit/form/MultiSelect
16 // Widget version of a <select multiple=true> element,
17 // for selecting multiple options.
19 return declare("dijit.form.MultiSelect", _FormValueWidget, {
21 // Widget version of a <select multiple=true> element,
22 // for selecting multiple options.
25 // Number of elements to display on a page
26 // NOTE: may be removed in version 2.0, since elements may have variable height;
27 // set the size via style="..." or CSS class names instead.
30 templateString: "<select multiple='true' ${!nameAttrSetting} data-dojo-attach-point='containerNode,focusNode' data-dojo-attach-event='onchange: _onChange'></select>",
32 addSelected: function(/*dijit.form.MultiSelect*/ select){
34 // Move the selected nodes of a passed Select widget
35 // instance to this Select widget.
38 // | // move all the selected values from "bar" to "foo"
39 // | dijit.byId("foo").addSelected(dijit.byId("bar"));
41 select.getSelected().forEach(function(n){
42 this.containerNode.appendChild(n);
43 // scroll to bottom to see item
44 // cannot use scrollIntoView since <option> tags don't support all attributes
45 // does not work on IE due to a bug where <select> always shows scrollTop = 0
46 this.domNode.scrollTop = this.domNode.offsetHeight; // overshoot will be ignored
47 // scrolling the source select is trickier esp. on safari who forgets to change the scrollbar size
48 var oldscroll = select.domNode.scrollTop;
49 select.domNode.scrollTop = 0;
50 select.domNode.scrollTop = oldscroll;
52 this._set('value', this.get('value'));
55 getSelected: function(){
57 // Access the NodeList of the selected options directly
58 return query("option",this.containerNode).filter(function(n){
59 return n.selected; // Boolean
63 _getValueAttr: function(){
65 // Hook so get('value') works.
67 // Returns an array of the selected options' values.
69 // Don't call getSelect.map() because it doesn't return a real array,
70 // and that messes up dojo.toJson() calls like in the Form.html test
71 return array.map(this.getSelected(), function(n){
76 multiple: true, // for Form
78 _setValueAttr: function(/*Array*/ values, /*Boolean?*/ priorityChange){
80 // Hook so set('value', values) works.
82 // Set the value(s) of this Select based on passed values
83 query("option",this.containerNode).forEach(function(n){
84 n.selected = (array.indexOf(values,n.value) != -1);
86 this.inherited(arguments);
89 invertSelection: function(/*Boolean?*/ onChange){
91 // Invert the selection
93 // If false, onChange is not fired.
95 query("option",this.containerNode).forEach(function(n){
96 if(!n.selected){ val.push(n.value); }
98 this._setValueAttr(val, !(onChange === false || onChange == null));
101 _onChange: function(/*Event*/){
102 this._handleOnChange(this.get('value'), true);
105 // for layout widgets:
106 resize: function(/*Object*/ size){
108 domGeometry.setMarginBox(this.domNode, size);
112 postCreate: function(){
113 this._set('value', this.get('value'));
114 this.inherited(arguments);