summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/form/CheckedMultiSelect.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/form/CheckedMultiSelect.js')
-rw-r--r--js/dojo/dojox/form/CheckedMultiSelect.js557
1 files changed, 557 insertions, 0 deletions
diff --git a/js/dojo/dojox/form/CheckedMultiSelect.js b/js/dojo/dojox/form/CheckedMultiSelect.js
new file mode 100644
index 0000000..1462ff3
--- /dev/null
+++ b/js/dojo/dojox/form/CheckedMultiSelect.js
@@ -0,0 +1,557 @@
+//>>built
+require({cache:{
+'url:dojox/form/resources/_CheckedMultiSelectMenuItem.html':"<tr class=\"dijitReset dijitMenuItem\" dojoAttachPoint=\"focusNode\" role=\"menuitemcheckbox\" tabIndex=\"-1\"\n\tdojoAttachEvent=\"onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick\"\n\t><td class=\"dijitReset dijitMenuItemIconCell\" role=\"presentation\"\n\t\t><div src=\"${_blankGif}\" alt=\"\" class=\"dijitMenuItemIcon ${_iconClass}\" dojoAttachPoint=\"iconNode\"\n\t\t\t><input class=\"dojoxCheckedMultiSelectCheckBoxInput\" dojoAttachPoint=\"inputNode\" type=\"${_type.type}\"\n\t\t/></div></td\n\t><td class=\"dijitReset dijitMenuItemLabel\" colspan=\"2\" dojoAttachPoint=\"containerNode,labelNode\"></td\n\t><td class=\"dijitReset dijitMenuItemAccelKey\" style=\"display: none\" dojoAttachPoint=\"accelKeyNode\"></td\n\t><td class=\"dijitReset dijitMenuArrowCell\" role=\"presentation\">&nbsp;</td\n></tr>",
+'url:dojox/form/resources/_CheckedMultiSelectItem.html':"<div class=\"dijitReset ${baseClass}\"\n\t><input class=\"${baseClass}Box\" data-dojo-type=\"dijit.form.CheckBox\" data-dojo-attach-point=\"checkBox\" \n\t\tdata-dojo-attach-event=\"_onClick:_changeBox\" type=\"${_type.type}\" baseClass=\"${_type.baseClass}\"\n\t/><div class=\"dijitInline ${baseClass}Label\" data-dojo-attach-point=\"labelNode\" data-dojo-attach-event=\"onclick:_onClick\"></div\n></div>\n",
+'url:dojox/form/resources/CheckedMultiSelect.html':"<div class=\"dijit dijitReset dijitInline dijitLeft\" id=\"widget_${id}\"\n\t><div data-dojo-attach-point=\"comboButtonNode\"\n\t></div\n\t><div data-dojo-attach-point=\"selectNode\" class=\"dijit dijitReset dijitInline ${baseClass}Wrapper\" data-dojo-attach-event=\"onmousedown:_onMouseDown,onclick:focus\"\n\t\t><select class=\"${baseClass}Select dojoxCheckedMultiSelectHidden\" multiple=\"true\" data-dojo-attach-point=\"containerNode,focusNode\"></select\n\t\t><div data-dojo-attach-point=\"wrapperDiv\"></div\n\t></div\n></div>"}});
+define("dojox/form/CheckedMultiSelect", [
+ "dojo/_base/declare",
+ "dojo/_base/lang",
+ "dojo/_base/array",
+ "dojo/_base/event",
+ "dojo/dom-geometry",
+ "dojo/dom-class",
+ "dojo/dom-construct",
+ "dojo/i18n",
+ "dijit/_Widget",
+ "dijit/_TemplatedMixin",
+ "dijit/_WidgetsInTemplateMixin",
+ "dijit/registry",
+ "dijit/Menu",
+ "dijit/MenuItem",
+ "dijit/Tooltip",
+ "dijit/form/_FormSelectWidget",
+ "dijit/form/ComboButton",
+ "dojo/text!dojox/form/resources/_CheckedMultiSelectMenuItem.html",
+ "dojo/text!dojox/form/resources/_CheckedMultiSelectItem.html",
+ "dojo/text!dojox/form/resources/CheckedMultiSelect.html",
+ "dojo/i18n!dojox/form/nls/CheckedMultiSelect",
+ "dijit/form/CheckBox" // template
+], function(declare, lang, array, event, domGeometry, domClass, domConstruct, i18n, Widget, TemplatedMixin, WidgetsInTemplateMixin, registry, Menu, MenuItem, Tooltip, FormSelectWidget, ComboButton, CheckedMultiSelectMenuItem, CheckedMultiSelectItem, CheckedMultiSelect, nlsCheckedMultiSelect){
+
+ // module:
+ // dojox/form/CheckedMultiSelect
+ // summary:
+ // Extends the core dojox.form.CheckedMultiSelect to provide a "checkbox" selector
+ //
+
+ /*=====
+ Widget = dijit._Widget;
+ TemplatedMixin = dijit._TemplatedMixin;
+ WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
+ Menu = dijit.Menu;
+ MenuItem = dijit.MenuItem;
+ FormSelectWidget = dijit.form._FormSelectWidget;
+ =====*/
+var formCheckedMultiSelectItem = declare("dojox.form._CheckedMultiSelectItem", [Widget, TemplatedMixin, WidgetsInTemplateMixin], {
+ // summary:
+ // The individual items for a CheckedMultiSelect
+
+ templateString: CheckedMultiSelectItem,
+
+ baseClass: "dojoxMultiSelectItem",
+
+ // option: dojox.form.__SelectOption
+ // The option that is associated with this item
+ option: null,
+ parent: null,
+
+ // disabled: boolean
+ // Whether or not this widget is disabled
+ disabled: false,
+
+ // readOnly: boolean
+ // Whether or not this widget is readOnly
+ readOnly: false,
+
+ postMixInProperties: function(){
+ // summary:
+ // Set the appropriate _subClass value - based on if we are multi-
+ // or single-select
+ this._type = this.parent.multiple ?
+ {type: "checkbox", baseClass: "dijitCheckBox"} :
+ {type: "radio", baseClass: "dijitRadio"};
+ this.disabled = this.option.disabled = this.option.disabled||false;
+ this.inherited(arguments);
+ },
+
+ postCreate: function(){
+ // summary:
+ // Set innerHTML here - since the template gets messed up sometimes
+ // with rich text
+ this.inherited(arguments);
+ this.labelNode.innerHTML = this.option.label;
+ },
+
+ _changeBox: function(){
+ // summary:
+ // Called to force the select to match the state of the check box
+ // (only on click of the checkbox) Radio-based calls _setValueAttr
+ // instead.
+ if(this.get("disabled") || this.get("readOnly")){ return; }
+ if(this.parent.multiple){
+ this.option.selected = this.checkBox.get('value') && true;
+ }else{
+ this.parent.set('value', this.option.value);
+ }
+ // fire the parent's change
+ this.parent._updateSelection();
+
+ // refocus the parent
+ this.parent.focus();
+ },
+
+ _onClick: function(e){
+ // summary:
+ // Sets the click state (passes through to the check box)
+ if(this.get("disabled") || this.get("readOnly")){
+ event.stop(e);
+ }else{
+ this.checkBox._onClick(e);
+ }
+ },
+
+ _updateBox: function(){
+ // summary:
+ // Called to force the box to match the state of the select
+ this.checkBox.set('value', this.option.selected);
+ },
+
+ _setDisabledAttr: function(value){
+ // summary:
+ // Disables (or enables) all the children as well
+ this.disabled = value||this.option.disabled;
+ this.checkBox.set("disabled", this.disabled);
+ domClass.toggle(this.domNode, "dojoxMultiSelectDisabled", this.disabled);
+ },
+
+ _setReadOnlyAttr: function(value){
+ // summary:
+ // Sets read only (or unsets) all the children as well
+ this.checkBox.set("readOnly", value);
+ this.readOnly = value;
+ }
+});
+
+var formCheckedMultiSelectMenu = declare("dojox.form._CheckedMultiSelectMenu", Menu, {
+ // summary:
+ // An internally-used menu for dropdown that allows us a vertical scrollbar
+ multiple: false,
+
+ // summary:
+ // An internally-used menu for dropdown that allows us a vertical scrollbar
+ buildRendering: function(){
+ // summary:
+ // Stub in our own changes, so that our domNode is not a table
+ // otherwise, we won't respond correctly to heights/overflows
+ this.inherited(arguments);
+ var o = (this.menuTableNode = this.domNode),
+ n = (this.domNode = domConstruct.create("div", {style: {overflowX: "hidden", overflowY: "scroll"}}));
+ if(o.parentNode){
+ o.parentNode.replaceChild(n, o);
+ }
+ domClass.remove(o, "dijitMenuTable");
+ n.className = o.className + " dojoxCheckedMultiSelectMenu";
+ o.className = "dijitReset dijitMenuTable";
+ o.setAttribute("role", "listbox");
+ n.setAttribute("role", "presentation");
+ n.appendChild(o);
+ },
+
+ resize: function(/*Object*/ mb){
+ // summary:
+ // Overridden so that we are able to handle resizing our
+ // internal widget. Note that this is not a "full" resize
+ // implementation - it only works correctly if you pass it a
+ // marginBox.
+ //
+ // mb: Object
+ // The margin box to set this dropdown to.
+ if(mb){
+ domGeometry.setMarginBox(this.domNode, mb);
+ if("w" in mb){
+ // We've explicitly set the wrapper <div>'s width, so set <table> width to match.
+ // 100% is safer than a pixel value because there may be a scroll bar with
+ // browser/OS specific width.
+ this.menuTableNode.style.width = "100%";
+ }
+ }
+ },
+
+ onClose: function(){
+ this.inherited(arguments);
+ if(this.menuTableNode){
+ // Erase possible width: 100% setting from _SelectMenu.resize().
+ // Leaving it would interfere with the next openDropDown() call, which
+ // queries the natural size of the drop down.
+ this.menuTableNode.style.width = "";
+ }
+ },
+
+ onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
+ // summary:
+ // Handle clicks on an item.
+ // tags:
+ // private
+ // this can't be done in _onFocus since the _onFocus events occurs asynchronously
+ if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
+ this._markActive();
+ }
+
+ this.focusChild(item);
+
+ if(item.disabled || item.readOnly){ return false; }
+
+ if(!this.multiple){
+ // before calling user defined handler, close hierarchy of menus
+ // and restore focus to place it was when menu was opened
+ this.onExecute();
+ }
+ // user defined handler for click
+ item.onClick(evt);
+ }
+});
+
+var formCheckedMultiSelectMenuItem = declare("dojox.form._CheckedMultiSelectMenuItem", MenuItem, {
+ // summary:
+ // A checkbox-like menu item for toggling on and off
+
+ templateString: CheckedMultiSelectMenuItem,
+
+ // option: dojox.form.__SelectOption
+ // The option that is associated with this item
+ option: null,
+
+ // reference of dojox.form._CheckedMultiSelectMenu
+ parent: null,
+
+ // icon of the checkbox/radio button
+ _iconClass: "",
+
+ postMixInProperties: function(){
+ // summary:
+ // Set the appropriate _subClass value - based on if we are multi-
+ // or single-select
+ if(this.parent.multiple){
+ this._iconClass = "dojoxCheckedMultiSelectMenuCheckBoxItemIcon";
+ this._type = {type: "checkbox"};
+ }else{
+ this._iconClass = "";
+ this._type = {type: "hidden"};
+ }
+ this.disabled = this.option.disabled;
+ this.checked = this.option.selected;
+ this.label = this.option.label;
+ this.readOnly = this.option.readOnly;
+ this.inherited(arguments);
+ },
+
+ onChange: function(/*Boolean*/ checked){
+ // summary:
+ // User defined function to handle check/uncheck events
+ // tags:
+ // callback
+ },
+
+ _updateBox: function(){
+ // summary:
+ // Called to force the box to match the state of the select
+ domClass.toggle(this.domNode, "dojoxCheckedMultiSelectMenuItemChecked", !!this.option.selected);
+ this.domNode.setAttribute("aria-checked", this.option.selected);
+ this.inputNode.checked = this.option.selected;
+ if(!this.parent.multiple){
+ domClass.toggle(this.domNode, "dijitSelectSelectedOption", !!this.option.selected);
+ }
+ },
+
+ _onClick: function(/*Event*/ e){
+ // summary:
+ // Clicking this item just toggles its state
+ // tags:
+ // private
+ if(!this.disabled && !this.readOnly){
+ if(this.parent.multiple){
+ this.option.selected = !this.option.selected;
+ this.parent.onChange();
+ this.onChange(this.option.selected);
+ }else{
+ if(!this.option.selected){
+ array.forEach(this.parent.getChildren(), function(item){
+ item.option.selected = false;
+ });
+ this.option.selected = true;
+ this.parent.onChange();
+ this.onChange(this.option.selected);
+ }
+ }
+ }
+ this.inherited(arguments);
+ }
+});
+
+var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelectWidget, {
+ // summary:
+ // Extends the core dijit MultiSelect to provide a "checkbox" selector
+
+ templateString: CheckedMultiSelect,
+
+ baseClass: "dojoxCheckedMultiSelect",
+
+ // required: Boolean
+ // User is required to check at least one item.
+ required: false,
+
+ // invalidMessage: String
+ // The message to display if value is invalid.
+ invalidMessage: "$_unset_$",
+
+ // _message: String
+ // Currently displayed message
+ _message: "",
+
+ // dropDown: Boolean
+ // Drop down version or not
+ dropDown: false,
+
+ // labelText: String
+ // Label of the drop down button
+ labelText: "",
+
+ // tooltipPosition: String[]
+ // See description of `Tooltip.defaultPosition` for details on this parameter.
+ tooltipPosition: [],
+
+ setStore: function(store, selectedValue, fetchArgs){
+ // summary:
+ // If there is any items selected in the store, the value
+ // of the widget will be set to the values of these items.
+ this.inherited(arguments);
+ var setSelectedItems = function(items){
+ var value = array.map(items, function(item){ return item.value[0]; });
+ if(value.length){
+ this.set("value", value);
+ }
+ };
+ this.store.fetch({query:{selected: true}, onComplete: setSelectedItems, scope: this});
+ },
+
+ postMixInProperties: function(){
+ this.inherited(arguments);
+ this._nlsResources = i18n.getLocalization("dojox.form", "CheckedMultiSelect", this.lang);
+ if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this._nlsResources.invalidMessage; }
+ },
+
+ _fillContent: function(){
+ // summary:
+ // Set the value to be the first, or the selected index
+ this.inherited(arguments);
+
+ // set value from selected option
+ if(this.options.length && !this.value && this.srcNodeRef){
+ var si = this.srcNodeRef.selectedIndex || 0; // || 0 needed for when srcNodeRef is not a SELECT
+ this.value = this.options[si >= 0 ? si : 0].value;
+ }
+ if(this.dropDown){
+ domClass.toggle(this.selectNode, "dojoxCheckedMultiSelectHidden");
+ this.dropDownMenu = new formCheckedMultiSelectMenu({
+ id: this.id + "_menu",
+ style: "display: none;",
+ multiple: this.multiple,
+ onChange: lang.hitch(this, "_updateSelection")
+ });
+ }
+ },
+
+ startup: function(){
+ // summary:
+ // Set the value to be the first, or the selected index
+ this.inherited(arguments);
+ if(this.dropDown){
+ this.dropDownButton = new ComboButton({
+ label: this.labelText,
+ dropDown: this.dropDownMenu,
+ baseClass: "dojoxCheckedMultiSelectButton",
+ maxHeight: this.maxHeight
+ }, this.comboButtonNode);
+ }
+ },
+
+ _onMouseDown: function(e){
+ // summary:
+ // Cancels the mousedown event to prevent others from stealing
+ // focus
+ event.stop(e);
+ },
+
+ validator: function(){
+ // summary:
+ // Overridable function used to validate that an item is selected if required =
+ // true.
+ // tags:
+ // protected
+ if(!this.required){ return true; }
+ return array.some(this.getOptions(), function(opt){
+ return opt.selected && opt.value != null && opt.value.toString().length != 0;
+ });
+ },
+
+ validate: function(isFocused){
+ Tooltip.hide(this.domNode);
+ var isValid = this.isValid(isFocused);
+ if(!isValid){ this.displayMessage(this.invalidMessage); }
+ return isValid;
+ },
+
+ isValid: function(/*Boolean*/ isFocused){
+ // summary:
+ // Tests if the required items are selected.
+ // Can override with your own routine in a subclass.
+ // tags:
+ // protected
+ return this.validator();
+ },
+
+ getErrorMessage: function(/*Boolean*/ isFocused){
+ // summary:
+ // Return an error message to show if appropriate
+ // tags:
+ // protected
+ return this.invalidMessage;
+ },
+
+ displayMessage: function(/*String*/ message){
+ // summary:
+ // Overridable method to display validation errors/hints.
+ // By default uses a tooltip.
+ // tags:
+ // extension
+ Tooltip.hide(this.domNode);
+ if(message){
+ Tooltip.show(message, this.domNode, this.tooltipPosition);
+ }
+ },
+
+ onAfterAddOptionItem: function(item, option){
+ // summary:
+ // a function that can be connected to in order to receive a
+ // notification that an item as been added to this dijit.
+ },
+
+ _addOptionItem: function(/* dojox.form.__SelectOption */ option){
+ var item;
+ if(this.dropDown){
+ item = new formCheckedMultiSelectMenuItem({
+ option: option,
+ parent: this.dropDownMenu
+ });
+ this.dropDownMenu.addChild(item);
+ }else{
+ item = new formCheckedMultiSelectItem({
+ option: option,
+ parent: this
+ });
+ this.wrapperDiv.appendChild(item.domNode);
+ }
+ this.onAfterAddOptionItem(item, option);
+ },
+
+ _refreshState: function(){
+ // summary:
+ // Validate if selection changes.
+ this.validate(this.focused);
+ },
+
+ onChange: function(newValue){
+ // summary:
+ // Validate if selection changes.
+ this._refreshState();
+ },
+
+ reset: function(){
+ // summary: Overridden so that the state will be cleared.
+ this.inherited(arguments);
+ Tooltip.hide(this.domNode);
+ },
+
+ _updateSelection: function(){
+ this.inherited(arguments);
+ this._handleOnChange(this.value);
+ array.forEach(this._getChildren(), function(item){
+ item._updateBox();
+ });
+ if(this.dropDown && this.dropDownButton){
+ var i = 0, label = "";
+ array.forEach(this.options, function(option){
+ if(option.selected){
+ i++;
+ label = option.label;
+ }
+ });
+ this.dropDownButton.set("label", this.multiple ?
+ lang.replace(this._nlsResources.multiSelectLabelText, {num: i}) :
+ label);
+ }
+ },
+
+ _getChildren: function(){
+ if(this.dropDown){
+ return this.dropDownMenu.getChildren();
+ }else{
+ return array.map(this.wrapperDiv.childNodes, function(n){
+ return registry.byNode(n);
+ });
+ }
+ },
+
+ invertSelection: function(onChange){
+ // summary: Invert the selection
+ // onChange: Boolean
+ // If null, onChange is not fired.
+ if(this.multiple){
+ array.forEach(this.options, function(i){
+ i.selected = !i.selected;
+ });
+ this._updateSelection();
+ }
+ },
+
+ _setDisabledAttr: function(value){
+ // summary:
+ // Disable (or enable) all the children as well
+ this.inherited(arguments);
+ if(this.dropDown){
+ this.dropDownButton.set("disabled", value);
+ }
+ array.forEach(this._getChildren(), function(node){
+ if(node && node.set){
+ node.set("disabled", value);
+ }
+ });
+ },
+
+ _setReadOnlyAttr: function(value){
+ // summary:
+ // Sets read only (or unsets) all the children as well
+ this.inherited(arguments);
+ if("readOnly" in this.attributeMap){
+ this._attrToDom("readOnly", value);
+ }
+ this.readOnly = value;
+ array.forEach(this._getChildren(), function(node){
+ if(node && node.set){
+ node.set("readOnly", value);
+ }
+ });
+ },
+
+ uninitialize: function(){
+ Tooltip.hide(this.domNode);
+ // Make sure these children are destroyed
+ array.forEach(this._getChildren(), function(child){
+ child.destroyRecursive();
+ });
+ this.inherited(arguments);
+ }
+});
+
+return formCheckedMultiSelect;
+}); \ No newline at end of file