Friday, November 14, 2008

Creating an UpDown Control

The updown control is merely a control that enables the user to select a number from a predefined range either by direct assignment or by using up and down selectors (arrows). This is usually very useful when the changing of the number has an immediate affect of some sort on the form where it’s placed. This is just a UI enhancement that should be used only where appropriate.

The idea behind the mechanics of the updown control is that it uses a span with an overflow-y: scroll. The span has an inner span which is set to hidden but its height is set to the updown max value. This hack actually creates the range for you. When the user scrolls down the scrollTop attribute reflects the current position (selected number) which is written back to the text field. An opposite approach is used when the users assigns a value directly, then the span scrollTop is updated with the current field datavalue.





/*
parameters: fieldId - crm field id
minValue - positive number
maxValue - positive number
*/
function UpDownControl( fieldId , minValue , maxValue )
{
var Instance = this;
/* crm field */
var upDownCtrlBox = crmForm.all[ fieldId ];
/* field parent element field_d */
var parent = upDownCtrlBox.parentElement;
/* this span affects the spanUpDown scroll */
var span = document.createElement( "<SPAN style='visibility:hidden;width:1;'>" );
var spanUpDownHeight = upDownCtrlBox.clientHeight - 2;
/* this span is the scroller */
var spanUpDown = document.createElement( "<SPAN style='margin-left:-18px;overflow-y:scroll;width:1;height:" + spanUpDownHeight + ";'>" );
/* max range */
Instance.Max = maxValue;
/* min range */
Instance.Min = minValue;
/* fires when the scroll is pressed */
function onScrollChange()
{
/* get the current scroll position */
var scrollTop = parseInt( spanUpDown.scrollTop );
/* adjust size if value is outside of the scroll limits */
if( scrollTop < Instance.Min ){
scrollTop = Instance.Min;
spanUpDown.scrollTop = scrollTop;
}
else if( scrollTop > Instance.Max ){
scrollTop = Instance.Max;
spanUpDown.scrollTop = scrollTop;
}
/* assign the scroll value back to the field */
upDownCtrlBox.DataValue = scrollTop;
}
/* fires when the field value changes */
function onValueChange()
{
/* if the value is valid */
if( upDownCtrlBox.DataValue != null )
{
/* get the value */
var dataValue = parseInt( upDownCtrlBox.DataValue );
/* check that the vlaue is within permitted limits */
if( dataValue < Instance.Min ){
dataValue = Instance.Min;
upDownCtrlBox.DataValue = dataValue;
return false;
}
else if( dataValue > Instance.Max ){
dataValue = Instance.Max;
upDownCtrlBox.DataValue = dataValue;
return false;
}
/* assign the field value back to the scroll */
spanUpDown.scrollTop = dataValue;
}
/* assign min value is the datavalue is null */
else spanUpDown.scrollTop = Instance.Min;
}

/* fire onValueChange when the field is changed */
upDownCtrlBox.attachEvent( "onchange" , onValueChange );
/* adjust inner span height = maxValue + spanHeight */
span.style.height = maxValue + spanUpDownHeight;
/* construct the updown control */
spanUpDown.appendChild( span );
/* fire onScrollChange when the user presses the scrollbar */
spanUpDown.attachEvent( "onscroll" , onScrollChange );
parent.appendChild( spanUpDown );
/* call onValueChange when the form loads / control is created */
onValueChange();
}

widthUpDownCtrl = new UpDownControl("gi_width" , 20 , 10000 );

No comments: