I'm trying to mark a text
input box as required in Javascript.
<input id="edName" type="text" id="name">
If the field was originally marked required
:
<form> <input id="edName" type="text" id="name" required><br> <input type="submit" value="Search"> </form>
When the user attempts to submit, they receive a validation error:
But now I want to set the required
property at "runtime" via Javascript:
<form> <input id="edName" type="text" id="name"><br> <input type="submit" value="Search"> </form>
Use the corresponding script:
//recommended W3C HTML5 syntax for boolean attributes document.getElementById("edName").attributes["required"] = "";
No validation checks, no blocking unless I submit now.
Settings What is the correct way to validate Boolean attributes in HTML5?
jsFiddle
HTML5 Validation required
Attributes logged as Boolean
:
4.10.7.3.4
required
Properties
required
The property is a Boolean property. When specified, this element is required.
There are a lot of annoying things about how to define boolean
properties. HTML5 specification comments:
The presence of a Boolean attribute on theelement represents a true value, and the absence of this attribute represents a false value.
If the attribute is present, its value must be the empty string or an ASCII case-insensitive value that matches the attribute's canonical name and has no leading or trailing spaces.
This means you can specify the required
boolean attribute in two different ways:
edName.attributes.required = ""; //the empty string edName.attributes.required = "required"; //the attribute's canonical name
When you look at my jsFiddle for this question, you'll notice that if the required
attribute is defined in the tag:
<input id="edName" type="text" id="name" required>
Then the value of the attribute is not an empty string , nor is it the canonical name of the attribute:
edName.attributes.required = [object Attr]
This may lead to a solution.
P粉2698479972023-10-14 00:45:14
required
is a reflective attribute (e.g. id
, name
, type
, etc.), so:
element.required = true;
...where element
is the actual input
DOM element, for example:
document.getElementById("edName").required = true;
(Just for completeness.)
reply:
That's because required
in this code is a property object, not a string; property
is< code>NamedNodeMap Its value is Attr代码>object
. To get the value of one of these, you need to look at its value
property. But for boolean properties, the value is irrelevant; the property is either present in the map (true) or not (false).
So if required
is not reflected, you can set it by adding the attribute:
element.setAttribute("required", "");
...Equivalent to element.required = true
. You can clear it by deleting it completely:
element.removeAttribute("required");
...Equivalent to element.required = false
.
But we don't have to do this for required
because it's already reflected.
P粉1333218392023-10-14 00:39:46
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
Once T.J. Crowder managed to point out the reflected properties, I learned the following syntax error:
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 pass 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 the attribute value to "true", you are mistakenly setting it to a String object instead of 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 type language) is:
HtmlAttribute attribute = new HtmlAttribute(); attribute.value = ""; element.attributes["required"] = attribute;
Here’s why:
getAttribute(name)
setAttribute(name, value)
exist. They are responsible for assigning values to the internal HtmlAttribute objects.
In addition, it also reflects some attributes. This means you have better access to them via 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 incorrectly use the .attributes
collection:
element.attributes.required = true; //WRONG! if (element.attributes.required) {...} //WRONG! element.attributes.required = false; //WRONG!
This results in testing around the use of the required
attribute, comparing the value returned via that attribute to the reflected attribute
document.getElementById("name").required; document.getElementById("name").getAttribute("required");
result:
HTML .required .getAttribute("required") ========================== =============== ========================= false (Boolean) null (Object) true (Boolean) "" (String) true (Boolean) "" (String) true (Boolean) "required" (String) true (Boolean) "true" (String) true (Boolean) "false" (String) true (Boolean) "0" (String)
It is an error to attempt to access the .attributes
collection directly. It returns an object representing a DOM property:
edName.attributes["required"] => [object Attr] edName.attributes.required => [object Attr]
This explains why you should never talk directly to the .attributes
collection. You are not manipulating the value of the property, you are manipulating the object that represents the property itself.
What is the correct way to set required
on a property? You have two options, either reflected properties or by setting the properties correctly:
element.setAttribute("required", ""); //Correct element.required = true; //Correct
Strictly speaking, any other value will "set" the property. However, the definition of the Boolean
property states that it can only be set to the empty string ""
to indicate true. The following methods can set the required
Boolean attribute,
But don’t 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 have learned that it is an error to try to set the property directly:
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
TryRemove required
The trick when using an attribute is that it's easy to accidentally open it:
edName.removeAttribute("required"); //Correct edName.required = false; //Correct
Invalid method:
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 reflection's .required
property, you can also use any "falsey" value to turn it off and use a true value to turn it on. But for the sake of clarity, stick to right and wrong.
required
? Check whether the attribute exists through the .hasAttribute("required")
method:
if (edName.hasAttribute("required")) { }
You can also check via the Boolean reflected .required
property:
if (edName.required) { }