]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/form/Select.js.uncompressed.js
2 'url:dijit/form/templates/Select.html':"<table class=\"dijit dijitReset dijitInline dijitLeft\"\n\tdata-dojo-attach-point=\"_buttonNode,tableNode,focusNode\" cellspacing='0' cellpadding='0'\n\trole=\"listbox\" aria-haspopup=\"true\"\n\t><tbody role=\"presentation\"><tr role=\"presentation\"\n\t\t><td class=\"dijitReset dijitStretch dijitButtonContents\" role=\"presentation\"\n\t\t\t><div class=\"dijitReset dijitInputField dijitButtonText\" data-dojo-attach-point=\"containerNode,_popupStateNode\" role=\"presentation\"></div\n\t\t\t><div class=\"dijitReset dijitValidationContainer\"\n\t\t\t\t><input class=\"dijitReset dijitInputField dijitValidationIcon dijitValidationInner\" value=\"Χ \" type=\"text\" tabIndex=\"-1\" readonly=\"readonly\" role=\"presentation\"\n\t\t\t/></div\n\t\t\t><input type=\"hidden\" ${!nameAttrSetting} data-dojo-attach-point=\"valueNode\" value=\"${value}\" aria-hidden=\"true\"\n\t\t/></td\n\t\t><td class=\"dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer\"\n\t\t\tdata-dojo-attach-point=\"titleNode\" role=\"presentation\"\n\t\t\t><input class=\"dijitReset dijitInputField dijitArrowButtonInner\" value=\"▼ \" type=\"text\" tabIndex=\"-1\" readonly=\"readonly\" role=\"presentation\"\n\t\t\t\t${_buttonInputDisabled}\n\t\t/></td\n\t></tr></tbody\n></table>\n"}});
3 define("dijit/form/Select", [
4 "dojo/_base/array", // array.forEach
5 "dojo/_base/declare", // declare
6 "dojo/dom-attr", // domAttr.set
7 "dojo/dom-class", // domClass.add domClass.remove domClass.toggle
8 "dojo/dom-geometry", // domGeometry.setMarginBox
9 "dojo/_base/event", // event.stop
10 "dojo/i18n", // i18n.getLocalization
11 "dojo/_base/lang", // lang.hitch
12 "dojo/sniff", // has("ie")
13 "./_FormSelectWidget",
19 "dojo/text!./templates/Select.html",
20 "dojo/i18n!./nls/validate"
21 ], function(array
, declare
, domAttr
, domClass
, domGeometry
, event
, i18n
, lang
, has
,
22 _FormSelectWidget
, _HasDropDown
, Menu
, MenuItem
, MenuSeparator
, Tooltip
, template
){
28 var _SelectMenu
= declare("dijit.form._SelectMenu", Menu
, {
30 // An internally-used menu for dropdown that allows us a vertical scrollbar
32 // Override Menu.autoFocus setting so that opening a Select highlights the current value.
35 buildRendering: function(){
37 // Stub in our own changes, so that our domNode is not a table
38 // otherwise, we won't respond correctly to heights/overflows
39 this.inherited(arguments
);
40 var o
= (this.menuTableNode
= this.domNode
);
41 var n
= (this.domNode
= this.ownerDocument
.createElement("div"));
42 n
.style
.cssText
= "overflow-x: hidden; overflow-y: scroll";
44 o
.parentNode
.replaceChild(n
, o
);
46 domClass
.remove(o
, "dijitMenuTable");
47 n
.className
= o
.className
+ " dijitSelectMenu";
48 o
.className
= "dijitReset dijitMenuTable";
49 o
.setAttribute("role", "listbox");
50 n
.setAttribute("role", "presentation");
54 postCreate: function(){
56 // stop mousemove from selecting text on IE to be consistent with other browsers
58 this.inherited(arguments
);
60 this.connect(this.domNode
, "onselectstart", event
.stop
);
66 // Overridden so that the previously selected value will be focused instead of only the first item
68 val
= this.parentWidget
.value
;
69 if(lang
.isArray(val
)){
70 val
= val
[val
.length
-1];
72 if(val
){ // if focus selected
73 array
.forEach(this.parentWidget
._getChildren(), function(child
){
74 if(child
.option
&& (val
=== child
.option
.value
)){ // find menu item widget with this value
76 this.focusChild(child
, false); // focus previous selection
81 this.inherited(arguments
); // focus first item by default
85 resize: function(/*Object*/ mb
){
87 // Overridden so that we are able to handle resizing our
88 // internal widget. Note that this is not a "full" resize
89 // implementation - it only works correctly if you pass it a
93 // The margin box to set this dropdown to.
95 domGeometry
.setMarginBox(this.domNode
, mb
);
97 // We've explicitly set the wrapper <div>'s width, so set <table> width to match.
98 // 100% is safer than a pixel value because there may be a scroll bar with
99 // browser/OS specific width.
100 this.menuTableNode
.style
.width
= "100%";
106 var Select
= declare("dijit.form.Select", [_FormSelectWidget
, _HasDropDown
], {
108 // This is a "styleable" select box - it is basically a DropDownButton which
109 // can take a `<select>` as its input.
111 baseClass
: "dijitSelect dijitValidationTextBox",
113 templateString
: template
,
115 _buttonInputDisabled
: has("ie") ? "disabled" : "", // allows IE to disallow focus, but Firefox cannot be disabled for mousedown events
118 // Can be true or false, default is false.
121 // state: [readonly] String
122 // "Incomplete" if this select is required but unset (i.e. blank value), "" otherwise
126 // Currently displayed error/prompt message
129 // tooltipPosition: String[]
130 // See description of `dijit/Tooltip.defaultPosition` for details on this parameter.
133 // emptyLabel: string
134 // What to display in an "empty" dropdown
135 emptyLabel
: " ", //
137 // _isLoaded: Boolean
138 // Whether or not we have been loaded
141 // _childrenLoaded: Boolean
142 // Whether or not our children have been loaded
143 _childrenLoaded
: false,
145 _fillContent: function(){
147 // Set the value to be the first, or the selected index
148 this.inherited(arguments
);
149 // set value from selected option
150 if(this.options
.length
&& !this.value
&& this.srcNodeRef
){
151 var si
= this.srcNodeRef
.selectedIndex
|| 0; // || 0 needed for when srcNodeRef is not a SELECT
152 this.value
= this.options
[si
>= 0 ? si
: 0].value
;
154 // Create the dropDown widget
155 this.dropDown
= new _SelectMenu({ id
: this.id
+ "_menu", parentWidget
: this });
156 domClass
.add(this.dropDown
.domNode
, this.baseClass
.replace(/\s+|$/g, "Menu "));
159 _getMenuItemForOption: function(/*_FormSelectWidget.__SelectOption*/ option
){
161 // For the given option, return the menu item that should be
162 // used to display it. This can be overridden as needed
163 if(!option
.value
&& !option
.label
){
164 // We are a separator (no label set for it)
165 return new MenuSeparator({ownerDocument
: this.ownerDocument
});
167 // Just a regular menu option
168 var click
= lang
.hitch(this, "_setValueAttr", option
);
169 var item
= new MenuItem({
171 label
: option
.label
|| this.emptyLabel
,
173 ownerDocument
: this.ownerDocument
,
175 disabled
: option
.disabled
|| false
177 item
.focusNode
.setAttribute("role", "option");
182 _addOptionItem: function(/*_FormSelectWidget.__SelectOption*/ option
){
184 // For the given option, add an option to our dropdown.
185 // If the option doesn't have a value, then a separator is added
188 this.dropDown
.addChild(this._getMenuItemForOption(option
));
192 _getChildren: function(){
196 return this.dropDown
.getChildren();
199 _loadChildren: function(/*Boolean*/ loadMenuItems
){
201 // Resets the menu and the length attribute of the button - and
202 // ensures that the label is appropriately set.
203 // loadMenuItems: Boolean
204 // actually loads the child menu items - we only do this when we are
205 // populating for showing the dropdown.
207 if(loadMenuItems
=== true){
208 // this.inherited destroys this.dropDown's child widgets (MenuItems).
209 // Avoid this.dropDown (Menu widget) having a pointer to a destroyed widget (which will cause
210 // issues later in _setSelected). (see #10296)
212 delete this.dropDown
.focusedChild
;
214 if(this.options
.length
){
215 this.inherited(arguments
);
217 // Drop down menu is blank but add one blank entry just so something appears on the screen
218 // to let users know that they are no choices (mimicing native select behavior)
219 array
.forEach(this._getChildren(), function(child
){ child
.destroyRecursive(); });
220 var item
= new MenuItem({
221 ownerDocument
: this.ownerDocument
,
222 label
: this.emptyLabel
224 this.dropDown
.addChild(item
);
227 this._updateSelection();
230 this._isLoaded
= false;
231 this._childrenLoaded
= true;
233 if(!this._loadingStore
){
234 // Don't call this if we are loading - since we will handle it later
235 this._setValueAttr(this.value
, false);
239 _refreshState: function(){
241 this.validate(this.focused
);
246 this.inherited(arguments
);
247 this._refreshState(); // after all _set* methods have run
250 _setValueAttr: function(value
){
251 this.inherited(arguments
);
252 domAttr
.set(this.valueNode
, "value", this.get("value"));
253 this._refreshState(); // to update this.state
256 _setDisabledAttr: function(/*Boolean*/ value
){
257 this.inherited(arguments
);
258 this._refreshState(); // to update this.state
261 _setRequiredAttr: function(/*Boolean*/ value
){
262 this._set("required", value
);
263 this.focusNode
.setAttribute("aria-required", value
);
264 this._refreshState(); // to update this.state
267 _setOptionsAttr: function(/*Array*/ options
){
268 this._isLoaded
= false;
269 this._set('options', options
);
272 _setDisplay: function(/*String*/ newDisplay
){
274 // sets the display for the given value (or values)
275 var lbl
= newDisplay
|| this.emptyLabel
;
276 this.containerNode
.innerHTML
= '<span role="option" class="dijitReset dijitInline ' + this.baseClass
.replace(/\s+|$/g, "Label ")+'">' + lbl
+ '</span>';
279 validate: function(/*Boolean*/ isFocused
){
281 // Called by oninit, onblur, and onkeypress, and whenever required/disabled state changes
283 // Show missing or invalid messages if appropriate, and highlight textbox field.
284 // Used when a select is initially set to no value and the user is required to
287 var isValid
= this.disabled
|| this.isValid(isFocused
);
288 this._set("state", isValid
? "" : (this._hasBeenBlurred
? "Error" : "Incomplete"));
289 this.focusNode
.setAttribute("aria-invalid", isValid
? "false" : "true");
290 var message
= isValid
? "" : this._missingMsg
;
291 if(message
&& this.focused
&& this._hasBeenBlurred
){
292 Tooltip
.show(message
, this.domNode
, this.tooltipPosition
, !this.isLeftToRight());
294 Tooltip
.hide(this.domNode
);
296 this._set("message", message
);
300 isValid: function(/*Boolean*/ /*===== isFocused =====*/){
302 // Whether or not this is a valid value. The only way a Select
303 // can be invalid is when it's required but nothing is selected.
304 return (!this.required
|| this.value
=== 0 || !(/^\s*$/.test(this.value
|| ""))); // handle value is null or undefined
309 // Overridden so that the state will be cleared.
310 this.inherited(arguments
);
311 Tooltip
.hide(this.domNode
);
312 this._refreshState(); // to update this.state
315 postMixInProperties: function(){
317 // set the missing message
318 this.inherited(arguments
);
319 this._missingMsg
= i18n
.getLocalization("dijit.form", "validate", this.lang
).missingMessage
;
322 postCreate: function(){
324 // stop mousemove from selecting text on IE to be consistent with other browsers
326 this.inherited(arguments
);
328 this.connect(this.domNode
, "onselectstart", event
.stop
);
329 this.domNode
.setAttribute("aria-expanded", "false");
332 // IE INPUT tag fontFamily has to be set directly using STYLE
333 // the defer gives IE a chance to render the TextBox and to deal with font inheritance
334 this.defer(function(){
336 var s
= domStyle
.getComputedStyle(this.domNode
); // can throw an exception if widget is immediately destroyed
338 var ff
= s
.fontFamily
;
340 var inputs
= this.domNode
.getElementsByTagName("INPUT");
342 for(var i
=0; i
< inputs
.length
; i
++){
343 inputs
[i
].style
.fontFamily
= ff
;
348 }catch(e
){/*when used in a Dialog, and this is called before the dialog is
349 shown, s.fontFamily would trigger "Invalid Argument" error.*/}
354 _setStyleAttr: function(/*String||Object*/ value
){
355 this.inherited(arguments
);
356 domClass
.toggle(this.domNode
, this.baseClass
.replace(/\s+|$/g, "FixedWidth "), !!this.domNode
.style
.width
);
359 isLoaded: function(){
360 return this._isLoaded
;
363 loadDropDown: function(/*Function*/ loadCallback
){
365 // populates the menu
366 this._loadChildren(true);
367 this._isLoaded
= true;
371 closeDropDown: function(){
372 // overriding _HasDropDown.closeDropDown()
373 this.inherited(arguments
);
375 if(this.dropDown
&& this.dropDown
.menuTableNode
){
376 // Erase possible width: 100% setting from _SelectMenu.resize().
377 // Leaving it would interfere with the next openDropDown() call, which
378 // queries the natural size of the drop down.
379 this.dropDown
.menuTableNode
.style
.width
= "";
383 destroy: function(preserveDom
){
384 if(this.dropDown
&& !this.dropDown
._destroyed
){
385 this.dropDown
.destroyRecursive(preserveDom
);
386 delete this.dropDown
;
388 this.inherited(arguments
);
391 _onFocus: function(){
392 this.validate(true); // show tooltip if second focus of required tooltip, but no selection
393 this.inherited(arguments
);
397 Tooltip
.hide(this.domNode
);
398 this.inherited(arguments
);
399 this.validate(false);
403 Select
._Menu
= _SelectMenu
; // for monkey patching