Type.registerNamespace('Sys.Extended.UI');
Sys.Extended.UI.NumericUpDownBehavior = function(element) {
// The NumericUpDownBehavior is used add up/down buttons to any textbox
// "element" - DOM Element the behavior is associated with
Sys.Extended.UI.NumericUpDownBehavior.initializeBase(this, [element]);
// Properties
this._currentValue = null;
this._widthValue = null;
this._targetButtonUpIDValue = null;
this._targetButtonDownIDValue = null;
this._serviceUpPathValue = location.pathname;
this._serviceUpMethodValue = null;
this._serviceDownPathValue = location.pathname;
this._serviceDownMethodValue = null;
this._refValuesValue = null;
this._tagValue = null;
this._elementTextBox = null;
this._step = 1.0;
this._min = -Number.MAX_VALUE;
this._max = Number.MAX_VALUE;
// Variables
this._bUp = null;
this._bDown = null;
this._stepPrecision = 0;
this._valuePrecision = 0;
// Delegates
this._clickUpHandler = null;
this._clickDownHandler = null;
this._changeHandler = null;
}
Sys.Extended.UI.NumericUpDownBehavior.prototype = {
initialize: function() {
Sys.Extended.UI.NumericUpDownBehavior.callBaseMethod(this, 'initialize');
$common.prepareHiddenElementForATDeviceUpdate();
var e = this.get_element();
this._elementTextBox = e;
if((this._refValuesValue) || (this._serviceUpMethodValue) || (this._serviceDownMethodValue))
this._elementTextBox.readOnly = true;
else
this._elementTextBox.readOnly = false;
// Init TextBox
this.readValue();
// Add Event
this._changeHandler = Function.createDelegate(this, this._onChange);
$addHandler(e, 'blur', this._changeHandler);
// If no button design for include them
if(!this._targetButtonUpIDValue || !this._targetButtonDownIDValue) {
// Change Style TextBox
this._widthValue = Math.max(this._widthValue, 24);
e.style.width = (this._widthValue - 24) + 'px';
e.style.textAlign = 'center';
// Create a new parent for TextBox
var _divContent = document.createElement('DIV');
_divContent.style.position = 'relative';
_divContent.style.width = this._widthValue + 'px';
_divContent.style.fontSize = e.clientHeight + 'px';
_divContent.style.height = e.clientHeight + 'px';
_divContent.style.paddingRight = '24px';
if(!(Sys.Browser.agent == Sys.Browser.Firefox || Sys.Browser.agent == Sys.Browser.Safari))
_divContent.style.display = 'inline';
else
_divContent.style.display = 'inline-block';
e.parentNode.insertBefore(_divContent, e);
var _innerTable = document.createElement('TABLE'),
_innerTbody = document.createElement('TBODY'),
_innerRow1 = document.createElement('TR'),
_innerRow2 = document.createElement('TR'),
_textboxCell = document.createElement('TD'),
_upButtonCell = document.createElement('TD'),
_downButtonCell = document.createElement('TD');
_textboxCell.rowSpan = '2';
_textboxCell.style.verticalAlign = 'middle';
_upButtonCell.style.verticalAlign = 'bottom';
_upButtonCell.style.lineHeight = '0';
_downButtonCell.style.verticalAlign = 'top';
_downButtonCell.style.lineHeight = '0';
_innerRow1.appendChild(_textboxCell);
_innerRow1.appendChild(_upButtonCell);
_innerRow2.appendChild(_downButtonCell);
_innerTbody.appendChild(_innerRow1);
_innerTbody.appendChild(_innerRow2);
_innerTable.appendChild(_innerTbody);
_divContent.appendChild(_innerTable);
e.parentNode.removeChild(e);
_textboxCell.appendChild(e);
_innerTable.style.borderCollapse = 'collapse';
_innerTable.className += "ajax__numericupdown_container";
_innerTable.style.display = 'inline';
_innerTable.style.position = 'relative';
_textboxCell.style.padding = '0';
_upButtonCell.style.padding = '0';
_downButtonCell.style.padding = '0';
_textboxCell.style.margin = '0';
_upButtonCell.style.margin = '0';
_downButtonCell.style.margin = '0';
}
// If no Up button create it
if(!this._targetButtonUpIDValue) {
this._bUp = document.createElement('input');
this._bUp.type = 'button';
this._bUp.id = e.id + '_bUp';
this._bUp.style.border = 'outset 1px';
if(Sys.Browser.agent == Sys.Browser.InternetExplorer) {
this._bUp.style.fontFamily = 'Webdings';
this._bUp.style.fontSize = '9pt';
this._bUp.value = '5';
} else {
this._bUp.style.fontFamily = 'Tahoma, Arial, sans-serif';
this._bUp.style.fontSize = '5pt';
this._bUp.value = '\u25B2';
this._bUp.style.fontWeight = 'bold';
this._bUp.style.lineHeight = '3pt';
}
this._bUp.style.height = '12px';
this._bUp.style.width = '24px';
this._bUp.style.overflow = 'hidden';
this._bUp.style.margin = '0';
_upButtonCell.appendChild(this._bUp);
}
// If no Down button create it
if(!this._targetButtonDownIDValue) {
this._bDown = document.createElement('input');
this._bDown.type = 'button';
this._bDown.id = e.id + '_bDown';
this._bDown.style.border = 'outset 1px';
if(Sys.Browser.agent == Sys.Browser.InternetExplorer) {
this._bDown.value = '6';
this._bDown.style.fontFamily = 'Webdings';
this._bDown.style.fontSize = '9pt';
} else {
this._bDown.value = '\u25BC';
this._bDown.style.fontFamily = 'Tahoma, Arial, sans-serif';
this._bDown.style.fontSize = '5pt';
this._bDown.style.fontWeight = 'bold';
}
this._bDown.style.height = '12px';
this._bDown.style.width = '24px';
this._bDown.style.overflow = 'hidden';
this._bDown.style.margin = '0';
_downButtonCell.appendChild(this._bDown);
}
// Add button Up Down Event
if(this._bUp == null)
this._bUp = document.getElementById(this._targetButtonUpIDValue);
if(this._bUp) {
this._clickUpHandler = Function.createDelegate(this, this._clickUp);
$addHandler(this._bUp, 'click', this._clickUpHandler);
}
if(this._bDown == null)
this._bDown = document.getElementById(this._targetButtonDownIDValue);
if(this._bDown) {
this._clickDownHandler = Function.createDelegate(this, this._clickDown);
$addHandler(this._bDown, 'click', this._clickDownHandler);
}
},
dispose: function() {
if(this._changeHandler) {
$removeHandler(this.get_element(), 'blur', this._changeHandler);
this._changeHandler = null;
}
if(this._clickUpHandler)
if(this._bUp) {
$removeHandler(this._bUp, 'click', this._clickUpHandler);
this._clickUpHandler = null;
}
if(this._clickDownHandler)
if(this._bDown) {
$removeHandler(this._bDown, 'click', this._clickDownHandler);
this._clickDownHandler = null;
}
Sys.Extended.UI.NumericUpDownBehavior.callBaseMethod(this, 'dispose');
},
///
/// Fires when the current textbox value changes
///
///
///
add_currentChanged: function(handler) {
this.get_events().addHandler('currentChanged', handler);
},
remove_currentChanged: function(handler) {
this.get_events().removeHandler('currentChanged', handler);
},
raise_currentChanged: function(eventArgs) {
var handler = this.get_events().getHandler('currentChanged');
if(handler) {
if(!eventArgs)
eventArgs = Sys.EventArgs.Empty;
handler(this, eventArgs);
}
},
raiseCurrentChanged: function(eventArgs) {
Sys.Extended.Deprecated("raiseCurrentChanged(eventArgs)", "raise_currentChanged(eventArgs)");
this.raise_currentChanged(eventArgs);
},
_onChange: function() {
this.readValue();
if(this._refValuesValue) {
this.setCurrentToTextBox(this._refValuesValue[this._currentValue]);
if(this._elementTextBox)
this._elementTextBox.readOnly = true;
} else {
this.setCurrentToTextBox(this._currentValue);
if(this._elementTextBox)
// Make the textbox readonly if its results come from a webservice
this._elementTextBox.readOnly = this._serviceUpMethodValue || this._serviceDownMethodValue;
}
},
///
/// Reads a value of the associated textbox
///
///
readValue: function() {
// Parse value of textbox and this._currentValue to be that value.
// this._currentValue = this._min if some there is an exception
// when attempting to parse.
// Parse int or string element of RefValues
if(this._elementTextBox) {
var v = this._elementTextBox.value;
// if textbox empty this._currentValue = this._min
if(!this._refValuesValue) {
if(!v) {
this._currentValue = this._min;
} else {
try {
this._currentValue = parseFloat(v);
} catch(ex) {
this._currentValue = this._min;
}
}
if(isNaN(this._currentValue))
this._currentValue = this._min;
this.setCurrentToTextBox(this._currentValue);
this._valuePrecision = this._computePrecision(this._currentValue);
} else {
if(!v) {
this._currentValue = 0;
} else {
var find = 0;
for(var i = 0; i < this._refValuesValue.length; i++)
if(v.toLowerCase() == this._refValuesValue[i].toLowerCase())
find = i;
this._currentValue = find;
}
this.setCurrentToTextBox(this._refValuesValue[this._currentValue]);
}
}
},
///
/// Sets a value of the associated textbox
///
/// Value to set
///
setCurrentToTextBox: function(value) {
if(this._elementTextBox) {
this._elementTextBox.value = value;
this.raise_currentChanged(value);
if(document.createEvent) {
var onchangeEvent = document.createEvent('HTMLEvents');
onchangeEvent.initEvent('change', true, false);
this._elementTextBox.dispatchEvent(onchangeEvent);
} else if(document.createEventObject) {
this._elementTextBox.fireEvent('onchange');
}
}
},
_incrementValue: function(step) {
// Use toFixed/parseFloat to prevent quantization when incrementing
var tmp = parseFloat((this._currentValue + step).toFixed(Math.max(this._stepPrecision, this._valuePrecision)));
if(step > 0)
this._currentValue = Math.max(Math.min(tmp, this._max), this._min);
else
this._currentValue = Math.min(Math.max(tmp, this._min), this._max);
},
_computePrecision: function(value) {
// Compute the precision of the value by counting the number
// of digits in the fractional part of its string representation
// "value" - value
// returns fractional precision of the number
if(value == Number.Nan)
return 0;
// Call toString which does not localize, according to ECMA 262
var str = value.toString();
if(str) {
var fractionalPart = /\.(\d*)$/;
var matches = str.match(fractionalPart);
if(matches && matches.length == 2 && matches[1])
return matches[1].length;
}
return 0;
},
///
/// Combined size of the TextBox and Up/Down buttons. Minimum value 25
///
///
/// This property is not used if you provide custom buttons
///
/// get_width
/// set_width
///
get_width: function() {
return this._widthValue;
},
set_width: function(value) {
if(this._widthValue != value) {
this._widthValue = value;
this.raisePropertyChanged('width');
}
},
get_Width: function() {
Sys.Extended.Deprecated("get_Width()", "get_width()");
return this.get_width();
},
set_Width: function(value) {
Sys.Extended.Deprecated("set_Width(value)", "set_width(value)");
this.set_width(value);
},
///
/// Custom parameter to pass to the Web Service
///
/// get_tag
/// set_tag
///
get_tag: function() {
return this._tagValue;
},
set_tag: function(value) {
if(this._tagValue != value) {
this._tagValue = value;
this.raisePropertyChanged('tag');
}
},
get_Tag: function() {
Sys.Extended.Deprecated("get_Tag()", "get_tag()");
return this.get_tag();
},
set_Tag: function(value) {
Sys.Extended.Deprecated("set_Tag(value)", "set_tag(value)");
this.set_tag(value);
},
///
/// A reference to a custom Up button
///
/// get_targetButtonUpID
/// set_targetButtonUpID
///
get_targetButtonUpID: function() {
return this._targetButtonUpIDValue;
},
set_targetButtonUpID: function(value) {
if(this._targetButtonUpIDValue != value) {
this._targetButtonUpIDValue = value;
this.raisePropertyChanged('targetButtonUpID');
}
},
get_TargetButtonUpID: function() {
Sys.Extended.Deprecated("get_TargetButtonUpID()", "get_targetButtonUpID()");
return this.get_targetButtonUpID();
},
set_TargetButtonUpID: function(value) {
Sys.Extended.Deprecated("set_TargetButtonUpID(value)", "set_targetButtonUpID(value)");
this.set_targetButtonUpID(value);
},
///
/// A reference to a custom Down button
///
/// get_targetButtonDownID
/// set_targetButtonDownID
///
get_targetButtonDownID: function() {
return this._targetButtonDownIDValue;
},
set_targetButtonDownID: function(value) {
if(this._targetButtonDownIDValue != value) {
this._targetButtonDownIDValue = value;
this.raisePropertyChanged('targetButtonDownID');
}
},
get_TargetButtonDownID: function() {
Sys.Extended.Deprecated("get_TargetButtonDownID()", "get_targetButtonDownID()");
return this.get_targetButtonDownID();
},
set_TargetButtonDownID: function(value) {
Sys.Extended.Deprecated("set_TargetButtonDownID(value)", "set_targetButtonDownID(value)");
this.set_targetButtonDownID(value);
},
///
/// A path to a web service that returns data used to get the next value
///
///
/// If the ServiceUpPath property is empty, the PageMethod will be used instead of the Web service
///
/// get_serviceUpPath
/// set_serviceUpPath
///
get_serviceUpPath: function() {
return this._serviceUpPathValue;
},
set_serviceUpPath: function(value) {
if(this._serviceUpPathValue != value) {
this._serviceUpPathValue = value;
this.raisePropertyChanged('serviceUpPath');
}
},
get_ServiceUpPath: function() {
Sys.Extended.Deprecated("get_ServiceUpPath()", "get_serviceUpPath()");
return this.get_serviceUpPath();
},
set_ServiceUpPath: function(value) {
Sys.Extended.Deprecated("set_ServiceUpPath(value)", "set_serviceUpPath(value)");
this.set_serviceUpPath(value);
},
///
/// A name of the method to call on the Web service (or the name of the PageMethod) to get the next value
///
/// get_serviceUpMethod
/// set_serviceUpMethod
///
get_serviceUpMethod: function() {
return this._serviceUpMethodValue;
},
set_serviceUpMethod: function(value) {
if(this._serviceUpMethodValue != value) {
this._serviceUpMethodValue = value;
this.raisePropertyChanged('serviceUpMethod');
if(this._elementTextBox)
this._elementTextBox.readOnly = true;
}
},
get_ServiceUpMethod: function() {
Sys.Extended.Deprecated("get_ServiceUpMethod()", "get_serviceUpMethod()");
return this.get_serviceUpMethod();
},
set_ServiceUpMethod: function(value) {
Sys.Extended.Deprecated("set_ServiceUpMethod(value)", "set_serviceUpMethod(value)");
this.set_serviceUpMethod(value);
},
///
/// A path to a Web service that returns data used to get the previous value
///
///
/// If the ServiceDownPath property is empty, the PageMethod will be used instead of the Web service
///
/// get_serviceDownPath
/// set_serviceDownPath
///
get_serviceDownPath: function() {
return this._serviceDownPathValue;
},
set_serviceDownPath: function(value) {
if(this._serviceDownPathValue != value) {
this._serviceDownPathValue = value;
this.raisePropertyChanged('serviceDownPath');
}
},
get_ServiceDownPath: function() {
Sys.Extended.Deprecated("get_ServiceDownPath()", "get_serviceDownPath()");
return this.get_serviceDownPath();
},
set_ServiceDownPath: function(value) {
Sys.Extended.Deprecated("set_ServiceDownPath(value)", "set_serviceDownPath(value)");
this.set_serviceDownPath(value);
},
///
/// A name of the method to call on the Web service (or the name of the PageMethod) to get the previous value
///
/// get_serviceDownMethod
/// set_serviceDownMethod
///
get_serviceDownMethod: function() {
return this._serviceDownMethodValue;
},
set_serviceDownMethod: function(value) {
if(this._serviceDownMethodValue != value) {
this._serviceDownMethodValue = value;
this.raisePropertyChanged('serviceDownMethod');
if(this._elementTextBox)
this._elementTextBox.readOnly = true;
}
},
get_ServiceDownMethod: function() {
Sys.Extended.Deprecated("get_ServiceDownMethod()", "get_serviceDownMethod()");
return this.get_serviceDownMethod();
},
set_ServiceDownMethod: function(value) {
Sys.Extended.Deprecated("set_ServiceDownMethod(value)", "set_serviceDownMethod(value)");
this.set_serviceDownMethod(value);
},
///
/// A list of strings separated by semicolons (;) to be used as an enumeration by NumericUpDown
///
/// get_refValues
/// set_refValues
///
get_refValues: function() {
return this._refValuesValue ? this._refValuesValue.join(";") : "";
},
set_refValues: function(value) {
if(value != '') {
this._refValuesValue = value.split(';');
this._onChange();
if(this._elementTextBox)
this._elementTextBox.readOnly = true;
} else {
this._refValuesValue = null;
if(this._elementTextBox)
this._elementTextBox.readOnly = false;
}
this.raisePropertyChanged('refValues');
},
get_RefValues: function() {
Sys.Extended.Deprecated("get_RefValues()", "get_refValues()");
return this.get_refValues();
},
set_RefValues: function(value) {
Sys.Extended.Deprecated("set_RefValues(value)", "set_refValues(value)");
this.set_refValues(value);
},
///
/// A step used for simple numeric incrementing and decrementing. The default value is 1
///
/// get_step
/// set_step
///
get_step: function() {
return this._step;
},
set_step: function(value) {
if(value != this._step) {
this._step = value;
this._stepPrecision = this._computePrecision(value);
this.raisePropertyChanged('step');
}
},
get_Step: function() {
Sys.Extended.Deprecated("get_Step()", "get_step()");
return this.get_step();
},
set_Step: function(value) {
Sys.Extended.Deprecated("set_Step(value)", "set_step(value)");
this.set_step(value);
},
///
/// The minimum value allowed by the extender
///
///
/// Currently, it does not prevent out of range values from being entered into the textbox
/// even if Minimum or Maximum are specified on the extender, but using the up/down buttons
/// should bring the value into the allowed range when clicked
///
/// get_minimum
/// set_minimum
///
get_minimum: function() {
return this._min;
},
set_minimum: function(value) {
if(value != this._min) {
this._min = value;
this.raisePropertyChanged('minimum');
}
},
get_Minimum: function() {
Sys.Extended.Deprecated("get_Minimum()", "get_minimum()");
return this.get_minimum();
},
set_Minimum: function(value) {
Sys.Extended.Deprecated("set_Minimum(value)", "set_minimum(value)");
this.set_minimum(value);
},
///
/// The maximum value allowed by the extender
///
/// get_maximum
/// set_maximum
///
get_maximum: function() {
return this._max;
},
set_maximum: function(value) {
if(value != this._max) {
this._max = value;
this.raisePropertyChanged('maximum');
}
},
get_Maximum: function() {
Sys.Extended.Deprecated("get_Maximum()", "get_maximum()");
return this.get_maximum();
},
set_Maximum: function(value) {
Sys.Extended.Deprecated("set_Maximum(value)", "set_maximum(value)");
this.set_maximum(value);
},
_clickUp: function(evt) {
// Handler for the Up button's click event
// "evt" - event info
this.readValue();
// Proxy WebService
if(this._serviceUpPathValue && this._serviceUpMethodValue) {
// Call the helper web service
Sys.Net.WebServiceProxy.invoke(this._serviceUpPathValue, this._serviceUpMethodValue, false,
{ current: this._currentValue, tag: this._tagValue },
Function.createDelegate(this, this._onMethodUpDownComplete));
$common.updateFormToRefreshATDeviceBuffer();
} else {
// Else increment one element on _refValues or juste this._currentValue++
if(this._refValuesValue) {
if((this._currentValue + 1) < this._refValuesValue.length) {
this._currentValue = this._currentValue + 1;
this.setCurrentToTextBox(this._refValuesValue[this._currentValue]);
}
} else {
this._incrementValue(this._step);
this.setCurrentToTextBox(this._currentValue);
}
}
if(evt)
evt.preventDefault();
return false;
},
_clickDown: function(evt) {
this.readValue();
// Proxy WebService
if(this._serviceDownPathValue && this._serviceDownMethodValue) {
// Call the helper web service
Sys.Net.WebServiceProxy.invoke(this._serviceDownPathValue, this._serviceDownMethodValue, false,
{ current: this._currentValue, tag: this._tagValue },
Function.createDelegate(this, this._onMethodUpDownComplete));
$common.updateFormToRefreshATDeviceBuffer();
} else {
// Else decrement one element on _refValues or juste this._currentValue--
if(this._refValuesValue) {
if((this._currentValue - 1) >= 0) {
this._currentValue = this._currentValue - 1;
this.setCurrentToTextBox(this._refValuesValue[this._currentValue]);
}
} else {
this._incrementValue(-this._step);
this.setCurrentToTextBox(this._currentValue);
}
}
if(evt)
evt.preventDefault();
return false;
},
// Call BackWebServices
_onMethodUpDownComplete: function(result, userContext, methodName) {
this._currentValue = result;
this.setCurrentToTextBox(this._currentValue);
}
}
Sys.Extended.UI.NumericUpDownBehavior.registerClass('Sys.Extended.UI.NumericUpDownBehavior', Sys.Extended.UI.BehaviorBase);