p:inputtext format number like '999,999' - javascript

In my XHTML page I have some inputText fields where the user can insert numeric values in the format "999,999" (max three integer values, max three decimal values). The decimal separator is ",", because I want to format the above fields using the Italian locale.
Actually this is my p:inputText component:
<p:inputText value="#{r.value}" id="verog_#{r.id}"
onkeypress="return isNumberKey(event)" />
The isNumberKey() javascript function enables permitted characters only (numbers and comma):
function isNumberKey(evt)
{
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode == 44) return true;
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;
return true;
}
But I have no control on the maximum number of digits allowed, so the user can, for example, input a number like "1234,5678", or, even worse, "12,,34".
I need to check these values on the client side because they are within a dialog. Actually I make checks on the server side, after the "save" button is clicked:
<p:commandButton value="save" action="#{myBean.saveAction}" ajax="true"
update=":growl" oncomplete="dialogVar.hide()">
<f:param name="action" value="#{action}" />
</p:commandButton>
But if I have an input error, the dialog is always hidden, and the user is forced to submit the values again.
I cannot use f:convertNumber, because data are saved on the db as strings, not as numbers.
I also tried to use the p:inputMask component, but I cannot make it to work properly (maybe for a lack of knowledge): the mask "999?,999" does not fit my requirements.
Maybe I can do it using a converter (the p:inputText component has the "converter" and "converterMessage" attributes), but my converter attempts failed too:
NumberFormat nf = NumberFormat.getNumberInstance(Locale.ITALIAN);
nf.setMaximumIntegerDigits(3);
nf.setMaximumFractionDigits(3);
String result = nf.format(submittedValue);
It always gives me IllegalArgumentException, even if submittedValue is 0.
How can I reach my goal? Thanks in advance.

You need to test the whole value on the client side.
I've made a fiddle with example JS validation: http://jsfiddle.net/lechlukasz/w8K8j/1/
It calls validation function on blur:
function valid(val) {
var reg = new RegExp('^[0-9]{1,3}(,[0-9]{1,3})?$');
if (!reg.test(val))
return false;
return true;
}
If you want to make full validation on keypress, don't forget to allow the coma as the last character (illegal in final string, but necessary when typing :)

Related

Validate clock time with quarters

I want to match below in a text box when user entered values.
.00
.25
.50
.75
and 2 specific digits:
[0 to 23].00
[0 to 23].25
[0 to 23].50
[0 to 23].75
for example 1.25, 12.25, 22.50, etc. All above values are allowed.
Values like 0, 7, 12.18, 24.00 are not allowed.
Currently I am just checking below which will allow any decimal values.
var charCode = (e.which) ? e.which : event.keyCode
if (
(charCode != 46 || $(element).val().indexOf('.') != -1) &&
(charCode < 48 || charCode > 57)
) return false;
return true;
Validate clock time with quarters
Thanks to the comments section we all realized it's a validation of a clock time (question edited to reflect).
Glad to remind here that in such case .00 or either 0.00 — should be a valid input since it represents midnight. And therefore all other integers of full-hour like 1.00 up to 23.00 are also valid.
Don't use keyboard Events. As #trincot suggested, if a user enters ".2" he will no longer be able to finish the desired number (0.25) since ".2" is (per your statement) already invalid.
Instead, use rather a "blur" or some other event. Or you can also use the Input element pattern attribute to visually mark the input as invalid.
Here's the basic regex to match the desired: a clock time with quarters
^(\d|[0-1]\d|2[0-3])?\.(00|15|30|45)$
or if you use decimals as hundreds:
^(\d|[0-1]\d|2[0-3])?\.(00|25|50|75)$
Regex101.com demo and explanation
Example of input pattern attribute:
input:invalid { background: red; }
<input type="text" pattern="(\d|[0-1]\d|2[0-3])?\.(00|25|50|75)">
Example using RegExp.prototype.test() ideal for JS validation
const validateNumDec = n => /^(\d|[0-1]\d|2[0-3])?\.(00|25|50|75)$/.test(n);
console.log(".00", validateNumDec(".00")); // true
console.log(".25", validateNumDec(".25")); // true
console.log("13.00", validateNumDec("13.00")); // true
console.log("23.75", validateNumDec("23.75")); // true
console.log("5", validateNumDec("5")); // false
console.log("5.13", validateNumDec("5.13")); // false
console.log("5.13", validateNumDec("23.59")); // false
Final note
One might eventually simply go for <input type="time" but as you can see the step="900" (900 seconds being 15 minutes) do work when using i.e: keyboarrd's up/down arrows (15 min jump), but it's not respected in the popup picker — in Chrome browser:
<input type="time" min="00:00" max="18:00" step="900" required>
From the MDN documentation about Using the Step attribute:
Note:
Using step seems to cause validation to not work properly (as seen in the next section).
Documentation:
RegExp.prototype.test()
Pattern attribute

How to make an input box to accept positive and negative decimal values?

How can I make an input box to accept only one - sign OR one + sign AND one decimal point with numbers?
I tried `preventDefault(); to block other characters by following code:
$('.pndecimal').on('keypress keyup blur', function(e){
if(e.which< 48 && e.which > 57)
{
e.preventDefault();
}
});
I'm not able to allow these because they are out of range of ASCII codes of numbers (e.which<48 & e.which >57)
Use regular expression validation, if it passes take the value or else show error.
eg: /(-|\\+)+[0-9]+\\.[0-9]+/g
valid inputs: +9.0, -9.7, +78.9, -10.0
If you want to have more than one number after decimal point than use this pattern(this patterns also allow inputs like -99/,++,--)
eg: /(-|\\+)+[0-9]+\\.[0-9]+/g
valid inputs: +91.42, +1.809, -9.0
If you want to restrict to 2 integer numbers,2 decimal numbers,any one sign use the following:
RegExp(/(-|\+)+[0-9]+\.[0-9]+/g)
<input type="text" maxlength="4">

how to make a text field to accept only numbers, and two decimal places

I need to make a text field accept only numbers and decimal point, and default to two decimal places.
I got this code from a search here. It works for accepting only numbers.
I need to make it accept decimal point, and default to two decimal places.
<input type="text" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));" />
Thanks
You could use a regular expression to limit what can be entered into the field.
As an example:
<input type="text" pattern="(?:[01]|2(?![4-9])){1}\d{1}:[0-5]{1}\d{1}">
You can visit a site like regexlib.com which can help you build and test the type of regex you are seeking.
There may be a better or more eloquent method, but this easy and works for me.
Leave it to HTML5:
<input type="number" step="0.01">
Also, remember about server side validation (in PHP for example). Don't try to force some missing keypress, or don't override default browser behaviour. This is not user friendly.
What will you do if you press A, and nothing is displayed? Would you go to a shop for a new keyboard?
In that case try to give the user a clue, what type of data you expect.
Give the user a tool (type="number") to show best possible keyboard layout on the phone.
But don't try to do it "better". In that case it means worse.
More on the subject:
Is there a float input type in HTML(5)?
If you want to always show 2 decimal places, you can reformat the input on change to round and display to 2 decimals:
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode > 31 && (charCode != 46 && (charCode < 48 || charCode > 57)))
return false;
return true;
}
$("#twodecimals").change(function() {
var format = parseFloat(Math.round($(this).val() * 100) / 100).toFixed(2);
$(this).val(format);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="twodecimals" onkeypress="return isNumberKey(event)" />

How can I control decimal field to allow enter more than one point?

I have a field that I can control that not accepts letters etc. I allow to enter "." In order to input decimals. How can I control that not more than one "."?
Here my source code:
$(".allow_decimal").on("input", function(evt) {
var self = $(this);
self.val(self.val().replace(/[^0-9\.]/g, ''));
if ((evt.which != 46 || self.val().indexOf('.') != -1) &&
(evt.which < 48 || evt.which > 57))
{
evt.preventDefault();
}
});
The HTML5 specification allows for a number input type. One of the attributes allowed for the number input is step which is the increments that the number may go up/down in:
<form>
<input type="number" step="0.1" />
<input type="submit">
</form>
While, yes, you can type in something like '2.25', when you try to submit the form, any HTML5 compliant browser will tell you off for it:
This only applies to HTML5 compliant browsers: CanIUse.com
As always - don't trust anything sent by a user - ALWAYS validate on the server ;)

Validating numeric input while formatting numeric input

In an asp.net-mvc project using C#.
I use a function to format larger numbers with commas such as 1,000,000, thanks to this post:
function numberWithCommas(str) {
return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
The issue is, I have the inputs locked down to accept only numbers with a min value of zero.
<input type="number" min="0" class="myclass" value="#somevalue" />
This poses a problem using the JS, as it needs only number input. Which brings me to a question like this How to make HTML input tag only accept numerical values?, which also offers a JS solution.
I'm wondering if anyone has developed an elegant way to format numeric input display, while validating numeric input, is there are any other options available here? It doesn't have to purely be a JS solution.
You can't use the numeric input, because, well, JavaScript doesn't consider formatted number to be a number.
The option is to use the non-numeric input but filter out any "problematic" chars.
In the following example, I'm also handling the dot separator in case you need to accept fractions.
As the text box is being edited, it also has to preserve the cursor position. I've achieved it there with the help of Updating an input's value without losing cursor position.
function format(inp){
var start = inp.selectionStart, // get the selection start
end = inp.selectionEnd; // and end, as per the linked post
var s1=inp.value.split(",").length-1; //count the commas before edit
inp.value=numberWithCommas(inp.value.replace(/,|[^\d.]/g,''));
var s2=inp.value.split(",").length-s1-1; //count the commas after edit so as to know where to place the cursor, as the position changes, if there are new commas or some commas have been removed
inp.setSelectionRange(start+s2, end+s2); // set the selection start and end, as per the linked post
}
function numberWithCommas(str) {
var a=str.split('.');
var p=/\B(?=(\d{3})+(?!\d))/g;
if(a.length>1)
return a[0].toString().replace(p, ",")+"."+a[1];
else
return str.toString().replace(p, ",");
}
<input onkeyup="format(this)">
I have the answer of your first question.
You can disable all keys rather than only numbers keys.
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if (charCode != 43 && charCode > 31
&& (charCode < 48 || charCode > 57))
return false;
return true;
}
I also created working demo on jsfiddle
The program flow:
Getting the input via an on change event and calling the other functions, showing passing the data through a Ajax POST.
$('.Amount').on("change", function (e) {
var myInput = $(e.target);
var input = this.value;
// Remove any non digits (including commas) to pass value to controller.
var Amount = validateInput(input);
// Format the string to have commas every three digits 1,000,000 for display.
var val = numberWithCommas(Amount);
$(myInput).val(val);
$.ajax({
type: 'POST',
dataType: "json",
url: somesUrl + '/' + somethingelse,
data: JSON.parse('{"Amount": "' + Amount + '"}'), // Amount is a nice format here and will not throw an error.
// TODO etc
});
});
Remove any non numbers and give a value of zero if no numbers are inputted.
var validateInput = function (input) {
input = input.toString().replace(/[^0-9]/g, "");
/* Remove leading zeros. */
input = input.replace(/^0+/, '');
if (input == "")
input = 0;
return input;
}
Format the input with commas 1,000,000,000.
function numberWithCommas(str) {
return str.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
So even if the user types input with commas e.g. 1,734,567 it will work and if they misplace where they put a commas e.g. 17,35,555 it will still validate.
See working fiddle.
I actually worked out a nice solution while trying to meet project deadlines and in part this was solved by this answer by nicael.
This solution does not check the input as it is being typed, but after it is finished, I chose the change event, as opposed to the input event, as it calls the function once and (similar to a submit event) than validates the input in one call. Removing any commas and non digits; solving the issue of formatting with commas, by removing them for the ajax call, then reformatting it with commas for the display. There is a check to remove leading zeros.
If all the input is garbage I replace this value with zero to prevent an error passing to the controller with null data (just a design choice, could display a toast message instead).

Categories

Resources