Knockout-Contrib / Knockout-Contrib/Knockout-Validation
step rule doesn't work correctly for decimal step value of 0.01
- Dominant language
- JavaScript
- Stars
- 1k
- Forks
- 366
- PR merge metrics
- No merged PRs in 30d
Description
Just try this javascript:
(17.56 \* 100) % ("0.01" \* 100) === 0
As you can see, there are numbers in Javascript (17.56 being just one example) where scaling by multiples of 10 the result is not an integer value.
17.56 \* 100 == 1755.9999999999998. Another example is 33.34 \* 1000000. The result is 33340000.000000004.
Instead it is necessary to do something like this:
parseFloat((17.56 \* 100).toFixed(0)) % parseFloat(("0.01" \* 100).toFixed(0)) === 0
Ideally, if step is an integer you could skip all the fancy code and just do the simple modulo operation like this:
ko.validation.rules['step'] = {
validator: function (val, step) {
if (utils.isEmptyVal(val) || step == 'any') return true;
var nStep = parseFloat(step);
if (isNaN(nStep) || nStep <= 0) return true; // invalid step
if (nStep !== ~~nStep)
{
val = parseFloat((val \* 100).toFixed(0));
nStep = parseFloat((nStep \* 100).toFixed(0));
}
return (val % nStep) === 0;
},
message: 'The value must increment by {0}'
};
You could scale by larger values to support additional digits of step precision without losing support for smaller numbers of step precision, i.e., scaling by 1000000 would support between 1 and 6 decimal digits of step precision.
Contributor guide
Research direction
Start at the ko.validation.rules['step'] validator described in the issue and reproduce the 0.01 case with 17.56 and 33.34. Check how decimal values are scaled before modulo validation. Done means decimal step values validate correctly without floating-point rounding failures, while integer steps and 'any' retain their existing behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100