183 lines
6.2 KiB
JavaScript
183 lines
6.2 KiB
JavaScript
|
dojo.provide("dijit.form.NumberTextBox");
|
||
|
|
||
|
dojo.require("dijit.form.ValidationTextBox");
|
||
|
dojo.require("dojo.number");
|
||
|
|
||
|
/*=====
|
||
|
dojo.declare(
|
||
|
"dijit.form.NumberTextBox.__Constraints",
|
||
|
[dijit.form.RangeBoundTextBox.__Constraints, dojo.number.__FormatOptions, dojo.number.__ParseOptions]
|
||
|
);
|
||
|
=====*/
|
||
|
|
||
|
dojo.declare("dijit.form.NumberTextBoxMixin",
|
||
|
null,
|
||
|
{
|
||
|
// summary:
|
||
|
// A mixin for all number textboxes
|
||
|
// tags:
|
||
|
// protected
|
||
|
|
||
|
// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
|
||
|
// than a straight regexp to deal with locale (plus formatting options too?)
|
||
|
regExpGen: dojo.number.regexp,
|
||
|
|
||
|
/*=====
|
||
|
// constraints: dijit.form.NumberTextBox.__Constraints
|
||
|
// Minimum/maximum allowed values.
|
||
|
constraints: {},
|
||
|
======*/
|
||
|
|
||
|
// value: Number
|
||
|
// The value of this NumberTextBox as a javascript Number (ie, not a String).
|
||
|
// If the displayed value is blank, the value is NaN, and if the user types in
|
||
|
// an gibberish value (like "hello world"), the value is undefined
|
||
|
// (i.e. attr('value') returns undefined).
|
||
|
//
|
||
|
// Symetrically, attr('value', NaN) will clear the displayed value,
|
||
|
// whereas attr('value', undefined) will have no effect.
|
||
|
value: NaN,
|
||
|
|
||
|
// editOptions: [protected] Object
|
||
|
// Properties to mix into constraints when the value is being edited.
|
||
|
// This is here because we edit the number in the format "12345", which is
|
||
|
// different than the display value (ex: "12,345")
|
||
|
editOptions: { pattern: '#.######' },
|
||
|
|
||
|
/*=====
|
||
|
_formatter: function(value, options){
|
||
|
// summary:
|
||
|
// _formatter() is called by format(). It's the base routine for formatting a number,
|
||
|
// as a string, for example converting 12345 into "12,345".
|
||
|
// value: Number
|
||
|
// The number to be converted into a string.
|
||
|
// options: dojo.number.__FormatOptions?
|
||
|
// Formatting options
|
||
|
// tags:
|
||
|
// protected extension
|
||
|
|
||
|
return "12345"; // String
|
||
|
},
|
||
|
=====*/
|
||
|
_formatter: dojo.number.format,
|
||
|
|
||
|
postMixInProperties: function(){
|
||
|
if(typeof this.constraints.max != "number"){
|
||
|
this.constraints.max = 9e+15;
|
||
|
}
|
||
|
this.inherited(arguments);
|
||
|
},
|
||
|
|
||
|
_onFocus: function(){
|
||
|
if(this.disabled){ return; }
|
||
|
var val = this.attr('value');
|
||
|
if(typeof val == "number" && !isNaN(val)){
|
||
|
var formattedValue = this.format(val, this.constraints);
|
||
|
if(formattedValue !== undefined){
|
||
|
this.textbox.value = formattedValue;
|
||
|
}
|
||
|
}
|
||
|
this.inherited(arguments);
|
||
|
},
|
||
|
|
||
|
format: function(/*Number*/ value, /*dojo.number.__FormatOptions*/ constraints){
|
||
|
// summary:
|
||
|
// Formats the value as a Number, according to constraints.
|
||
|
// tags:
|
||
|
// protected
|
||
|
|
||
|
if(typeof value != "number") { return String(value) }
|
||
|
if(isNaN(value)){ return ""; }
|
||
|
if(("rangeCheck" in this) && !this.rangeCheck(value, constraints)){ return String(value) }
|
||
|
if(this.editOptions && this._focused){
|
||
|
constraints = dojo.mixin(dojo.mixin({}, this.editOptions), constraints);
|
||
|
}
|
||
|
return this._formatter(value, constraints);
|
||
|
},
|
||
|
|
||
|
/*=====
|
||
|
parse: function(value, constraints){
|
||
|
// summary:
|
||
|
// Parses the string value as a Number, according to constraints.
|
||
|
// value: String
|
||
|
// String representing a number
|
||
|
// constraints: dojo.number.__ParseOptions
|
||
|
// Formatting options
|
||
|
// tags:
|
||
|
// protected
|
||
|
|
||
|
return 123.45; // Number
|
||
|
},
|
||
|
=====*/
|
||
|
parse: dojo.number.parse,
|
||
|
|
||
|
_getDisplayedValueAttr: function(){
|
||
|
var v = this.inherited(arguments);
|
||
|
return isNaN(v) ? this.textbox.value : v;
|
||
|
},
|
||
|
|
||
|
filter: function(/*Number*/ value){
|
||
|
// summary:
|
||
|
// This is called with both the display value (string), and the actual value (a number).
|
||
|
// When called with the actual value it does corrections so that '' etc. are represented as NaN.
|
||
|
// Otherwise it dispatches to the superclass's filter() method.
|
||
|
//
|
||
|
// See `dijit.form.TextBox.filter` for more details.
|
||
|
return (value === null || value === '' || value === undefined) ? NaN : this.inherited(arguments); // attr('value', null||''||undefined) should fire onChange(NaN)
|
||
|
},
|
||
|
|
||
|
serialize: function(/*Number*/ value, /*Object?*/options){
|
||
|
// summary:
|
||
|
// Convert value (a Number) into a canonical string (ie, how the number literal is written in javascript/java/C/etc.)
|
||
|
// tags:
|
||
|
// protected
|
||
|
return (typeof value != "number" || isNaN(value))? '' : this.inherited(arguments);
|
||
|
},
|
||
|
|
||
|
_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange, /*String?*/formattedValue){
|
||
|
// summary:
|
||
|
// Hook so attr('value', ...) works.
|
||
|
if(value !== undefined && formattedValue === undefined){
|
||
|
if(typeof value == "number"){
|
||
|
if(isNaN(value)){ formattedValue = '' }
|
||
|
else if(("rangeCheck" in this) && !this.rangeCheck(value, this.constraints)){
|
||
|
formattedValue = String(value);
|
||
|
}
|
||
|
}else if(!value){ // 0 processed in if branch above, ''|null|undefined flow thru here
|
||
|
formattedValue = '';
|
||
|
value = NaN;
|
||
|
}else{ // non-numeric values
|
||
|
formattedValue = String(value);
|
||
|
value = undefined;
|
||
|
}
|
||
|
}
|
||
|
this.inherited(arguments, [value, priorityChange, formattedValue]);
|
||
|
},
|
||
|
|
||
|
|
||
|
_getValueAttr: function(){
|
||
|
// summary:
|
||
|
// Hook so attr('value') works.
|
||
|
// Returns Number, NaN for '', or undefined for unparsable text
|
||
|
var v = this.inherited(arguments); // returns Number for all values accepted by parse() or NaN for all other displayed values
|
||
|
|
||
|
// If the displayed value of the textbox is gibberish (ex: "hello world"), this.inherited() above
|
||
|
// returns NaN; this if() branch converts the return value to undefined.
|
||
|
// Returning undefined prevents user text from being overwritten when doing _setValueAttr(_getValueAttr()).
|
||
|
// A blank displayed value is still returned as NaN.
|
||
|
if(isNaN(v) && this.textbox.value !== ''){ // if displayed value other than ''
|
||
|
var n = Number(this.textbox.value); // check for exponential notation that parse() rejected (erroneously?)
|
||
|
return (String(n)===this.textbox.value)? n : undefined; // return exponential Number or undefined for random text
|
||
|
}else{ return v } // Number or NaN for ''
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
|
||
|
dojo.declare("dijit.form.NumberTextBox",
|
||
|
[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin],
|
||
|
{
|
||
|
// summary:
|
||
|
// A validating, serializable, range-bound text box.
|
||
|
}
|
||
|
);
|