JavaScript - Keep date value in non-complete field - javascript

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.

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.

How to listen for segment value (__/__/___) change in input[type="date"]

Input[type="date"] returns a value only if all the segments(//___) are filled with proper values. Is there a way to know if any of the segments is filled?
No, the values that you see (e.g. 05/02/    ) only exist in the UI layer. The value of the DOM element becomes "" anytime the parsing as a Date fails, and it is set to "yyyy-mm-dd" anytime the parsing as a Date succeeds.
The spec: https://dev.w3.org/html5/spec-LC/states-of-the-type-attribute.html#date-state
Quote regarding parsing/validation:
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.

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})?$/)

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

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.

Unexplained change in data in request/response

I am having a very strange problem and I really hope you all can tell my how I'm being dumb and why this is happening.
I have a mobile app that I'm building using the Telerik Appbuilder. The back end is all written on OpenEdge 11.6 and I'm using the Pacific App Server for OE to serve everything up. I am also using the JSDO to interact with my data on the client side.
For some reason when I call jsdo.assign() and send over and object of data to update, all the field get updated except one. It is the only field that is defined as a decimal data type. It looks like the data is being sent as decimal, but somewhere along the line something changes and looks like it gets turned into an integer, or at the very least something OpenEdge does not like.
My request payload looks like this (TEMP is the offending field):
My response looks like this:
What is happening? What could be meddling with my data? I really don't know where to start.
Thank you in advance!
The problem was with my temp-table definition, as it did not reflect the structure of the table. Originally, my code looked like this:
DEFINE TEMP-TABLE ttWHS_TEMP_REPORT BEFORE-TABLE bttWHS_TEMP_REPORT
FIELD LOCATION_ID AS INTEGER INITIAL "0" LABEL "Location_Id"
FIELD LOCATION_NAME AS CHARACTER LABEL "Location_Name"
FIELD TEMP AS DECIMAL INITIAL "0" LABEL "Temp"
FIELD IN_RANGE AS LOGICAL INITIAL "no" LABEL "In_Range"
FIELD EMPLOYEE AS CHARACTER LABEL "Employee"
FIELD STAMP_DT AS DATE INITIAL "?" LABEL "Stamp_DT"
FIELD STAMP_TM AS CHARACTER LABEL "Stamp_TM"
FIELD REPORT_ID AS INTEGER INITIAL "0" LABEL "?".
I simply changed it to look like this:
DEFINE TEMP-TABLE ttWHS_TEMP_REPORT BEFORE-TABLE bttWHS_TEMP_REPORT
FIELD LOCATION_ID AS INTEGER INITIAL "0" LABEL "Location_Id"
FIELD LOCATION_NAME AS CHARACTER LABEL "Location_Name"
FIELD IN_RANGE AS LOGICAL INITIAL "no" LABEL "In_Range"
FIELD EMPLOYEE AS CHARACTER LABEL "Employee"
FIELD STAMP_DT AS DATE INITIAL "?" LABEL "Stamp_DT"
FIELD STAMP_TM AS CHARACTER LABEL "Stamp_TM"
FIELD REPORT_ID AS INTEGER INITIAL "0" LABEL "?"
FIELD TEMP AS DECIMAL INITIAL "0" LABEL "Temp".
I had made changes to my table after defining the temp-table, and I did not know enough about OpenEdge to realize that the order of fields defined in the temp table mattered.

Categories

Resources