Why does my "oninvalid" attribute let the pattern fail? - html

This little HTML5 password field works perfectly WITHOUT the oninvalid attribute (the pattern say: minimum 6 characters):
<form>
<input type="password" name="user_password_new" pattern=".{6,}" required />
<input type="submit" name="register" value="Register" />
</form>
See the jsFiddle here.
But when I add an oninvalid attribute that gives out a custom error message when user's input does not fit the pattern, the entire field NEVER becomes valid, see the code here:
<form>
<input type="password" name="user_password_new" pattern=".{6,}" oninvalid="setCustomValidity('Minimum length is 6 characters')" required />
<input type="submit" name="register" value="Register" />
</form>
See the jsFiddle here.
Can you spot the mistake ?

If you set a value with setCustomValidity() then the field is invalid. That is setting a non-zero length string causes the browser to consider the field invalid. In order to allow for the effects of any other validations you have to clear the custom validity:
<input type="password" name="user_password_new" pattern=".{6,}" required
oninvalid="setCustomValidity('Minimum length is 6 characters')"
oninput="setCustomValidity('')" />

Since I stumbled on the same problem, here is my solution – tested and working with FF, Chrome, IE 10, Edge (Feb 2017).
<form>
<input pattern="1234" oninput="setCustomValidity(''); checkValidity(); setCustomValidity(validity.valid ? '' :'please enter 1234');">
<input type="email" required>
<input type="submit">
</form>
Explanation:
setCustomValidity(''); removes the custom error string which otherwise would always result in an invalid field at the validation process.
checkValidity(); does a manual validation – the same as it is happening at the form submisson. The result is stored in validity.valid.
The second setCustomValidity(validity.valid ? '' :'please enter 1234'); now sets the error string according to the validation result. If the field is valid it needs to be empty, otherwise the custom error string can be set.

I like to use like this:
<input type="email" name="Email" required oninvalid="setCustomValidity('ErrorMessage')"/>
And unplugged for all of valid input data
UPD, one more thing for better work:
$("input").attr("onblur", "setCustomValidity('')");
$("input").attr("oninput", "setCustomValidity(' ')");

Although the answers for this question had good information, they weren't sufficient for my needs. I need to display different messages depending on which validity rule failed. In the other examples, the same validation failure message is used for all valiation failures.
The "validity" property of a form object holds the key to creating more than one validation failure message.
You can review all of the different "validity" property properties at this web site.
https://www.w3schools.com/js/js_validation_api.asp
This example shows how to display two different validation messages. If you uncomment the console.log() line below you can watch the validity property change as you type in a field.
<label for="user_password_new">New Password:</label>
<input type="password" name="user_password_new" id="user_password_new"
pattern=".{6,}"
value=""
required
oninput="
setCustomValidity('');
checkValidity();
// console.log(validity);
if (validity.patternMismatch) {
setCustomValidity('Please enter at least six characters.');
}
else if (validity.valueMissing) {
setCustomValidity('This field is required.');
}
else if (validity.valid) {
setCustomValidity('');
}
// allow default validation message to appear for other validation failures
"
>
NOTE: Some validity checks are "type" specific. For example, the "rangeOverflow", "rangeUnderflow", and "stepMismatch" attributes get set if type uses them; type="number".

You can use title as long as you don't mind having 'You must use this format:' before your message. If you want a full custom message, the setCustomValidity() worked for me.

Related

The autofill field name “postal-code” is not allowed in this context

im currently trying to optimize my forms on my Webpage. The HTML Validator gives me the following error:
The autofill field name “postal-code” is not allowed in this context.
I dont know why, since it does what it should. The autofill inserts the Postal-code. Here is the Element:
<td><input type=number name="changeZip" min=00000 max=99999 autocomplete="postal-code"></td>
This Element has same Error:
<input class="login" type="number" name="txtZip" value="" required max="99999" min="00000" placeholder="Postleitzahl" autocomplete="postal-code"/>
Why isnt it allowed here according to the Error-Message? I dont find anything in Google for this.
Thanks.
The type attribute needs to be "text". Some countries use a combination of letters and numbers for their postal code.
Therefore, your input element should be
<input type="text" name="changeZip" minLength="5" maxLength="5" autocomplete="postal-code">

Purposely invalidate the html5 form validator using dummy pattern

I want to programatically set the input to invalid if specific condition is met e.g
<input type="text" required />
Lets take a variable isValid an example, if that is false, i want that bubble to show up with default browser bubble (onsubmit) and the custom error thats provided. So to add custom errors i figured the solition
<input
type="text"
required
oninvalid="this.setCustomValidity('Please Enter valid name')"
oninput="setCustomValidity('')"
/>
However this only check if its empty, the extra validation comes from a field called pattern however that regex, so I was thinking maybe do a pretty much all case regex when is 'isValid == true' else a regex that will fall everytime e.g. (react)
<input
type="text"
required
pattern={isValid ? 'regex valid always' : 'regex fail always'}
...
/>
Could this even work? is there a better way that I'm not seeing?
Thanks to #revo for his help got it working with just:
<input
type="text"
required
pattern={isValid ? null : '(?!)'}
...
/>

How to turn off HTML input form field suggestions?

By suggestions, I mean the drop down menu appear when you start typing, and it's suggestions are based on what you've typed before:
For example, when I type 'a' in title field, it will give me a ton of suggestions which is pretty annoying.
How can this be turned off?
What you want is to disable HTML autocomplete Attribute.
Setting autocomplete="off" here has two effects:
It stops the browser from saving field data for later autocompletion
on similar forms though heuristics that vary by browser. It stops the
browser from caching form data in session history. When form data is
cached in session history, the information filled in by the user will
be visible after the user has submitted the form and clicked on the
Back button to go back to the original form page.
Read more on MDN Network
Here's an example how to do it.
<form action="#" autocomplete="on">
First name:<input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
E-mail: <input type="email" name="email" autocomplete="off"><br>
<input type="submit">
</form>
If it's on React framework then use as follows:
<input
id={field.name}
className="form-control"
type="text"
placeholder={field.name}
autoComplete="off"
{...fields}/>
Link to react docs
Update
Here's an update to fix some browsers skipping "autocomplete=off" flag.
<form action="#" autocomplete="off">
First name: <input type="text" name="fname" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"><br> Last name: <input type="text" name="lname" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"><br> E-mail:
<input type="email" name="email" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"><br>
<input type="submit">
</form>
On Chrome, the only method we could identify which prevented all form fills was to use autocomplete="new-password". Apply this on any input which shouldn't have autocomplete, and it'll be enforced (even if the field has nothing to do with passwords, e.g. SomeStateId filling with state form values). See this link on the Chromium bugs discussion for more detail.
Note that this only consistently works on Chromium-based browsers and Safari - Firefox doesn't have special handlers for this new-password (see this discussion for some detail).
Update: Firefox is coming aboard! Nightly v68.0a1 and Beta v67.0b5 (3/27/2019) feature support for the new-password autocomplete attribute, stable releases should be coming on 5/14/2019 per the roadmap.
Update in 2022: For input fields with a type of password, some browsers are now offering to generate secure passwords if you've specified autocomplete="new-password". There's currently no workaround if you want to suppress that behavior, but I'll update if one becomes available.
use autocomplete="off" attribute
Quote:IMPORTANT
Put the attribute on the <input> element,
NOT on the <form> element
Adding the two following attributes turn off all the field suggestions (tested on Chrome v85, Firefox v80 and Edge v44):
<input type="search" autocomplete="off">
I know it's been a while but if someone is looking for the answer this might help. I have used autocomplete="new-password" for the password field. and it solved my problem. Here is the MDN documentation.
This solution worked for me: Add readonly attribute.
Here's an update to fix some browsers skipping the
"autocomplete=off" flag.
<input type="text" name="lname" autocomplete="off" readonly onfocus="this.removeAttribute('readonly');">
autocomplete = "new-password" does not work for me.
I built a React Form.
Google Chrome will autocomplete the form input based on the name attribute.
<input
className="scp-remark"
type="text"
name="remark"
id='remark'
value={this.state.remark}
placeholder="Remark"
onChange={this.handleChange}
/>
It will base on the "name" attribute to decide whether to autofill your form. In this example, name: "remark". So Chrome will autofill based on all my previous "remark" inputs.
<input
className="scp-remark"
type="text"
name={uuid()} //disable Chrome autofill
id='remark'
value={this.state.remark}
placeholder="Remark"
onChange={this.handleChange}
/>
So, to hack this, I give name a random value using uuid() library.
import uuid from 'react-uuid';
Now, the autocomplete dropdown list will not happen.
I use the id attribute to identify the form input instead of name in the handleChange event handler
handleChange = (event) => {
const {id, value} = event.target;
this.setState({
[id]: value,
})
}
And it works for me.
I had similar issue but I eventually end up doing
<input id="inp1" autocomplete="off" maxlength="1" />
i.e.,
autocomplete = 'off' and suggestions will be disappeared.
<input type="text" autocomplete="off"> is in fact the right answer, though for me it wasn't immediately clear.
According to MDN:
If a browser keeps on making suggestions even after setting
autocomplete to off, then you have to change the name attribute of the
input element.
The attribute does prevent the future saving of data but it does not necessarily clear existing saved data. Thus, if suggestions are still being made even after setting the attribute to "off", either:
rename the input
clear existing data entries
Additionally, if you are working in a React context the attribute naturally becomes autoComplete.
Cheers!
I ended up changing the input field to
<textarea style="resize:none;"></textarea>
You'll never get autocomplete for textareas.
If you are using ReactJS. Then make this as autoComplete="off"
<input type="text" autoComplete="off" />

HTML5 novalidate only for some inputs

I've got really simple question - is there any way to disable HTML5 validation only for some chosen inputs (instead of setting "novalidate" for whole form)?
I mean something like <input type='number' requirednovalidate>. But this doesn't work.
You may ask why I need type="number" or "required" then? Well, I need it there because my framework uses it for its own validation.
EDIT
It is about one special input - birth number. I need it to be of type number (because of mobile devices) but its value is mostly used with "/" (e.g. 860518/8757) which is not valid character for type number. So I need user to fill it without slash (8605188757). The problem is when there is invalid value filled in html5 input (e.g. "fsda" in number type), it seems like it is empty, with no value.
So when user fill the value in wrong format (860518/8757), html validation is disabled so the JS validation runs, it is validated like empty field. So the error message is like "Please fill the field birth number" (which is really confusing) instead somthing like "Sorry, wrong format".
My solution was to enable html5 validation for this field (so the default browser message is displayed when there is wrong format filled) but disable it for other fields so that they would be validated only with my JS validation.
You cannot disable HTML5 validation for a chosen input(s).
If you want to remove validation on the entire form you can use formnovalidate in your input element.
For example,
<input type="submit" value="Save" class="button primary large" formnovalidate/>
Note you can use formnovalidate with <input type=submit>, <inut type=image> or <button> -source
For more info go here or here.
novalidate attribute is only for form tag, it can't be applied on form controls.
You can remove the required attribute in js, after your framework validates:
$('[Selector]').removeAttr('required');​​​​​
Now the selected field will not be validated.
Inputs will be validate when:
have attr required or prop required=true
aren't empty; don't have to have attr required or prop required=true
and have no attr disabled or prop disabled=true
If you want to validate data in a specific way, use pattern attr.
JSFiddle
(function() {
document.querySelector('form').addEventListener('submit', function(event) {
event.preventDefault();
});
})();
<form>
1. <input type='text'><br>
2. <input type='text' required><br>
3. <input type='text' required disabled><br>
4. <input type='text' value="" pattern="\d*"><br>
5. <input type='text' value="" pattern="\d*" required><br>
6. <input type='text' value="" pattern="\d+"><br>
7. <input type='text' value="" pattern="\d+" required><br>
8. <input type='text' value="test" pattern="\d+" required disabled><br>
<button>check field validity</button>
</form>

Angular/bootstrap show specific form validation message

I'd like to have a required email input on a form, and I'd like to augment the input's label to show validity with specific messages. I tried the markup below (simplified, and a few variants). The actual can be found at this fiddle illustrating the problem.
<label for="email">Email
<small class="help-inline" ng-show="form.email.$invalid-required"> (required)</small>
<small class="help-inline" ng-show="form.email.$invalid-email"> (email)</small>
</label>
<div class="input-group">
<input type="email" placeholder="Email" name="email"
ng-model="model.email" required>
I'd like the 'required' message to appear when the input is empty, and when it's non-empty, I'd like the 'email' message to appear conditionally if angular email validation passes.
As you'll see in the fiddle, both messages appear and disappear together, even though, as I use the chrome inspector, the $invalid classes on the input seem to change appropriately. This casts suspicion on the ng-show expression for the errors, but no matter what I try there I get the same behavior.
I've seen a couple answers (like this one) that use a lot of code, but that answer seems a little roundabout. I'm new to web, and already appalled by how bulky the html/code can get (each time I learn about a new streamlining idea, mine seems to double in size)
Thanks in advance.
Change the expression for required to
<label for="email">Email <small class="help-inline" ng-show="!form.email.$viewValue">
and it would work.
The problem with Angular is that it does not allow invalid data in the model. So unless you provide a valid email value the linked model property remains empty and both the required and email validation fail.