AngularJS formatting input value to currency and comma separated number if it's only number - javascript

I have angularjs single page application. In the form, there are several input fields controls which can have either any text values e.g. ($12,345 NEDRO) or it can have only amount(e.g. $1,234,567.25). Now if it's only amount then I would like to format to proper currency (which is only $), with commas if user just inputs the number which can be integer or decimal. For example, if user enters 100000, it should be automatically converted to $100,000 either when user leaves the input field or while typing. If user enters the number with proper format e.g. $123,456.34, then no changes required.
What's the best way to handle it? And can someone please provide the code for it.

Related

How can I make a text box in React which allows only numbers or an empty value, which triggers the number keypad on mobile?

There are lots of questions like this on StackOverflow, but none of them captures all of my requirements in the same solution. Any help appreciated.
The problem
In my React app, I need a text box with the following characteristics:
It only allows digits to be entered - no minus signs, decimal places, letters, or anything besides just the digits 0-9.
It automatically brings up the number keypad on iOS and Android
I can further restrict the numbers that should be entered, e.g. only allow 4 digits
Leading zeroes are automatically trimmed, e.g. if a user types 02 it should correct to just 2
It allows an empty textbox, and can differentiate between empty and a value of 0
Current code
https://codepen.io/micahrl/pen/RwGeLmo
This code allows typing non-digits, and will just interpret the value as NaN. For instance, the user can type 2f or asdf and the page will say You typed: NaN.
Additionally, while the page loads initially with an empty text box, the user cannot type something and then delete it back to empty. Attempting to delete all text in the input box places a 0 in the box.
Finally, this code doesn't reliably trim leading zeroes, which causes me particular problems because I want to restrict the number to four digits. Typing 01 will not truncate the leading zero; on some browsers, typing 01111 will result in 1111, which is good enough, while on others, typing 01111 will result in 0111, which is a problem.
What I've tried
Because I have set type="number" on the input element, if there is ever a non-number added to the text box, event.target.value in setNumWrapper will be an empty string. This means I can't differentiate between a true empty string (where the user has deleted all text) and invalid input (where the user has typed a non-number, like asdf).
I could set type="text" on the input element, except that I think I need to set it to number to get the number keypad on mobile OSes like iOS and Android.
With further experimentation, and some help from #Keith in a comment, I've solved almost all my problems.
I've forked the codepen in my question and made these changes in the fork: https://codepen.io/micahrl/pen/GRjwqdO.
Checking input validity
#Keith pointed me to validity.badInput (https://developer.mozilla.org/en-US/docs/Web/API/ValidityState/badInput). With this, I can differentiate between empty input, where a user types something then deletes it, and bad input, where the user attempts to add a non-numeric character.
That means I add this to the beginning of setNumWrapper():
if (event.target.value === "") {
if (event.target.validity.badInput) {
// Set the text box and number to the old value - ignore the bad input
inputRef.current.value = String(num);
setNum(num);
} else {
// The data in the text box was deleted - set everything to empty
inputRef.current.value = "";
setNum(NaN);
}
return;
}
I also have to make an inputRef with useRef(), and set it on the <input> element.
This solves #5 most of #1 (but see below for one remaining minor problem).
Trimming leading zeroes
All I had to do for this was use that inputRef to set the value in the <input> element at the end of setNumWrapper():
inputRef.current.value = String(newNum);
The <input> element's value is always a string anyway, and casting the number to a string removed leading zeroes, if there were any.
Remaining problem: invalid input is allowed if the text box is empty
When the text box is empty, the user can type non-numeric characters into it, and setNumWrapper() doesn't even fire. If you put a console.log() at the top of setNumWrapper(), it won't print anything to the log if the user types a letter, but it will print to the log if the user types a number.
This means I cannot use setNumWrapper() to solve this problem.
However, it's also relatively minor. On mobile, the number keypad comes up, preventing non-numeric input. On the desktop nothing stops the user from typing letters with their keyboard, but for my app, it's clear that only numbers are allowed, so this is good enough for now.
Still, if there's a way to fix this, I'd be curious to hear about it.

Integer/decimal user input: how to serialize/store the value

Our stack is currently: React SPA/Apollo/GraphQL/Rails/PostgreSQL.
We have a web form with a number input that maybe (or not) be used to entry decimal values (dynamic/user-created form).
We want the form to be lenient (it has an autosave feature). If user types ,3 or 17,, that is considered a valid number value. But not too lenient, the number should by parseable as a float and be able to display in graphs...
Also, when the user visit the form again, we want to make sure to init the number input with the exact same value he typed initially (I mean, ,3 does not become magically 0,3)
I'd like to know, for our stack, how to serialize (sending as GraphQL payload) and store (in PostgreSQL) and manipulate (in JS/Ruby) such number without loosing the initial user input value.
I'm thinking it would be simpler to send/store a string, as long as it's validated that it can be parsed.
Just wondering if there is a "proper" solution, for example using number libs, custom GraphQL scalar type, decimal SQL type... that seems complicated to me, anyone did something similar before?
Create two fields. One for user input and other with parsed value. I do not think this will be different for any stack.
The challenge is how to show to a user how you understood entered value. This could be solved with a hint with a parsed value under the text field.
you should choose type of the input as "text" instead of number, so you can create a specific format for your input. first, add a property to your state
state={amount:""}
input section for amount in your form should be like this:
<input
type="text"
placeholder="Amount"
value={this.state.amount}
onChange={this.onAmountChange}
/>
onAmountChange = e => {
const amount = e.target.value;
if (!amount || amount.match(/^-?[0-9]\d*(\.\d{0,2})?$/)) {
this.setState(() => ({ amount }));
}
};
regexp in above function means start with any number with optional -, and optionally u can end with 2 decimal number. you can change it for your form.
if you want to add only positive numbers if your form is for price you can use this regexp:
amount.match(/^\d{1,}(\.\d{0,2})?$/)

JavaScript - Keep date value in non-complete field

I've looked everywhere with no result.
I'm working on a little form that allows users to subscribe themselves on a site.
There is a table with some cells and textnodes including also a 'date' field.
With 'onfocus' event cells are colored in blue during editing.
With 'onblur' event cells recover previous color, except if they include wrong value (e.g. numbers in 'name' field): in this case cells become red.
I've some problem with 'date' field.
I give example: user start to write birthday date and for some reason doesn't complete the field before change cell....or user after complete date field press ESC.
I both cases, if I try to read field value using getelementbyId().value, it returns '' (empty).
Is there any way to read value in these cases?
Thanks a lot.
According to the specification(WHATWG) you cann't access this value.
The value sanitization algorithm is as follows: If the value of the element is not a valid date string, then set it to the empty string instead.
Same for W3
User agents must not allow the user to set the value to a non-empty string that is not a valid date string.

How to allow a user to enter decimal places right after a comma/point is pressed?

I have textboxes where a user can insert some numeric values. These textboxes have up to 9 decimal places (I use metric system):
0,000000000
Right now, in order to type 50,000000000, one must type 5 then a bunch of zeros, clearly not the best solution. I would like to allow my user to type 5 then press comma and directly be able to type any decimal value he wanted.
How can I achieve that using javascript and/or jquery?

angularjs convert 0 to 1 in number (html5) field

its an odd behavior. m using input field field where type is number
and if i enter 1230 model value remains -> 1230
but as i type 01 its becomes -> 1
where as i can see 01 in input value . so this something to do with angular js
i need 00 in model because its user phone number and number type is to stop user from entering text
any help will be appreciated
https://docs.angularjs.org/api/ng/input/input%5Bnumber%5D
test can be run at angular site
The type number allows you to enter +-,.. So you cannot achieve your goal of preventing the user from entering "invalid" numbers in the first place.
It's also not very user friendly, as telephone numbers are often formatted using spaces and braces. A user can no longer copy and paste such values into the input field. Digits in phone numbers can also be represented by letters btw. 123-HELLO is equal to 12343556.
Please note that there's also an input type tel. It's not particularly useful but semantically more appropriate.
If you only want to save and display the value then use the input as is. It doesn't make much sense to force a user to adhere to your preferred pattern. Adding pattern or ngPattern allows you to use regular expressions to limit the possible characters. If you need the plain number then strip all non-numeric characters - and possibly convert roman letters to numbers - before usage.

Categories

Resources