How to set HTML5 required attribute in Javascript?
Short version
element.setAttribute("required", ""); //turns required on
element.required = true; //turns required on through reflected attribute
jQuery(element).attr('required', ''); //turns required on
$("#elementId").attr('required', ''); //turns required on
element.removeAttribute("required"); //turns required off
element.required = false; //turns required off through reflected attribute
jQuery(element).removeAttr('required'); //turns required off
$("#elementId").removeAttr('required'); //turns required off
if (edName.hasAttribute("required")) { } //check if required
if (edName.required) { } //check if required using reflected attribute
Long Version
Once T.J. Crowder managed to point out reflected properties, i learned that following syntax is wrong:
element.attributes["name"] = value; //bad! Overwrites the HtmlAttribute object
element.attributes.name = value; //bad! Overwrites the HtmlAttribute object
value = element.attributes.name; //bad! Returns the HtmlAttribute object, not its value
value = element.attributes["name"]; //bad! Returns the HtmlAttribute object, not its value
You must go through element.getAttribute
and element.setAttribute
:
element.getAttribute("foo"); //correct
element.setAttribute("foo", "test"); //correct
This is because the attribute actually contains a special HtmlAttribute object:
element.attributes["foo"]; //returns HtmlAttribute object, not the value of the attribute
element.attributes.foo; //returns HtmlAttribute object, not the value of the attribute
By setting an attribute value to "true", you are mistakenly setting it to a String object, rather than the HtmlAttribute object it requires:
element.attributes["foo"] = "true"; //error because "true" is not a HtmlAttribute object
element.setAttribute("foo", "true"); //error because "true" is not an HtmlAttribute object
Conceptually the correct idea (expressed in a typed language), is:
HtmlAttribute attribute = new HtmlAttribute();
attribute.value = "";
element.attributes["required"] = attribute;
This is why:
getAttribute(name)
setAttribute(name, value)
exist. They do the work on assigning the value to the HtmlAttribute object inside.
On top of this, some attribute are reflected. This means that you can access them more nicely from Javascript:
//Set the required attribute
//element.setAttribute("required", "");
element.required = true;
//Check the attribute
//if (element.getAttribute("required")) {...}
if (element.required) {...}
//Remove the required attribute
//element.removeAttribute("required");
element.required = false;
What you don't want to do is mistakenly use the .attributes
collection:
element.attributes.required = true; //WRONG!
if (element.attributes.required) {...} //WRONG!
element.attributes.required = false; //WRONG!
Testing Cases
This led to testing around the use of a required
attribute, comparing the values returned through the attribute, and the reflected property
document.getElementById("name").required;
document.getElementById("name").getAttribute("required");
with results:
HTML .required .getAttribute("required")
========================== =============== =========================
<input> false (Boolean) null (Object)
<input required> true (Boolean) "" (String)
<input required=""> true (Boolean) "" (String)
<input required="required"> true (Boolean) "required" (String)
<input required="true"> true (Boolean) "true" (String)
<input required="false"> true (Boolean) "false" (String)
<input required="0"> true (Boolean) "0" (String)
Trying to access the .attributes
collection directly is wrong. It returns the object that represents the DOM attribute:
edName.attributes["required"] => [object Attr]
edName.attributes.required => [object Attr]
This explains why you should never talk to the .attributes
collect directly. You're not manipulating the values of the attributes, but the objects that represent the attributes themselves.
How to set required?
What's the correct way to set required
on an attribute? You have two choices, either the reflected property, or through correctly setting the attribute:
element.setAttribute("required", ""); //Correct
edName.required = true; //Correct
Strictly speaking, any other value will "set" the attribute. But the definition of Boolean
attributes dictate that it should only be set to the empty string ""
to indicate true. The following methods all work to set the required
Boolean attribute,
but do not use them:
element.setAttribute("required", "required"); //valid, but not preferred
element.setAttribute("required", "foo"); //works, but silly
element.setAttribute("required", "true"); //Works, but don't do it, because:
element.setAttribute("required", "false"); //also sets required boolean to true
element.setAttribute("required", false); //also sets required boolean to true
element.setAttribute("required", 0); //also sets required boolean to true
We already learned that trying to set the attribute directly is wrong:
edName.attributes["required"] = true; //wrong
edName.attributes["required"] = ""; //wrong
edName.attributes["required"] = "required"; //wrong
edName.attributes.required = true; //wrong
edName.attributes.required = ""; //wrong
edName.attributes.required = "required"; //wrong
How to clear required?
The trick when trying to remove the required
attribute is that it's easy to accidentally turn it on:
edName.removeAttribute("required"); //Correct
edName.required = false; //Correct
With the invalid ways:
edName.setAttribute("required", null); //WRONG! Actually turns required on!
edName.setAttribute("required", ""); //WRONG! Actually turns required on!
edName.setAttribute("required", "false"); //WRONG! Actually turns required on!
edName.setAttribute("required", false); //WRONG! Actually turns required on!
edName.setAttribute("required", 0); //WRONG! Actually turns required on!
When using the reflected .required
property, you can also use any "falsey" values to turn it off, and truthy values to turn it on. But just stick to true and false for clarity.
How to check for required
?
Check for the presence of the attribute through the .hasAttribute("required")
method:
if (edName.hasAttribute("required"))
{
}
You can also check it through the Boolean reflected .required
property:
if (edName.required)
{
}
HTML5 form required attribute. Set custom validation message?
Use setCustomValidity
:
document.addEventListener("DOMContentLoaded", function() {
var elements = document.getElementsByTagName("INPUT");
for (var i = 0; i < elements.length; i++) {
elements[i].oninvalid = function(e) {
e.target.setCustomValidity("");
if (!e.target.validity.valid) {
e.target.setCustomValidity("This field cannot be left blank");
}
};
elements[i].oninput = function(e) {
e.target.setCustomValidity("");
};
}
})
I changed to vanilla JavaScript from Mootools as suggested by @itpastorn in the comments, but you should be able to work out the Mootools equivalent if necessary.
Edit
I've updated the code here as setCustomValidity
works slightly differently to what I understood when I originally answered. If setCustomValidity
is set to anything other than the empty string it will cause the field to be considered invalid; therefore you must clear it before testing validity, you can't just set it and forget.
Further edit
As pointed out in @thomasvdb's comment below, you need to clear the custom validity in some event outside of invalid
otherwise there may be an extra pass through the oninvalid
handler to clear it.
HTML5 required attribute one of two fields
Update 2020-06-21 (ES6):
Given that jQuery has become somewhat unfashionable in the JavaScript world and that ES6 provides some nice syntactic sugar, I have written a pure JS equivalent to the original answer:
document.addEventListener('DOMContentLoaded', function() {
const inputs = Array.from(
document.querySelectorAll('input[name=telephone], input[name=mobile]')
);
const inputListener = e => {
inputs
.filter(i => i !== e.target)
.forEach(i => (i.required = !e.target.value.length));
};
inputs.forEach(i => i.addEventListener('input', inputListener));
});
<form method="post">
Telephone:
<input type="tel" name="telephone" value="" required>
<br>Mobile:
<input type="tel" name="mobile" value="" required>
<br>
<input type="submit" value="Submit">
</form>
dynamically change required atributte for html5 input control
required
is a so called boolean attribute. It's mere existence on the element indicates that the input is required. It doesn't matter which value it has.
Remove the attribute if you want to make the input optional (same goes for all boolean attributes):
document.getElementById("website").removeAttribute("required");
Alternatively, access the DOM property and set it to false
:
document.getElementById("website").required = false;
You should usually prefer dealing with properties than with attributes. It also makes the intentions clearer.
Required attribute HTML5
I just ran into this issue with Safari 5 and it has been an issue with Opera 10 for some time, but I never spent time to fix it. Now I need to fix it and saw your post but no solution yet on how to cancel the form. After much searching I finally found something:
http://www.w3.org/TR/html5/forms.html#attr-fs-formnovalidate
<input type=submit formnovalidate name=cancel value="Cancel">
Works on Safari 5 and Opera 10.
HTML5 'Required' attribute for form validation: Good idea or bad idea
Client-side form validation is a good way for enhancing user experience, it also provides some styling that can help to communicate that an input is required.
But you will allways still have to validate any data submitted on the server, making sure is clean and safe data. The required
attribute can be manipulated by a malicious user.
Javascript - Toggle html5 required= attribute based on form selection
Here is a newer version using addEventListener
window.addEventListener("DOMContentLoaded", () => {
const sel = document.querySelector("[name=InquiryType]"),
terms = document.getElementById("terms_target"),
form = document.getElementById("myForm"),
agree = form.checked; // checked is a poor name for a field
toggleAgree = () => {
const show = ["1", "2"].includes(sel.value);
terms.hidden = !show;
agree.required = show;
};
sel.addEventListener("change", toggleAgree)
toggleAgree(); // initialise
})
<form action="process_affiliate.php" id="myForm" method="post">
<select name="InquiryType" required>
<option value="">Please Select Your Inquiry Type</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div id="terms_target" hidden>
<input type="checkbox" name="checked" value="Checked" required="" />I agree to the terms
</div>
<input type="submit" value="Submit">
</form>
Related Topics
How to Programmatically Tell an HTML Select to Drop Down (For Example, Due to Mouseover)
How to Know Which Radio Button Is Selected Via Jquery
Jquery Id Selector Works Only For the First Element
What's the Effect of Adding 'Return False' to a Click Event Listener
Clearing ≪Input Type='File' /≫ Using Jquery
How to Store an Array in Localstorage
How to Stop Event Propagation With Inline Onclick Attribute
Set the Value of an Input Field
"Submit Is Not a Function" Error in JavaScript
Changing Website Favicon Dynamically
Rendering HTML Inside Textarea
Show/Hide 'Div' Using JavaScript
Creating a Textarea With Auto-Resize
How to Write Data to File Using Only JavaScript
How to Use a C++ Library from Node.Js
Encryption in JavaScript and Decryption With PHP
Do You Need Text/JavaScript Specified in Your ≪Script≫ Tags