MultiSelect.js 3.6 KB

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