]> git.wh0rd.org Git - tt-rss.git/blob - lib/dijit/form/ValidationTextBox.js.uncompressed.js
upgrade dojo to 1.8.3 (refs #570)
[tt-rss.git] / lib / dijit / form / ValidationTextBox.js.uncompressed.js
1 require({cache:{
2 'url:dijit/form/templates/ValidationTextBox.html':"<div class=\"dijit dijitReset dijitInline dijitLeft\"\n\tid=\"widget_${id}\" role=\"presentation\"\n\t><div class='dijitReset dijitValidationContainer'\n\t\t><input class=\"dijitReset dijitInputField dijitValidationIcon dijitValidationInner\" value=\"&#935; \" type=\"text\" tabIndex=\"-1\" readonly=\"readonly\" role=\"presentation\"\n\t/></div\n\t><div class=\"dijitReset dijitInputField dijitInputContainer\"\n\t\t><input class=\"dijitReset dijitInputInner\" data-dojo-attach-point='textbox,focusNode' autocomplete=\"off\"\n\t\t\t${!nameAttrSetting} type='${type}'\n\t/></div\n></div>\n"}});
3 define("dijit/form/ValidationTextBox", [
4         "dojo/_base/declare", // declare
5         "dojo/_base/kernel", // kernel.deprecated
6         "dojo/i18n", // i18n.getLocalization
7         "./TextBox",
8         "../Tooltip",
9         "dojo/text!./templates/ValidationTextBox.html",
10         "dojo/i18n!./nls/validate"
11 ], function(declare, kernel, i18n, TextBox, Tooltip, template){
12
13         // module:
14         //              dijit/form/ValidationTextBox
15
16
17         /*=====
18         var __Constraints = {
19                 // locale: String
20                 //              locale used for validation, picks up value from this widget's lang attribute
21                 // _flags_: anything
22                 //              various flags passed to pattern function
23         };
24         =====*/
25
26         var ValidationTextBox;
27         return ValidationTextBox = declare("dijit.form.ValidationTextBox", TextBox, {
28                 // summary:
29                 //              Base class for textbox widgets with the ability to validate content of various types and provide user feedback.
30
31                 templateString: template,
32
33                 // required: Boolean
34                 //              User is required to enter data into this field.
35                 required: false,
36
37                 // promptMessage: String
38                 //              If defined, display this hint string immediately on focus to the textbox, if empty.
39                 //              Also displays if the textbox value is Incomplete (not yet valid but will be with additional input).
40                 //              Think of this like a tooltip that tells the user what to do, not an error message
41                 //              that tells the user what they've done wrong.
42                 //
43                 //              Message disappears when user starts typing.
44                 promptMessage: "",
45
46                 // invalidMessage: String
47                 //              The message to display if value is invalid.
48                 //              The translated string value is read from the message file by default.
49                 //              Set to "" to use the promptMessage instead.
50                 invalidMessage: "$_unset_$",
51
52                 // missingMessage: String
53                 //              The message to display if value is empty and the field is required.
54                 //              The translated string value is read from the message file by default.
55                 //              Set to "" to use the invalidMessage instead.
56                 missingMessage: "$_unset_$",
57
58                 // message: String
59                 //              Currently error/prompt message.
60                 //              When using the default tooltip implementation, this will only be
61                 //              displayed when the field is focused.
62                 message: "",
63
64                 // constraints: __Constraints
65                 //              user-defined object needed to pass parameters to the validator functions
66                 constraints: {},
67
68                 // pattern: [extension protected] String|Function(constraints) returning a string.
69                 //              This defines the regular expression used to validate the input.
70                 //              Do not add leading ^ or $ characters since the widget adds these.
71                 //              A function may be used to generate a valid pattern when dependent on constraints or other runtime factors.
72                 //              set('pattern', String|Function).
73                 pattern: ".*",
74
75                 // regExp: Deprecated [extension protected] String.  Use "pattern" instead.
76                 regExp: "",
77
78                 regExpGen: function(/*__Constraints*/ /*===== constraints =====*/){
79                         // summary:
80                         //              Deprecated.  Use set('pattern', Function) instead.
81                 },
82
83                 // state: [readonly] String
84                 //              Shows current state (ie, validation result) of input (""=Normal, Incomplete, or Error)
85                 state: "",
86
87                 // tooltipPosition: String[]
88                 //              See description of `dijit/Tooltip.defaultPosition` for details on this parameter.
89                 tooltipPosition: [],
90
91                 _deprecateRegExp: function(attr, value){
92                         if(value != ValidationTextBox.prototype[attr]){
93                                 kernel.deprecated("ValidationTextBox id="+this.id+", set('" + attr + "', ...) is deprecated.  Use set('pattern', ...) instead.", "", "2.0");
94                                 this.set('pattern', value);
95                         }
96                 },
97                 _setRegExpGenAttr: function(/*Function*/ newFcn){
98                         this._deprecateRegExp("regExpGen", newFcn);
99                         this.regExpGen = this._getPatternAttr; // backward compat with this.regExpGen(this.constraints)
100                 },
101                 _setRegExpAttr: function(/*String*/ value){
102                         this._deprecateRegExp("regExp", value);
103                 },
104
105                 _setValueAttr: function(){
106                         // summary:
107                         //              Hook so set('value', ...) works.
108                         this.inherited(arguments);
109                         this.validate(this.focused);
110                 },
111
112                 validator: function(/*anything*/ value, /*__Constraints*/ constraints){
113                         // summary:
114                         //              Overridable function used to validate the text input against the regular expression.
115                         // tags:
116                         //              protected
117                         return (new RegExp("^(?:" + this._getPatternAttr(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
118                                 (!this.required || !this._isEmpty(value)) &&
119                                 (this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean
120                 },
121
122                 _isValidSubset: function(){
123                         // summary:
124                         //              Returns true if the value is either already valid or could be made valid by appending characters.
125                         //              This is used for validation while the user [may be] still typing.
126                         return this.textbox.value.search(this._partialre) == 0;
127                 },
128
129                 isValid: function(/*Boolean*/ /*===== isFocused =====*/){
130                         // summary:
131                         //              Tests if value is valid.
132                         //              Can override with your own routine in a subclass.
133                         // tags:
134                         //              protected
135                         return this.validator(this.textbox.value, this.constraints);
136                 },
137
138                 _isEmpty: function(value){
139                         // summary:
140                         //              Checks for whitespace
141                         return (this.trim ? /^\s*$/ : /^$/).test(value); // Boolean
142                 },
143
144                 getErrorMessage: function(/*Boolean*/ /*===== isFocused =====*/){
145                         // summary:
146                         //              Return an error message to show if appropriate
147                         // tags:
148                         //              protected
149                         var invalid = this.invalidMessage == "$_unset_$" ? this.messages.invalidMessage :
150                                 !this.invalidMessage ? this.promptMessage : this.invalidMessage;
151                         var missing = this.missingMessage == "$_unset_$" ? this.messages.missingMessage :
152                                 !this.missingMessage ? invalid : this.missingMessage;
153                         return (this.required && this._isEmpty(this.textbox.value)) ? missing : invalid; // String
154                 },
155
156                 getPromptMessage: function(/*Boolean*/ /*===== isFocused =====*/){
157                         // summary:
158                         //              Return a hint message to show when widget is first focused
159                         // tags:
160                         //              protected
161                         return this.promptMessage; // String
162                 },
163
164                 _maskValidSubsetError: true,
165                 validate: function(/*Boolean*/ isFocused){
166                         // summary:
167                         //              Called by oninit, onblur, and onkeypress.
168                         // description:
169                         //              Show missing or invalid messages if appropriate, and highlight textbox field.
170                         // tags:
171                         //              protected
172                         var message = "";
173                         var isValid = this.disabled || this.isValid(isFocused);
174                         if(isValid){ this._maskValidSubsetError = true; }
175                         var isEmpty = this._isEmpty(this.textbox.value);
176                         var isValidSubset = !isValid && isFocused && this._isValidSubset();
177                         this._set("state", isValid ? "" : (((((!this._hasBeenBlurred || isFocused) && isEmpty) || isValidSubset) && (this._maskValidSubsetError || (isValidSubset && !this._hasBeenBlurred && isFocused))) ? "Incomplete" : "Error"));
178                         this.focusNode.setAttribute("aria-invalid", isValid ? "false" : "true");
179
180                         if(this.state == "Error"){
181                                 this._maskValidSubsetError = isFocused && isValidSubset; // we want the error to show up after a blur and refocus
182                                 message = this.getErrorMessage(isFocused);
183                         }else if(this.state == "Incomplete"){
184                                 message = this.getPromptMessage(isFocused); // show the prompt whenever the value is not yet complete
185                                 this._maskValidSubsetError = !this._hasBeenBlurred || isFocused; // no Incomplete warnings while focused
186                         }else if(isEmpty){
187                                 message = this.getPromptMessage(isFocused); // show the prompt whenever there's no error and no text
188                         }
189                         this.set("message", message);
190
191                         return isValid;
192                 },
193
194                 displayMessage: function(/*String*/ message){
195                         // summary:
196                         //              Overridable method to display validation errors/hints.
197                         //              By default uses a tooltip.
198                         // tags:
199                         //              extension
200                         if(message && this.focused){
201                                 Tooltip.show(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
202                         }else{
203                                 Tooltip.hide(this.domNode);
204                         }
205                 },
206
207                 _refreshState: function(){
208                         // Overrides TextBox._refreshState()
209                         if(this._created){
210                                 this.validate(this.focused);
211                         }
212                         this.inherited(arguments);
213                 },
214
215                 //////////// INITIALIZATION METHODS ///////////////////////////////////////
216
217                 constructor: function(params /*===== , srcNodeRef =====*/){
218                         // summary:
219                         //              Create the widget.
220                         // params: Object|null
221                         //              Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
222                         //              and functions, typically callbacks like onClick.
223                         //              The hash can contain any of the widget's properties, excluding read-only properties.
224                         // srcNodeRef: DOMNode|String?
225                         //              If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree.
226
227                         this.constraints = {};
228                         this.baseClass += ' dijitValidationTextBox';
229                 },
230
231                 startup: function(){
232                         this.inherited(arguments);
233                         this._refreshState(); // after all _set* methods have run
234                 },
235
236                 _setConstraintsAttr: function(/*__Constraints*/ constraints){
237                         if(!constraints.locale && this.lang){
238                                 constraints.locale = this.lang;
239                         }
240                         this._set("constraints", constraints);
241                         this._refreshState();
242                 },
243
244                 _setPatternAttr: function(/*String|Function*/ pattern){
245                         this._set("pattern", pattern); // don't set on INPUT to avoid native HTML5 validation
246                 },
247
248                 _getPatternAttr: function(/*__Constraints*/ constraints){
249                         // summary:
250                         //              Hook to get the current regExp and to compute the partial validation RE.
251                         var p = this.pattern;
252                         var type = (typeof p).toLowerCase();
253                         if(type == "function"){
254                                 p = this.pattern(constraints || this.constraints);
255                         }
256                         if(p != this._lastRegExp){
257                                 var partialre = "";
258                                 this._lastRegExp = p;
259                                 // parse the regexp and produce a new regexp that matches valid subsets
260                                 // if the regexp is .* then there's no use in matching subsets since everything is valid
261                                 if(p != ".*"){
262                                         p.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,
263                                         function(re){
264                                                 switch(re.charAt(0)){
265                                                         case '{':
266                                                         case '+':
267                                                         case '?':
268                                                         case '*':
269                                                         case '^':
270                                                         case '$':
271                                                         case '|':
272                                                         case '(':
273                                                                 partialre += re;
274                                                                 break;
275                                                         case ")":
276                                                                 partialre += "|$)";
277                                                                 break;
278                                                          default:
279                                                                 partialre += "(?:"+re+"|$)";
280                                                                 break;
281                                                 }
282                                         });
283                                 }
284                                 try{ // this is needed for now since the above regexp parsing needs more test verification
285                                         "".search(partialre);
286                                 }catch(e){ // should never be here unless the original RE is bad or the parsing is bad
287                                         partialre = this.pattern;
288                                         console.warn('RegExp error in ' + this.declaredClass + ': ' + this.pattern);
289                                 } // should never be here unless the original RE is bad or the parsing is bad
290                                 this._partialre = "^(?:" + partialre + ")$";
291                         }
292                         return p;
293                 },
294
295                 postMixInProperties: function(){
296                         this.inherited(arguments);
297                         this.messages = i18n.getLocalization("dijit.form", "validate", this.lang);
298                         this._setConstraintsAttr(this.constraints); // this needs to happen now (and later) due to codependency on _set*Attr calls attachPoints
299                 },
300
301                 _setDisabledAttr: function(/*Boolean*/ value){
302                         this.inherited(arguments);      // call FormValueWidget._setDisabledAttr()
303                         this._refreshState();
304                 },
305
306                 _setRequiredAttr: function(/*Boolean*/ value){
307                         this._set("required", value);
308                         this.focusNode.setAttribute("aria-required", value);
309                         this._refreshState();
310                 },
311
312                 _setMessageAttr: function(/*String*/ message){
313                         this._set("message", message);
314                         this.displayMessage(message);
315                 },
316
317                 reset:function(){
318                         // Overrides dijit/form/TextBox.reset() by also
319                         // hiding errors about partial matches
320                         this._maskValidSubsetError = true;
321                         this.inherited(arguments);
322                 },
323
324                 _onBlur: function(){
325                         // the message still exists but for back-compat, and to erase the tooltip
326                         // (if the message is being displayed as a tooltip), call displayMessage('')
327                         this.displayMessage('');
328
329                         this.inherited(arguments);
330                 }
331         });
332 });