Reputation: 61
function validateFloatKeyPress(el, evt)
{
var charCode = (evt.which) ? evt.which : event.keyCode;
var number = el.value.split('.');
if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57))
{
return false;
}
//just one dot
if (number.length > 1 && charCode == 46)
{
return false;
}
//get the carat position
var caratPos = getSelectionStart(el);
var dotPos = el.value.indexOf(".");
if (caratPos > dotPos && dotPos > -1 && (number[1].length > 2))
{
return false;
}
return true;
}
//thanks: http://javascript.nwbox.com/cursor_position/
function getSelectionStart(o)
{
if (o.createTextRange)
{
var r = document.selection.createRange().duplicate()
r.moveEnd('character', o.value.length)
if (r.text == '') return o.value.length
return o.value.lastIndexOf(r.text)
} else return o.selectionStart
}
<td style="height:32px">
<input style="height:27px" name="hispanicLatino" class="numeral form-control text-font-md" type="text" oncopy="return false"
oncut="return false" onpaste="return false" maxlength="100.000" onkeypress="return validateFloatKeyPress(this,event);"
data-bind="css: , attr: {id: 'hispanicLatino' + ($index() + 1), title: $parent.hispanicLatinoToolTip}, value: $data.hispanicLatino">
</td>
Updated my code. Now my code works to limit the decimals to 3 decimals after the "." but now the left part of the "." doesn't lock to 100. you can enter 1111111111 etc. Not sure what i should add.
Upvotes: 0
Views: 328
Reputation: 4304
If you need immediate validation rather than only on submit you could try using a custom knockout binding to intercept the values before they're written to the view-model. This has the down-side of bypassing knockout's default textInput binding which handles a lot of browser specific quirks.
//prevent values from updating unless they pass a validator function
ko.bindingHandlers.gatedValue = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//element -> viewmodel
var validator = allBindings().gatedValidator;
$(element).on("keydown change keyup",
function() {
var newValue = $(element).val();
var target = valueAccessor();
if (validator(newValue)) {
target(newValue);
} else {
$(element).val(target()); //reset to previous value
}
});
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
//viewmodel -> element
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).val(value);
}
}
function viewModel() {
this.myNumber = ko.observable();
this.myValidator = function(value) {
var decimalPos = value.indexOf('.');
if (decimalPos > 0) {
var decimal = value.substring(decimalPos+1);
if (decimal.length > 3) {
return false;
}
}
var numeric = Number(value);
if (isNaN(numeric) || numeric > 100) {
return false;
}
return true;
}
}
ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" data-bind="gatedValue: myNumber, gatedValidator: myValidator" />
Upvotes: 0
Reputation: 121
It sounds like you need to limit the number of decimal places in your calculations? If that's the case you can try something like this in your code: finalValue = ($(me).val() + currentValue).toFixed(3);
Check this link for more info on the toFixed method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
Upvotes: 0
Reputation: 6967
I'm not sure why you're relying on JavaScript here when it seems like native form controls would be sufficient. Consider the following code:
<form>
<input type="number" min="0.000" max="100.000" step=".001" required />
<button type="submit">Submit</button>
</form>
The minimum value is already set at 0.000
and the maximum at 100.000
with a step (the rate at which the number increases) set to .001
. Any value below the minimum or above the maximum will trigger a form error.
Certainly I would use JavaScript for adding clarity to the user, but in terms of raw "Make this form 'work'" it seems like HTML alone provides a solution.
Upvotes: 1