I'm trying to set some validation for an input field. It is working fine everywhere except on iOS.
Here's some example code but the are two points to consider:
It must be a type="text" input because I need to allow the user to type
special characters like - and /
I made some regex to handle the input validation but for the sake of
simplicity I'm omitting it from the snippet.
https://codesandbox.io/s/youthful-morning-gjjsq
The original code is from a React project with Redux so I reproduced the same logic with both state management from React and from Redux to make clear the problem is not coming from neither of them. In the example I set the if-else conditional to allow any value less or equal to 20 to be displayed in the input fields and, as I said, it works OK. Nothing fancy, it's just to demonstrate that when the value is greater than 20, or when is not even a numeric value, the input field won't get updated. But whatever the reason, for iOS when, specifically, the dash (or minus) character is inserted in the input field the other characters get erased. Try typing 2- or 20- and the characters will disappear. If I try to type other character like / or ?, whatever, the values are not erased though. The desired behavior is to keep the value untouched (i.e. 2 or 20), not delete it.
The problem doesn't happen on Windows and on Android; it's only on iOS no matter the browser (not sure if it happens on Mac too). I tried return false, e.preventDefault(), e.stopPropagation(), e.nativeEvent.stopImmediatePropagation(). None of these worked.
Does anybody could help me with this? Again, the code I provided is just an example based on the original code which I can't reproduce here. I can clarify better if needed.
Related
How can I create a input text in React with placeholder as DD-MM-YYYY,
when I start typing the value, the placeholder should be removed partially.
For eg if I type 02-MM-YYYY(in this case -MM-YYYY should be visible part of the placeholder)
The pattern you are describing is an input mask, so you might have more luck searching for this than placeholder.
First of all, have you considered using <input type="date">? Most browsers also provide an input mask for this kind of input.
If this doesn’t help you, HTML does not provide input mask functionality natively, so you will need to find a library that does that for you.
As always, you should clarify your basic requirements before choosing a library from npm. Most notably, it should be accessible for users with disabilities. Input masks seemingly improve user experience, but they are hard to get right. If not done well, they actually render the user’s experience worse.
Things the input should still support with input mask applied:
(Copying and) Pasting the value from elsewhere
Autofill by the browser (for your birthdate, for example)
Screen readers announce the value correctly
Correcting the value by means of keyboard only, for example deleting one number in the middle
The pattern adjusts with the locale (language)
I'm developing a small application that consists on a set of text inputs, and each one will fit only one character, and all inputs together should behave like one. So, when a input is filled with a character, the next input should be highlighted, behaving like the input's caret. In the same manner, when you empty an input, it should behave like a common character deleting, and the previous input should be highlighted.
You can see my work here: https://codepen.io/Vitaozim/full/vqaRQY
Sample here:
Here's how I've done it:
Whenever any of the input elements if focused, its whole content is
highlighted, to make sure any input it receives changes its whole
value.
Whenever the input event is triggered in any of the input elements,
one of these may happen:
If the input's new value is not blank, the next input element is focused. If it receives a value with more than 1 character, the code will trim the string and leave only the last character.
Else, the value is programatically changed to one single space, and the previous input element is focused. The value is changed to one single space so that whenever that input is focused again, there will be some content to be highlighted and then deleted, triggering the "backspace" condition.
The problem is, it works perfectly on the following browsers:
Chrome for Mac and iPhone
Safari for Mac and iPhone
Firefox for Mac, iPhone and Android
But it's buggy on Chrome for Android. I tested it in many different devices. The "backspace simulation" bugs and the input's value isn't highlighted on focus.
I've made some tests, and I noticed that if I set the selection after a setTimeout of 100ms, it works. It's like i'm overriding the browser's default behavior... But that's still an really odd behavior, because it only happens on the "backspace" simulation. Any other situation where the input is focused doesn't have this bug.
This seems to be a common issue with Chrome. You should be able to use the following.
setTimeout(function() {}, 0);
Other StackOverflow answers suggesting this is a known bug in Chrome / Chromium.
https://stackoverflow.com/a/32049253/1050507
https://stackoverflow.com/a/17384592/1050507
I know there is a pattern a attribute for html5 input tag, but this help to validate the field after the user has entered the value.
The request here is to prevent the user to type something wrong, instead of correct it after. I'm not interested to discuss if it's better or not - it's just the request.
I also know I could add an event listener for keyPress event and decide which chars accept.
But all the examples I saw are not cross-browser compatible (I'm interested at least in FF, Chrome, in both desktop and mobile versions) and they fails because the user can enter "----" or "....".
What could be a reliable, robust, cross-browser regexp pattern to allow the user to type:
any number [0..9]
only one decimal point ('.' or ',' converter to the first one)
a specified number of decimals (i.e. numbers after the decimal point)
optional only one sign symbol ('+' or '-') as first char
common text commands: arrow keys, copy/cut/paste, backspace, delete, enter
It's better without the use of jQuery - because I should add it only for this goal.
"The request here is to prevent the user" -- don't do that.
If I am typing my name, but my finger slips when typing the i and I hit the 8 key too... no big deal, I just hit backspace, right?
Well, with your idea, wrong. Your name input would disallow numbers, so the accidental 8 wouldn't appear, and the backspace would erase the i instead.
In your question you appear to be seeking a numeric input (have you considered <input type="number" />?) so the finger-slip could apply to the * key when trying to input a 9. Whatever your input the same idea applies.
Always allow the user to type whatever they want. When they are done typing (either onchange of the element or onsubmit of the form), then you tell them "hey, this thing you typed doesn't seem right."
Therefore, the behaviour provided by browsers supporting input[pattern] is correct, and should not be changed.
I sunk way too much time into fixing this and i'm still not too sure what to make of it.
The issue:
I have an input tag <input type="number" max="{{ theMax }}"> with a dynamic max value that should be set on the template load.
The max tag will prevent you from going above that number when you click the little up/down arrow icons in the input box, but not if you type it in.
On my local, if I typed in a number higher than the maximum value I was still able to read that value from the input fine.
On my server however (which has the exact same codebase), when I typed in something above the value and queried the input for it, it would give me undefined.
Both behaviours could make sense (I'm not sure what the actual spec is supposed to be with the max attribute) it's the oddness of the inconsistency that bewilders me (same browser and everything).
At first i'm thinking it was some kind of race condition and perhaps because {{ theMax }} is dynamically set perhaps the live code was slower at fetching it or something, but the fact is it still recognises the max value because the input value only returns undefined if you put something it it that is above the max.
What could explain this inconsistency? Is there something obvious or perhaps something in the rest of my code that's having this effect?
Note: yes, same browser used for both tests.
Thanks
I would not recommend to use dynamic max value because ng-max doesn't watch the change of value after link(or compile) function.
If you need to use dynamic max value, this post could help you.
I have an HTML form with two input textfields.
When the user tabs from the first field to the second, I'd like to automatically switch the user's input method to a different one, say for a different language.
The reason I'm trying to do this is that I expect the user to type content in known different languages in each field.
I tried <input lang="JA" /> but that didn't seem to change the input method on Safari for Mac nor iOS.
Is it possible in HTML or JavaScript to change the input method on a per-textfield basis?
Input methods are controlled by the browser and the user. The lang attribute does not affect this, and there is no other HTML way either. It would not be useful to change the input method on a per-document, still less per-field basis, from the method normally used in the browser and accepted by the user (either silently or by finding out how to control such things).
In some situations, it can be helpful to provide special tools to users—not to override input methods but to offer additional possibilities. For example, if the expected language is written in Latin letters with a few extra letters in addition to the basic a–z, you could have buttons for entering them (to help people using keyboards that have no convenient way to type them).
It is possible to build controls that act as input method editors, see e.g. typd.in for entering Japanese. But this means using something on top of the input methods that the user is using.