Shortened 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
As soon as TJ Crowder was able to specify the reflected properties , I found out that the following syntax is incorrect :
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 have to 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"];
By setting the value of the attribute to true, you mistakenly set it to a String object, and not to the HtmlAttribute object that it needs:
element.attributes["foo"] = "true"; //error because "true" is not a HtmlAttribute object element.setAttribute("foo", "true"); //error because "true" is not an HtmlAttribute object
The conceptually correct idea (expressed in a typed language) is:
HtmlAttribute attribute = new HtmlAttribute(); attribute.value = ""; element.attributes["required"] = attribute;
That's why:
getAttribute(name)setAttribute(name, value)
exist. They do the work of assigning a value to the HtmlAttribute object inside.
In addition, some attributes are reflected . This means that you can access them more conveniently 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!
Test cases
This led to testing the use of the required attribute, comparing the values returned through the attribute, and the reflected property.
document.getElementById("name").required; document.getElementById("name").getAttribute("required");
with the 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)
An attempt to directly access the .attributes collection is incorrect. 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 collection directly. You are not manipulating attribute values, but objects that represent the attributes themselves.
How to install the required?
What is the correct way to set the required attribute? You have two options: either a reflected property, or through the correct setting of 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 dictates that it should only be given an empty string "" indicating the truth. 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 an 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 clean necessarily?
The trick when trying to remove the required attribute is that it is easy to accidentally turn it on:
edName.removeAttribute("required"); //Correct edName.required = false; //Correct
With invalid methods:
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 you can also use any falsey values to disable it, and true values to enable it. But just stick to truth and falsehood for clarity.
How to check for required ?
Check for the attribute using .hasAttribute("required") :
if (edName.hasAttribute("required")) { }
You can also check this via the .required boolean property:
if (edName.required) { }