1 if(!dojo._hasResource["dijit.form.ValidationTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dijit.form.ValidationTextBox"] = true;
3 dojo.provide("dijit.form.ValidationTextBox");
5 dojo.require("dojo.i18n");
7 dojo.require("dijit.form.TextBox");
8 dojo.require("dijit.Tooltip");
10 dojo.requireLocalization("dijit.form", "validate", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,pt-pt,ROOT,cs,fr,es,ko,nl,zh-tw,pl,it,hu");
13 dijit.form.ValidationTextBox.__Constraints = function(){
15 // locale used for validation, picks up value from this widget's lang attribute
17 // various flags passed to regExpGen function
24 "dijit.form.ValidationTextBox",
28 // A TextBox subclass with the ability to validate content of various types and provide user feedback.
30 templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\t\t><input class=\"dijitReset\" dojoAttachPoint='textbox,focusNode' dojoAttachEvent='onfocus:_update,onkeyup:_onkeyup,onblur:_onMouse,onkeypress:_onKeyPress' autocomplete=\"off\"\n\t\t\ttype='${type}' name='${name}'\n\t\t/></div\n\t></div\n></div>\n",
31 baseClass: "dijitTextBox",
33 // default values for new subclass properties
35 // Can be true or false, default is false.
38 // promptMessage: String
42 // invalidMessage: String
43 // The message to display if value is invalid.
44 invalidMessage: "$_unset_$", // read from the message file if not overridden
46 // constraints: dijit.form.ValidationTextBox.__Constraints
47 // user-defined object needed to pass parameters to the validator functions
51 // regular expression string used to validate the input
52 // Do not specify both regExp and regExpGen
55 // regExpGen: Function
56 // user replaceable function used to generate regExp when dependent on constraints
57 // Do not specify both regExp and regExpGen
58 regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/constraints){ return this.regExp; },
61 // Shows current state (ie, validation result) of input (Normal, Warning, or Error)
64 // tooltipPosition: String[]
65 // See description of dijit.Tooltip.defaultPosition for details on this parameter.
69 this.inherited(arguments);
70 this.validate(this._focused);
73 validator: function(/*anything*/value, /*dijit.form.ValidationTextBox.__Constraints*/constraints){
74 // summary: user replaceable function used to validate the text input against the regular expression.
75 return (new RegExp("^(" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
76 (!this.required || !this._isEmpty(value)) &&
77 (this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean
80 isValid: function(/*Boolean*/ isFocused){
81 // summary: Need to over-ride with your own validation code in subclasses
82 return this.validator(this.textbox.value, this.constraints);
85 _isEmpty: function(value){
86 // summary: Checks for whitespace
87 return /^\s*$/.test(value); // Boolean
90 getErrorMessage: function(/*Boolean*/ isFocused){
91 // summary: return an error message to show if appropriate
92 return this.invalidMessage; // String
95 getPromptMessage: function(/*Boolean*/ isFocused){
96 // summary: return a hint to show if appropriate
97 return this.promptMessage; // String
100 validate: function(/*Boolean*/ isFocused){
102 // Called by oninit, onblur, and onkeypress.
104 // Show missing or invalid messages if appropriate, and highlight textbox field.
106 var isValid = this.isValid(isFocused);
107 var isEmpty = this._isEmpty(this.textbox.value);
108 this.state = (isValid || (!this._hasBeenBlurred && isEmpty)) ? "" : "Error";
109 this._setStateClass();
110 dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
113 message = this.getPromptMessage(true);
115 if(!message && this.state == "Error"){
116 message = this.getErrorMessage(true);
119 this.displayMessage(message);
123 // currently displayed message
126 displayMessage: function(/*String*/ message){
128 // User overridable method to display validation errors/hints.
129 // By default uses a tooltip.
130 if(this._message == message){ return; }
131 this._message = message;
132 dijit.hideTooltip(this.domNode);
134 dijit.showTooltip(message, this.domNode, this.tooltipPosition);
138 _refreshState: function(){
139 this.validate(this._focused);
142 _update: function(/*Event*/e){
143 this._refreshState();
144 this._onMouse(e); // update CSS classes
147 _onkeyup: function(/*Event*/e){
152 //////////// INITIALIZATION METHODS ///////////////////////////////////////
154 constructor: function(){
155 this.constraints = {};
158 postMixInProperties: function(){
159 this.inherited(arguments);
160 this.constraints.locale = this.lang;
161 this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
162 if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; }
163 var p = this.regExpGen(this.constraints);
170 "dijit.form.MappedTextBox",
171 dijit.form.ValidationTextBox,
174 // A dijit.form.ValidationTextBox subclass which provides a visible formatted display and a serializable
175 // value in a hidden input field which is actually sent to the server. The visible display may
176 // be locale-dependent and interactive. The value sent to the server is stored in a hidden
177 // input field which uses the `name` attribute declared by the original widget. That value sent
178 // to the serveris defined by the dijit.form.MappedTextBox.serialize method and is typically
181 serialize: function(/*anything*/val, /*Object?*/options){
182 // summary: user replaceable function used to convert the getValue() result to a String
183 return val.toString ? val.toString() : ""; // String
186 toString: function(){
187 // summary: display the widget as a printable string using the widget's value
188 var val = this.filter(this.getValue());
189 return val != null ? (typeof val == "string" ? val : this.serialize(val, this.constraints)) : ""; // String
192 validate: function(){
193 this.valueNode.value = this.toString();
194 return this.inherited(arguments);
197 setAttribute: function(/*String*/ attr, /*anything*/ value){
198 this.inherited(arguments);
202 this.valueNode.disabled = this.disabled;
207 postCreate: function(){
208 var textbox = this.textbox;
209 var valueNode = (this.valueNode = dojo.doc.createElement("input"));
210 valueNode.setAttribute("type", textbox.type);
211 valueNode.setAttribute("value", this.toString());
212 dojo.style(valueNode, "display", "none");
213 valueNode.name = this.textbox.name;
214 valueNode.disabled = this.textbox.disabled;
215 this.textbox.name = this.textbox.name + "_displayed_";
216 this.textbox.removeAttribute("name");
217 dojo.place(valueNode, textbox, "after");
219 this.inherited(arguments);
225 dijit.form.RangeBoundTextBox.__Constraints = function(){
227 // Minimum signed value. Default is -Infinity
229 // Maximum signed value. Default is +Infinity
236 "dijit.form.RangeBoundTextBox",
237 dijit.form.MappedTextBox,
240 // A dijit.form.MappedTextBox subclass which defines a range of valid values
242 // constraints: dijit.form.RangeBoundTextBox.__Constraints
244 // rangeMessage: String
245 // The message to display if value is out-of-range
252 compare: function(/*anything*/val1, /*anything*/val2){
253 // summary: compare 2 values
254 return val1 - val2; // anything
257 rangeCheck: function(/*Number*/ primitive, /*dijit.form.RangeBoundTextBox.__Constraints*/ constraints){
258 // summary: user replaceable function used to validate the range of the numeric input value
259 var isMin = "min" in constraints;
260 var isMax = "max" in constraints;
262 return (!isMin || this.compare(primitive,constraints.min) >= 0) &&
263 (!isMax || this.compare(primitive,constraints.max) <= 0);
265 return true; // Boolean
268 isInRange: function(/*Boolean*/ isFocused){
269 // summary: Need to over-ride with your own validation code in subclasses
270 return this.rangeCheck(this.getValue(), this.constraints);
273 isValid: function(/*Boolean*/ isFocused){
274 return this.inherited(arguments) &&
275 ((this._isEmpty(this.textbox.value) && !this.required) || this.isInRange(isFocused)); // Boolean
278 getErrorMessage: function(/*Boolean*/ isFocused){
279 if(dijit.form.RangeBoundTextBox.superclass.isValid.call(this, false) && !this.isInRange(isFocused)){ return this.rangeMessage; } // String
280 return this.inherited(arguments);
283 postMixInProperties: function(){
284 this.inherited(arguments);
285 if(!this.rangeMessage){
286 this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang);
287 this.rangeMessage = this.messages.rangeMessage;
291 postCreate: function(){
292 this.inherited(arguments);
293 if(this.constraints.min !== undefined){
294 dijit.setWaiState(this.focusNode, "valuemin", this.constraints.min);
296 if(this.constraints.max !== undefined){
297 dijit.setWaiState(this.focusNode, "valuemax", this.constraints.max);
301 setValue: function(/*Number*/ value, /*Boolean?*/ priorityChange){
302 dijit.setWaiState(this.focusNode, "valuenow", value);
303 this.inherited('setValue', arguments);