Ibrahim Imam
Top achievements
Rank 1
Ibrahim Imam
asked on 30 Nov 2010, 10:16 AM
hello
i am using the radnumeric textbox with spin buttons and dynamic Increment Steps depending on previous user input.
during testing i discovered the following wrong behaviour:
Value of the Textbox set on server: 50
Increment Step: 0.127
after clicking 3 times (numbers vary) the value in the textbox is wrong because it decrements by 0.128.
so it shows the value 49.618 (=50-(2*0.127)-0.128) instead of 49.619 (=50-(3*0.127))
this seems to occur for prime numbers after 0. for example 0.127 or 0.05
when the user then sends the values my custom validations on the server reject the value.
i checked the javascript code for the textbox and as a temporary solution i set the "KeepNotRoundedValue" to true.
the value in the textbox is then wrong but sending and saving to server works. the value is then changed to the correct value.
this auto correct after sending will confuse some users so i need a clean solution.
another question regarding the spin button:
is it possible to customize the behaviour? in my use case i only allow specific values for example:
the value in the textbox is 98 and the step value is set to 5. valid values are 93,88, and so on.
if the user now enters 95 and then uses the decrement spin button it changes the value to 90 which is not allowed.
i would like to set the next valid number when using the spin button or better have some auto-rounding to the next valid number when the value is changed
i am using the radnumeric textbox with spin buttons and dynamic Increment Steps depending on previous user input.
during testing i discovered the following wrong behaviour:
Value of the Textbox set on server: 50
Increment Step: 0.127
after clicking 3 times (numbers vary) the value in the textbox is wrong because it decrements by 0.128.
so it shows the value 49.618 (=50-(2*0.127)-0.128) instead of 49.619 (=50-(3*0.127))
this seems to occur for prime numbers after 0. for example 0.127 or 0.05
when the user then sends the values my custom validations on the server reject the value.
i checked the javascript code for the textbox and as a temporary solution i set the "KeepNotRoundedValue" to true.
the value in the textbox is then wrong but sending and saving to server works. the value is then changed to the correct value.
this auto correct after sending will confuse some users so i need a clean solution.
another question regarding the spin button:
is it possible to customize the behaviour? in my use case i only allow specific values for example:
the value in the textbox is 98 and the step value is set to 5. valid values are 93,88, and so on.
if the user now enters 95 and then uses the decrement spin button it changes the value to 90 which is not allowed.
i would like to set the next valid number when using the spin button or better have some auto-rounding to the next valid number when the value is changed
6 Answers, 1 is accepted
0
Hi Ibrahim,
To achieve the desired functionality without using the KeepNotRoundedValue property you could try setting the NumberFormat.DecimalDigits property to 3:
On the following link I attached a small video which demonstrates how the RadNumericTextBox works on my end when the DecimalDigits is set to 3.
Regarding your second question:
You could handle the client side OnButtonClick event and check if the entered value is valid, if the user enters invalid value you could change it manually to one of the valid values for the RadNumericTextBox:
Please give it try and let me know if you experience any problems.
Greetings,
Radoslav
the Telerik team
To achieve the desired functionality without using the KeepNotRoundedValue property you could try setting the NumberFormat.DecimalDigits property to 3:
<
telerik:RadNumericTextBox
runat
=
"server"
ID
=
"RadNumericTextBox1"
ShowSpinButtons
=
"true"
>
<
IncrementSettings
Step
=
"0.127"
/>
<
NumberFormat
DecimalDigits
=
"3"
/>
</
telerik:RadNumericTextBox
>
On the following link I attached a small video which demonstrates how the RadNumericTextBox works on my end when the DecimalDigits is set to 3.
Regarding your second question:
You could handle the client side OnButtonClick event and check if the entered value is valid, if the user enters invalid value you could change it manually to one of the valid values for the RadNumericTextBox:
<
telerik:RadNumericTextBox
runat
=
"server"
ID
=
"RadNumericTextBox1"
ShowSpinButtons
=
"true"
>
<
IncrementSettings
Step
=
"0.127"
/>
<
NumberFormat
DecimalDigits
=
"3"
/>
<
ClientEvents
OnButtonClick
=
"ButtonClicked"
/>
</
telerik:RadNumericTextBox
>
<telerik:RadCodeBlock runat=
"server"
>
<script type=
"text/javascript"
>
function
ButtonClicked(sender, eventArgs)
{
var
numericTextBox = $find(
"<%=RadNumericTextBox1.ClientID %>"
);
var
enteredValue = numericTextBox.get_value();
if
(eventArgs._buttonType == 2)
{
// Spin Button up pressed
if
(!Validate(enteredValue))
{
// Change enteredValue to valid value for the RadNumericTextBox1
// For example if the enteredValue is 95, change it to next valid value - 98
}
}
else
{
// Spin Button down pressed
if
(!Validate(enteredValue))
{
// Change enteredValue to valid value for the RadNumericTextBox1
// For example if the enteredValue is 95, change it to next valid value - 93
}
}
}
function
Validate(enteredValue)
{
// Check if enteredValue is valid value
}
</script>
</telerik:RadCodeBlock>
Please give it try and let me know if you experience any problems.
Greetings,
Radoslav
the Telerik team
Browse the vast support resources we have to jumpstart your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
0
Ibrahim Imam
Top achievements
Rank 1
answered on 06 Dec 2010, 12:27 PM
i create the columns at runtime and already set the decimal amount in the
void ux_ApplyGrid_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
event using:
((RadNumericTextBox)item["NewOffer"].Controls[0]).NumberFormat.DecimalDigits = BidData.BidTargetCategories[dataItem["PositionId"].ToString()].DecimalsAmount;
i tried to reduce the value a few times with the spin button and then clicked save.
i get the error message and the value inside the textbox was something like
59.000000000001
i will check the custom solution also
void ux_ApplyGrid_ItemCreated(object sender, Telerik.Web.UI.GridItemEventArgs e)
event using:
((RadNumericTextBox)item["NewOffer"].Controls[0]).NumberFormat.DecimalDigits = BidData.BidTargetCategories[dataItem["PositionId"].ToString()].DecimalsAmount;
i tried to reduce the value a few times with the spin button and then clicked save.
i get the error message and the value inside the textbox was something like
59.000000000001
i will check the custom solution also
0
Ibrahim Imam
Top achievements
Rank 1
answered on 06 Dec 2010, 05:57 PM
i now tried to implement my auto correction function based on your code snippet.
during debugging i found that the get_value() method returns the "old" value before the action of the spin button.
besides that after setting a value the spin action is performed so it subracts the value after setting it (in case i click spin button down)
another thing i noted during debugging:
also produces wrong values sometimes (for example 95.0000000002). i researched and it seems to be a javascript problem that incorrect numbers appear. i worked around this issue by using the following "rounding" calculation (as rounding is only possible to no decimals in JS):
var roundingprecision = 1000000; // rounding is exact up to 6 digits
var difference = Math.round((initialValue - enteredValue) * roundingprecision) / roundingprecision;
here is my current code. the find logic wouldn't have worked in my case as i create the buttons in code behind.
it works with the sender for me:
because of above mentioned problems i think the better solution is to handle the OnValueChanged event.
this will work for manual entries also which is ok in my scenario
here is my code which seems to work correctly so far:
the downside is the risk of an endless recursion if the calculation is wrong as the set_value method triggers the event again.
is there a way to not handle the event if i used the set_value() method?
during debugging i found that the get_value() method returns the "old" value before the action of the spin button.
besides that after setting a value the spin action is performed so it subracts the value after setting it (in case i click spin button down)
another thing i noted during debugging:
var
difference = initialValue - enteredValue;
also produces wrong values sometimes (for example 95.0000000002). i researched and it seems to be a javascript problem that incorrect numbers appear. i worked around this issue by using the following "rounding" calculation (as rounding is only possible to no decimals in JS):
var roundingprecision = 1000000; // rounding is exact up to 6 digits
var difference = Math.round((initialValue - enteredValue) * roundingprecision) / roundingprecision;
here is my current code. the find logic wouldn't have worked in my case as i create the buttons in code behind.
it works with the sender for me:
function
SpinButtonClicked(sender, eventArgs)
{
var
numericTextBox = sender;
var
enteredValue = numericTextBox.get_value();
// should be the new value after spin button action, currently wrong
var
initialValue = numericTextBox._originalValue;
// the value last received from the server
var
stepSize = numericTextBox._incrementSettings.Step;
var
difference = initialValue - enteredValue;
if
(difference < 0)
//make difference always a positive value
{
difference = difference * (-1);
}
var
errorDifference = difference % stepSize;
if
(errorDifference != 0)
// entered value not valid
{
if
(eventArgs
._buttonType == 2)
// Spin Button up pressed
{
numericTextBox.set_value(enteredValue + errorDifference);
// add the errorDifference to actual entered value -> auto round up to next valid value
}
else
// Spin Button down pressed
{
numericTextBox.set_value(enteredValue - errorDifference);
// subtract the errorDifference to actual entered value -> auto round down to next valid value
}
}
}
because of above mentioned problems i think the better solution is to handle the OnValueChanged event.
this will work for manual entries also which is ok in my scenario
here is my code which seems to work correctly so far:
the downside is the risk of an endless recursion if the calculation is wrong as the set_value method triggers the event again.
is there a way to not handle the event if i used the set_value() method?
function
ValueChanged(sender, eventArgs)
{
var
numericTextBox = sender;
var
enteredValue = numericTextBox.get_value();
var
initialValue = numericTextBox._originalValue;
var
stepSize = numericTextBox._incrementSettings.Step;
var
difference = customRound (initialValue - enteredValue);
var
errorDifference = difference % stepSize;
if
(errorDifference != 0)
// entered value not valid
{
var
correctedValue =customRound( enteredValue - (stepSize - errorDifference));
numericTextBox.set_value(correctedValue);
}
}
function
customRound(value)
{
var
roundingprecision = 1000000;
return
Math.round(value * roundingprecision) / roundingprecision
}
0
Hello Ibrahim,
I am glad that you achieved the desired functionality. Additionally to avoid the endless recursion you could try setting a flag which keeps value when the set_value function is called explicitly:
I hope this helps.
Greetings,
Radoslav
the Telerik team
I am glad that you achieved the desired functionality. Additionally to avoid the endless recursion you could try setting a flag which keeps value when the set_value function is called explicitly:
var
setValueFunctionCalled =
false
;
function
ValueChanged(sender, eventArgs)
{
var
numericTextBox = sender;
var
enteredValue = numericTextBox.get_value();
var
initialValue = numericTextBox._originalValue;
var
stepSize = numericTextBox._incrementSettings.Step;
var
difference = customRound(initialValue - enteredValue);
var
errorDifference = difference % stepSize;
if
(errorDifference != 0)
// entered value not valid
{
var
correctedValue = customRound(enteredValue - (stepSize - errorDifference));
if
(!setValueFunctionCalled)
{
setValueFunctionCalled =
true
;
numericTextBox.set_value(correctedValue);
}
}
}
I hope this helps.
Greetings,
Radoslav
the Telerik team
Browse the vast support resources we have to jumpstart your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
0
Ibrahim Imam
Top achievements
Rank 1
answered on 07 Dec 2010, 01:50 PM
thanks for the fast reply.
EDIT:
unfortunately the recursion check strategy doesn't work that simple as there are many textboxes in the grid so multiple changes are possible.
if i change first textbox and correct the value the variable is set to true.
when i then change the next value the auto correct won't work anymore.
as for the spin button issues
1. setting the eventArgs._cancel property to false solved the issue that the value is changed again after setting the value manually
2. i guess there is no way of getting the new value as the built in spin button action is performed after the custom method, right?
EDIT:
unfortunately the recursion check strategy doesn't work that simple as there are many textboxes in the grid so multiple changes are possible.
if i change first textbox and correct the value the variable is set to true.
when i then change the next value the auto correct won't work anymore.
as for the spin button issues
1. setting the eventArgs._cancel property to false solved the issue that the value is changed again after setting the value manually
2. i guess there is no way of getting the new value as the built in spin button action is performed after the custom method, right?
0
Hello Ibrahim,
Indeed if you have the multiple RadNumericTextBox into the RadGrid the suggested approach with the Boolean flag would not work, however you could try keeping such a flag for every RadNumericTextBox. For example:
In this case every boolean item in the setValueFunctionCalled is associate with the textbox by its ID. Please give it try and let me know if it helps you.
Additionally you could not get the new value after performing spin button actions. You could get it into the OnValueChanged event only.
I hope this helps.
Best wishes,
Radoslav
the Telerik team
Indeed if you have the multiple RadNumericTextBox into the RadGrid the suggested approach with the Boolean flag would not work, however you could try keeping such a flag for every RadNumericTextBox. For example:
var
setValueFunctionCalled =
new
Array();
function
ValueChanged(sender, eventArgs)
{
var
numericTextBox = sender;
var
enteredValue = numericTextBox.get_value();
var
initialValue = numericTextBox._originalValue;
var
stepSize = numericTextBox._incrementSettings.Step;
var
difference = customRound(initialValue - enteredValue);
var
errorDifference = difference % stepSize;
if
(errorDifference != 0)
// entered value not valid
{
var
correctedValue = customRound(enteredValue - (stepSize - errorDifference));
if
(!setValueFunctionCalled[sender._textBoxElement.id])
{
setValueFunctionCalled[sender._textBoxElement.id] =
true
;
numericTextBox.set_value(correctedValue);
}
}
}
In this case every boolean item in the setValueFunctionCalled is associate with the textbox by its ID. Please give it try and let me know if it helps you.
Additionally you could not get the new value after performing spin button actions. You could get it into the OnValueChanged event only.
I hope this helps.
Best wishes,
Radoslav
the Telerik team
Browse the vast support resources we have to jumpstart your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.