Removing invalid marker from input field - html

So, I have an input field that sends up a flag if the entered text is not exactly seven digits long. I used oninvalid to give it a customized error message if you try to save the data with a shorter string. The problem is that, once triggered, it will retain the red border and the error message, even after a valid string has been entered and the save button pressed again. Fields without customized error messages work fine. Any ideas what might be causing this, or a way to force it to clear the invalid flag?
Worth noting, I am not actually using a submit call, but making an angularJS call instead.
<form name="myForm" class="myForm" required>
<input name="barcode_num" size="7" type="text" class="form-control" maxlength="7" ng-required="ctrl.barcodeRequired" ng-model="ctrl.barcode" pattern=".{0}|.{7}" oninvalid="this.setCustomValidity('Barcode must be exactly 7 characters')" />
....
<button ng-click="ctrl.submitButton()" type="submit">SAVE</button>
</form>

I would recommend checking out docs.angularjs.org/api/ng/type/form.FormController and docs.angularjs.org/guide/forms. These details how to use the built in angular form controller to hide and show errors and classes.
Essentially you can use a span for the error, and using the built in $error properties, you can display the message like so:
<span ng-show="myForm.barcode_num.$invalid">Barcode must be exactly 7 characters</span>
And in your input, you can use ng-class to have angular update your classes. You can add the class for the red border like so:
<input ... ng-class="{ 'red-border-class': myForm.barcode_num.$invalid }" />
If you read through those docs, you will see there are numerous different validation properties. You can validate the entire form or each named input. You can also have multiple spans for showing different error messages.

Related

Pre-validation of an input field in HTML

Is there any way to validate inputs in the form using HMTL?
For example:
<input type="text" class="input-text error"
aria-required="true" placeholder="Enter your name *"
aria-invalid="true" required />
If user adds a special character to input, an error message saying "Characters are not allowed" should be shown below the input box.
First of all, client-side form validation is the greatest feature coming with the HTML5. Client-side form validation helps you to ensure data submitted matches the requirements. To get more detail about it you can visit here.
Important Note
Client-side form validation is an initial check, You should not use data coming from the form on the server side without checking it. It just a feature for good user experience. Because client-side validation is too easy to manipulate, so users can still easily send data that you do not want to on your server.
Solution
In this question, the best solution is; using HTML attribute pattern. The pattern attribute defines a regular expression the form control's value should match. To get more detail about pattern attribute you can visit the this page.
Below regexp you need.
^[a-zA-Z0-9]{5,12}$
It works like that;
It should contains only alphanumeric.
Minumum 5 and maximum 10
character.
You can use below code to integrate it with input field.
<form action="">
<input type="text" name="name" required
pattern="[a-zA-Z0-9]{5,12}" title="No special character">
<input type="submit">
</form>
Usually, to check inputs from html tags, you can create a javascript function to check your needs which is called everytime the user type in your input with the "onkeyup()" function.
The "onkeyup" keyword will trigger the function everytime user type in your field
<input type="text" onkeyup="myFunctionToCheck()">
<script>
myFunctionToCheck(){
//Here check your needs
}
</script>

What is required to make browsers send "submit"-input names to the server?

I need to debug missing data in some from POSTed to the server and after reading lots of tutorials and following other examples about that aspect, I still can't find my problem. The use case is pretty simple in theory: Have one form with two submit buttons to trigger different implementation on the server side.
According to lots of tutorials and examples, the submit-buttons should send their name if they have a name-attribute, while values should not be sent at all. The naming thing seems to differ according server side programming languages, sometimes it's some_name and sometimes some_name[], but that doesn't make any difference for me currently.
My problem is that whatever HTML I create, inputs of type submit are never part of the POSTed data. OTOH, pretty much the same HTML as button works as expected: If the button is used to submit the form, its name and even value are part of the POSTed data. When other inputs are clicked to submit, no names of any submit-input are available in the data.
So, with the exact same form, reaching the exact same endpoint, using same browser etc., the following DOES NOT provide any hint to the clicked button in the POSTed data:
<input type="submit"
name="foobar input"
value="foobar input"
title="foobar input"
/>
While the following OTOH does:
<button type="submit"
name="foobar button"
value="foobar button"
title="foobar button">
foobar button
</button>
So, should the input work the same way like the button does in theory? Or is the HTML wrong and I'm not able to spot the error? Sending the form itself works in both cases, though. So the browser obviously knows about the submit-input and its purpose.
Or have something changed the last years in modern browsers and submit-inputs are not part of POSTed data at all anymore for some reason? I can't remember the need to have multiple submits on a form for years.
How does a minimal example using a submit-input sending its name look like and tested to work for you? And in which browser? I tested an up-to-date Chromium based Opera and IE 11 and neither did include submit names.
Thanks!
OPINION: I would personally NEVER use more than one word in the name of a submit button
FACT: If that word is "submit" or you have id="submit" then you will not be able to programmatically submit the form using .submit()
FACT if you have script that disables the form element, it will not be sent to the server
Conclusion
In my experience and according to documentation - If you have the following
<form>
...................
<button type="submit"
name="whatever you want here but I would only use one name and NOT submit">Whatever</button>
</form>
OR
<form>
...................
<input type="submit"
name="whatever you want here but I would only use one name and NOT submit" value"Whatever">
</form>
your server will receive the button as name=value in the POST array if method = post and in the GET if nothing or method=get AND in the REQUEST array in either case (assuming PHP)
TEST PAGE
<form method="post" action="testsubmit.php">
Did not work according to OP<br/>
But it actually DOES work if not disabled from elsewhere <br/>
<input type="submit"
name="foobar input"
value="foobar input"
title="foobar input"
/>
<hr/>
<input type="text" name="sentField" value="This WILL be sent to the server" style="width:300px"/>
<hr/>
<input type="text" name="disField" disabled value="This will NOT be sent to the server" style="width:300px"/>
<hr/>
Does work
<button type="submit"
name="foobar button"
value="foobar button"
title="foobar button">
foobar button
</button>
</form>

Angular 2 - Basic form validation not working anymore

I have an angular 2 application which contains a basic form with inputs and basic html validation. Something like:
<form (onSubmit)="submit()">
<input type="email" />
<input type="submit" value="save" />
</form>
This worked about a week or two ago. Today, I was testing my application and noticed that it's completely ignoring any basic validation like type, pattern, max, min, etc.
In this case, it should complain when you type in a value without the # symbol. However, it isn't complaining anymore. You can type whatever you want in the input field.
Any idea how this could happen?
I was having this issue too. So I searched and found this.
Basically by default angular is adding something called novalidate.
If you guys want to use browser's native form validation just add ngNativeValidate attribute:
<form ngNativeValidate></form>

Input type="number" with not mandatory step attribute

I have an input in my form with a step defined to 3:
<form>
<input name="surface" id="surface" type="number" step="3" />
</form>
I would like to be able to enter a number not multiple of the step, but it's refused at validation by the browser.
In example, if I insert "2.5" in the input, the message error I've got is:
Please select a valid value. The 2 closest values are 0 and 3.
Is it possible to make this step not mandatory?
I've tried to add novalidate="novalidate" as attribute but it doesn't work.
After more research, it appears it's not possible to make the step non mandatory on an HTML5 input.
I'll have to implement a custom number input (in jQuery or else) to achieve this.

An invalid form control with name='' is not focusable

In Google Chrome some customers are not able to proceed to my payment page.
When trying to submit a form I get this error:
An invalid form control with name='' is not focusable.
This is from the JavaScript console.
I read that the problem could be due to hidden fields having the required attribute.
Now the problem is that we are using .net webforms required field validators, and not the html5 required attribute.
It seems random who gets this error.
Is there anyone who knows a solution for this?
This issue occurs on Chrome if a form field fails validation, but due to the respective invalid control not being focusable the browser's attempt to display the message "Please fill out this field" next to it fails as well.
A form control may not be focusable at the time validation is triggered for several reasons. The two scenarios described below are the most prominent causes:
The field is irrelevant according to the current context of the business logic. In such a scenario, the respective control should be disabled or removed from the DOM or not be marked with the required attribute at that point.
Premature validation may occur due to a user pressing ENTER key on an input. Or a user clicking on a button/input control in the form which has not defined the type attribute of the control correctly. If the type attribute of a button is not set to button, Chrome (or any other browser for that matter) performs a validation each time the button is clicked because submit is the default value of a button's type attribute.
To solve the problem, if you have a button on your page that does something else other than submit or reset, always remember to do this: <button type="button">.
Adding a novalidate attribute to the form will help:
<form name="myform" novalidate>
In your form, You might have hidden input having required attribute:
<input type="hidden" required />
<input type="file" required style="display: none;"/>
The form can't focus on those elements, you have to remove required from all hidden inputs, or implement a validation function in javascript to handle them if you really require a hidden input.
In case anyone else has this issue, I experienced the same thing. As discussed in the comments, it was due to the browser attempting to validate hidden fields. It was finding empty fields in the form and trying to focus on them, but because they were set to display:none;, it couldn't. Hence the error.
I was able to solve it by using something similar to this:
$("body").on("submit", ".myForm", function(evt) {
// Disable things that we don't want to validate.
$(["input:hidden, textarea:hidden, select:hidden"]).attr("disabled", true);
// If HTML5 Validation is available let it run. Otherwise prevent default.
if (this.el.checkValidity && !this.el.checkValidity()) {
// Re-enable things that we previously disabled.
$(["input:hidden, textarea:hidden, select:hidden"]).attr("disabled", false);
return true;
}
evt.preventDefault();
// Re-enable things that we previously disabled.
$(["input:hidden, textarea:hidden, select:hidden"]).attr("disabled", false);
// Whatever other form processing stuff goes here.
});
Also, this is possibly a duplicate of "Invalid form control" only in Google Chrome
In my case the problem was with the input type="radio" required being hidden with:
visibility: hidden;
This error message will also show if the required input type radio or checkbox has a display: none; CSS property.
If you want to create custom radio/checkbox inputs where they must be hidden from the UI and still keep the required attribute, you should instead use the:
opacity: 0; CSS property
None of the previous answers worked for me, and I don't have any hidden fields with the required attribute.
In my case, the problem was caused by having a <form> and then a <fieldset> as its first child, which holds the <input> with the required attribute. Removing the <fieldset> solved the problem. Or you can wrap your form with it; it is allowed by HTML5.
I'm on Windows 7 x64, Chrome version 43.0.2357.130 m.
Not only required field as mentioned in other answers. Its also caused by placing an <input> field in a hidden <div> which holds an invalid value.
Consider below example,
<div style="display:none;">
<input type="number" name="some" min="1" max="50" value="0">
</div>
This throws the same error. So make sure the <input> fields inside hidden <div> doesnt hold any invalid value.
This issue occurs when you provide style="display: none;" and required attribute to the input field, and there will be validation on submit.
for example:
<input type="text" name="name" id="name" style="display: none;" required>
This issue can be resolved by removing required attribute from the input field from your HTML. If you need to add required attribute, add it dynamically. If you are using JQuery, use below code:
$("input").prop('required',true);
If you need to remove this field dynamically,
$("input").prop('required',false);
You can also make use of plain Javascript if you are not using JQuery:
document.getElementById('element_id').removeAttribute('required');
Yet another possibility if you're getting the error on a checkbox input. If your checkboxes use custom CSS which hides the default and replaces it with some other styling, this will also trigger the not focusable error in Chrome on validation error.
I found this in my stylesheet:
input[type="checkbox"] {
visibility: hidden;
}
Simple fix was to replace it with this:
input[type="checkbox"] {
opacity: 0;
}
It can be that you have hidden (display: none) fields with the required attribute.
Please check all required fields are visible to the user :)
For me this happens, when there's a <select> field with pre-selected option with value of '':
<select name="foo" required="required">
<option value="" selected="selected">Select something</option>
<option value="bar">Bar</option>
<option value="baz">Baz</option>
</select>
Unfortunately it's the only cross-browser solution for a placeholder (How do I make a placeholder for a 'select' box?).
The issue comes up on Chrome 43.0.2357.124.
For Select2 Jquery problem
The problem is due to the HTML5 validation cannot focus a hidden invalid element.
I came across this issue when I was dealing with jQuery Select2 plugin.
Solution
You could inject an event listener on and 'invalid' event of every element of a form so that you can manipulate just before the HTML5 validate event.
$('form select').each(function(i){
this.addEventListener('invalid', function(e){
var _s2Id = 's2id_'+e.target.id; //s2 autosuggest html ul li element id
var _posS2 = $('#'+_s2Id).position();
//get the current position of respective select2
$('#'+_s2Id+' ul').addClass('_invalid'); //add this class with border:1px solid red;
//this will reposition the hidden select2 just behind the actual select2 autosuggest field with z-index = -1
$('#'+e.target.id).attr('style','display:block !important;position:absolute;z-index:-1;top:'+(_posS2.top-$('#'+_s2Id).outerHeight()-24)+'px;left:'+(_posS2.left-($('#'+_s2Id).width()/2))+'px;');
/*
//Adjust the left and top position accordingly
*/
//remove invalid class after 3 seconds
setTimeout(function(){
$('#'+_s2Id+' ul').removeClass('_invalid');
},3000);
return true;
}, false);
});
If you have any field with required attribute which is not visible during the form submission, this error will be thrown. You just remove the required attribute when your try to hide that field. You can add the required attribute in case if you want to show the field again. By this way, your validation will not be compromised and at the same time, the error will not be thrown.
It's weird how everyone is suggesting to remove the validation, while validation exists for a reason...
Anyways, here's what you can do if you're using a custom control, and want to maintain the validation:
1st step. Remove display none from the input, so the input becomes focusable
.input[required], .textarea[required] {
display: inline-block !important;
height: 0 !important;
padding: 0 !important;
border: 0 !important;
z-index: -1 !important;
position: absolute !important;
}
2nd step. Add invalid event handler on the input to for specific cases if the style isn't enough
inputEl.addEventListener('invalid', function(e){
//if it's valid, cancel the event
if(e.target.value) {
e.preventDefault();
}
});
It happens if you hide an input element which has a required attribute.
Instead of using display:none you can use opacity: 0;
I also had to use some CSS rules (like position:absolute) to position my element perfectly.
Yea.. If a hidden form control has required field then it shows this error. One solution would be to disable this form control. This is because usually if you are hiding a form control it is because you are not concerned with its value. So this form control name value pair wont be sent while submitting the form.
I came here to answer that I had triggered this issue myself based on NOT closing the </form> tag AND having multiple forms on the same page. The first form will extend to include seeking validation on form inputs from elsewhere. Because THOSE forms are hidden, they triggered the error.
so for instance:
<form method="POST" name='register' action="#handler">
<input type="email" name="email"/>
<input type="text" name="message" />
<input type="date" name="date" />
<form method="POST" name='register' action="#register">
<input type="text" name="userId" />
<input type="password" name="password" />
<input type="password" name="confirm" />
</form>
Triggers
An invalid form control with name='userId' is not focusable.
An invalid form control with name='password' is not focusable.
An invalid form control with name='confirm' is not focusable.
Another possible cause and not covered in all previous answers when you have a normal form with required fields and you submit the form then hide it directly after submission (with javascript) giving no time for validation functionality to work.
The validation functionality will try to focus on the required field and show the error validation message but the field has already been hidden, so "An invalid form control with name='' is not focusable." appears!
Edit:
To handle this case simply add the following condition inside your submit handler
submitHandler() {
const form = document.body.querySelector('#formId');
// Fix issue with html5 validation
if (form.checkValidity && !form.checkValidity()) {
return;
}
// Submit and hide form safely
}
Edit: Explanation
Supposing you're hiding the form on submission, this code guarantees that the form/fields will not be hidden until form become valid. So, if a field is not valid, the browser can focus on it with no problems as this field is still displayed.
There are many ways to fix this like
Add novalidate to your form but its totally wrong as it will remove form validation which will lead to wrong information entered by the users.
<form action="...." class="payment-details" method="post" novalidate>
Use can remove the required attribute from required fields which is also wrong as it will remove form validation once again.
Instead of this:
<input class="form-control" id="id_line1" maxlength="255" name="line1" placeholder="First line of address" type="text" required="required">
Use this:
<input class="form-control" id="id_line1" maxlength="255" name="line1" placeholder="First line of address" type="text">
Use can disable the required fields when you are not going to submit the form instead of doing some other option. This is the recommended solution in my opinion.
like:
<input class="form-control" id="id_line1" maxlength="255" name="line1" placeholder="First line of address" type="text" disabled="disabled">
or disable it through javascript / jquery code dependes upon your scenario.
It will show that message if you have code like this:
<form>
<div style="display: none;">
<input name="test" type="text" required/>
</div>
<input type="submit"/>
</form>
You may try .removeAttribute("required") for those elements which are hidden at the time of window load. as it is quite probable that the element in question is marked hidden due to javascript (tabbed forms)
e.g.
if(document.getElementById('hidden_field_choice_selector_parent_element'.value==true){
document.getElementById('hidden_field').removeAttribute("required");
}
This should do the task.
It worked for me... cheers
There are things that still surprises me... I have a form with dynamic behaviour for two different entities. One entity requires some fields that the other don't.
So, my JS code, depending on the entity, does something like:
$('#periodo').removeAttr('required');
$("#periodo-container").hide();
and when the user selects the other entity:
$("#periodo-container").show();
$('#periodo').prop('required', true);
But sometimes, when the form is submitted, the issue apppears: "An invalid form control with name=periodo'' is not focusable (i am using the same value for the id and name).
To fix this problem, you have to ensurance that the input where you are setting or removing 'required' is always visible.
So, what I did is:
$("#periodo-container").show(); //for making sure it is visible
$('#periodo').removeAttr('required');
$("#periodo-container").hide(); //then hide
Thats solved my problem... unbelievable.
In my case..
ng-show was being used.
ng-if was put in its place and fixed my error.
Wow, a lot of answers here!
If the problem is <input type="hidden" required="true" />, then you can solve this in just a few lines.
The logic is simple and straight-forward:
Mark every required input on page-load with a data-required class.
On submit, do two things: a) Add required="true" to all data-required inputs. b) Remove required="true"` from all hidden inputs.
HTML
<input type="submit" id="submit-button">
Pure JavaScript
document.querySelector('input,textarea,select').filter('[required]').classList.add('data-required');
document.querySelector('#submit-button').addEventListener('click', function(event) {
document.querySelector('.data-required').prop('required', true);
document.querySelector('input,textarea,select').filter('[required]:hidden').prop('required', false);
return true;
}
jQuery
$('input,textarea,select').filter('[required]').addClass('data-required');
$('#submit-button').on('click', function(event) {
$('.data-required').prop('required', true);
$('input,textarea,select').filter('[required]:hidden').prop('required', false);
return true;
}
For Angular use:
ng-required="boolean"
This will only apply the html5 'required' attribute if the value is true.
<input ng-model="myCtrl.item" ng-required="myCtrl.items > 0" />
I found same problem when using Angular JS. It was caused from using required together with ng-hide. When I clicked on the submit button while this element was hidden then it occurred the error An invalid form control with name='' is not focusable. finally!
For example of using ng-hide together with required:
<input type="text" ng-hide="for some condition" required something >
I solved it by replacing the required with ng-pattern instead.
For example of solution:
<input type="text" ng-hide="for some condition" ng-pattern="some thing" >
Not just only when specify required, I also got this issue when using min and max e.g.
<input type="number" min="1900" max="2090" />
That field can be hidden and shown based on other radio value. So, for temporary solution, I removed the validation.
I have seen this question asked often and have come across this 'error' myself. There have even been links to question whether this is an actual bug in Chrome.
This is the response that occurs when one or more form input type elements are hidden and these elements have a min/max limit (or some other validation limitation) imposed.
On creation of a form, there are no values attributed to the elements, later on the element values may be filled or remain unchanged.
At the time of submit, the form is parsed and any hidden elements that are outside of these validation limits will throw this 'error' into the console and the submit will fail. Since you can't access these elements (because they are hidden) this is the only response that is valid.
This isn't an actual fault nor bug. It is an indication that there are element values about to be submitted that are outside of the limits stipulated by one or more elements.
To fix this, assign a valid default value to any elements that are hidden in the form at any time before the form is submitted, then these 'errors' will never occur. It is not a bug as such, it is just forcing you into better programming habits.
NB: If you wish to set these values to something outside the validation limits then use form.addEventListener('submit', myFunction) to intercept the 'submit' event and fill in these elements in "myFunction". It seems the validation checking is performed before "myFunction() is called.
Its because there is a hidden input with required attribute in the form.
In my case, I had a select box and it is hidden by jquery tokenizer using inline style. If I dont select any token, browser throws the above error on form submission.
So, I fixed it using the below css technique :
select.download_tag{
display: block !important;//because otherwise, its throwing error An invalid form control with name='download_tag[0][]' is not focusable.
//So, instead set opacity
opacity: 0;
height: 0px;
}
For other AngularJS 1.x users out there, this error appeared because I was hiding a form control from displaying instead of removing it from the DOM entirely when I didn't need the control to be completed.
I fixed this by using ng-if instead of ng-show/ng-hide on the div containing the form control requiring validation.
Hope this helps you fellow edge case users.