Wie setze ich das erforderliche HTML5-Attribut in Javascript?

88

Ich versuche, ein textEingabefeld als in Javascript erforderlich zu markieren .

<input id="edName" type="text" id="name">

Wenn das Feld zunächst markiert als required:

<form>
    <input id="edName" type="text" id="name" required><br>
    <input type="submit" value="Search">
</form>

Wenn der Benutzer versucht zu senden, wird ihm ein Validierungsfehler angezeigt:

Geben Sie hier die Bildbeschreibung ein

Aber jetzt möchte ich das requiredAttribut über Javascript auf "Laufzeit" setzen :

<form>
    <input id="edName" type="text" id="name"><br>
    <input type="submit" value="Search">
</form>

mit dem entsprechenden Skript:

//recommended W3C HTML5 syntax for boolean attributes
document.getElementById("edName").attributes["required"] = "";         

Außer wenn ich jetzt abschicke, gibt es keine Validierungsprüfung, keine Blockierung.

Was ist der richtige Weg, um ein boolesches HTML5-Validierungsattribut festzulegen ?

jsFiddle

Was ist der Wert des Attributs, fragen Sie?

Das HTML5-Validierungsattribut requiredist wie folgt dokumentiertBoolean :

4.10.7.3.4 Das requiredAttribut

Das requiredAttribut ist ein boolesches Attribut . Wenn angegeben, ist das Element erforderlich.

Es gibt viel Handarbeit darüber, wie man ein booleanAttribut definiert . Die HTML5-Spezifikation stellt fest:

Das Vorhandensein eines booleschen Attributs für ein Element repräsentiert den wahren Wert, und das Fehlen des Attributs repräsentiert den falschen Wert.

Wenn das Attribut vorhanden ist, muss sein Wert entweder die leere Zeichenfolge oder ein Wert sein, bei dem der kanonische Name des Attributs nicht zwischen Groß- und Kleinschreibung unterschieden wird, ohne führende oder nachfolgende Leerzeichen.

Dies bedeutet, dass Sie ein required boolesches Attribut auf zwei verschiedene Arten angeben können:

edName.attributes.required = ""; //the empty string
edName.attributes.required = "required"; //the attribute's canonical name

Aber was ist der Wert des Attributs wirklich ?

Wenn Sie sich meine jsFiddle dieses Problems ansehen , werden Sie feststellen, dass, wenn das requiredAttribut im Markup definiert ist:

<input id="edName" type="text" id="name" required>

Dann ist der Wert des Attributs weder die leere Zeichenfolge noch der kanonische Name des Attributs:

edName.attributes.required = [object Attr]

Das könnte zu einer Lösung führen.

Ian Boyd
quelle
4
Ich verstehe nicht, warum sie nicht zulassen required="false", haben sie jemals eine Vorlage geschrieben, bevor sie den Standard geschrieben haben? Bedingte Attribute sind normalerweise ein Schmerz, es ist viel einfacher, diesen Booleschen Wert einfach in den Attributwert zu setzen ...
Christophe Roussy
Ist es möglich, diesen Text manuell über der erforderlichen Eingabe anzuzeigen: "Bitte füllen Sie dieses Feld aus."?
Zygimantus

Antworten:

115

requiredist eine reflektiertes Eigenschaft (wie id, name, type, und so weiter ), so:

element.required = true;

... wo elementist das eigentliche inputDOM-Element, zB:

document.getElementById("edName").required = true;

(Nur der Vollständigkeit halber.)

Re:

Dann ist der Wert des Attributs weder die leere Zeichenfolge noch der kanonische Name des Attributs:

edName.attributes.required = [object Attr]

Das liegt daran, requireddass dieser Code ein Attributobjekt ist , keine Zeichenfolge. attributesist ein, NamedNodeMapdessen Werte AttrObjekte sind . Um den Wert eines von ihnen zu ermitteln, müssen Sie sich dessen valueEigenschaft ansehen . Für ein boolesches Attribut ist der Wert jedoch nicht relevant. Das Attribut ist entweder in der Karte vorhanden (wahr) oder nicht vorhanden (falsch).

Wenn dies required nicht berücksichtigt würde, würden Sie es durch Hinzufügen des Attributs festlegen:

element.setAttribute("required", "");

... was das Äquivalent von ist element.required = true. Sie würden es löschen, indem Sie es vollständig entfernen:

element.removeAttribute("required");

... was das Äquivalent von ist element.required = false.

Aber wir müssen das nicht tun required, da es sich widerspiegelt.

TJ Crowder
quelle
102

Kurzfassung

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

Lange Version

Nachdem es TJ Crowder gelungen war, auf reflektierte Eigenschaften hinzuweisen, stellte ich fest, dass die folgende Syntax falsch ist :

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

Sie müssen durchgehen element.getAttributeund element.setAttribute:

element.getAttribute("foo");         //correct
element.setAttribute("foo", "test"); //correct

Dies liegt daran, dass das Attribut tatsächlich ein spezielles HtmlAttribute- Objekt enthält:

element.attributes["foo"];           //returns HtmlAttribute object, not the value of the attribute
element.attributes.foo;              //returns HtmlAttribute object, not the value of the attribute

Wenn Sie einen Attributwert auf "true" setzen, setzen Sie ihn fälschlicherweise auf ein String- Objekt und nicht auf das erforderliche HtmlAttribute- Objekt:

element.attributes["foo"] = "true";  //error because "true" is not a HtmlAttribute object
element.setAttribute("foo", "true"); //error because "true" is not an HtmlAttribute object

Konzeptionell ist die richtige Idee (ausgedrückt in einer getippten Sprache):

HtmlAttribute attribute = new HtmlAttribute();
attribute.value = "";
element.attributes["required"] = attribute;

Deshalb:

  • getAttribute(name)
  • setAttribute(name, value)

existieren. Sie arbeiten daran, den Wert dem darin enthaltenen HtmlAttribute-Objekt zuzuweisen.

Hinzu kommt, sind einige Attribute reflektiert . Dies bedeutet, dass Sie über Javascript besser auf sie zugreifen können:

//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;

Was Sie nicht tun möchten, ist fälschlicherweise die .attributesSammlung zu verwenden:

element.attributes.required = true;     //WRONG!
if (element.attributes.required) {...}  //WRONG!
element.attributes.required = false;    //WRONG!

Fälle testen

Dies führte zu Tests zur Verwendung eines requiredAttributs, zum Vergleich der über das Attribut zurückgegebenen Werte und der reflektierten Eigenschaft

document.getElementById("name").required;
document.getElementById("name").getAttribute("required");

mit Ergebnissen:

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)

Der Versuch, .attributesdirekt auf die Sammlung zuzugreifen, ist falsch. Es gibt das Objekt zurück, das das DOM-Attribut darstellt:

edName.attributes["required"] => [object Attr]
edName.attributes.required    => [object Attr]

Dies erklärt, warum Sie niemals .attributesdirekt mit der Sammlung sprechen sollten . Sie bearbeiten nicht die Werte der Attribute, sondern die Objekte, die die Attribute selbst darstellen.

Wie wird eingestellt?

Wie kann requiredein Attribut richtig festgelegt werden? Sie haben zwei Möglichkeiten, entweder die reflektierte Eigenschaft oder die korrekte Einstellung des Attributs:

element.setAttribute("required", "");         //Correct
edName.required = true;                       //Correct

Streng genommen "setzt" jeder andere Wert das Attribut. Die Definition von BooleanAttributen schreibt jedoch vor, dass nur die leere Zeichenfolge festgelegt werden muss "", um true anzuzeigen . Die folgenden Methoden dienen alle zum Festlegen des required Booleschen Attributs:

aber benutze sie nicht:

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

Wir haben bereits gelernt, dass der Versuch, das Attribut direkt festzulegen, falsch ist:

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

Wie zu löschen erforderlich?

Der Trick beim Entfernen des requiredAttributs besteht darin, dass es leicht versehentlich aktiviert werden kann:

edName.removeAttribute("required");     //Correct
edName.required = false;                //Correct

Mit den ungültigen Wegen:

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!

Wenn Sie die reflektierte .requiredEigenschaft verwenden, können Sie auch beliebige "Falsey" -Werte verwenden, um sie auszuschalten, und wahrheitsgemäße Werte, um sie einzuschalten. Aber bleiben Sie zur Klarheit einfach bei wahr und falsch.

Wie überprüfe ich required?

Überprüfen Sie das Vorhandensein des Attributs mithilfe der folgenden .hasAttribute("required")Methode:

if (edName.hasAttribute("required"))
{
}

Sie können dies auch über die boolesche reflektierte .requiredEigenschaft überprüfen :

if (edName.required)
{
}
Ian Boyd
quelle
1
Was ist der Unterschied zwischen den Variablen elementund edName?
Faintsignal
1
Eines ist, wo ich vergessen habe, einen bestimmten Elementnamen edName(dh Name Input Box) in den generischen zu konvertieren element.
Ian Boyd
10

Was zählt, ist nicht das Attribut, sondern die Eigenschaft , und ihr Wert ist ein Boolescher Wert.

Sie können es mit einstellen

 document.getElementById("edName").required = true;
Denys Séguret
quelle
10

Und die jquery-Version:

$('input').attr('required', true)
$('input').attr('required', false)

Ich weiß, es steht außer Frage, aber vielleicht findet das jemand hilfreich :)

vladCovaliov
quelle
2
Verwenden Sie tatsächlich prop()anstelle von attr():)
Poul Kruijt
1
@PierreDuc Es ist 2019 .. wir verwenden nicht mehr :)
a20
@ a20 Als ich das letzte Mal nachgesehen habe, benutze ich es immer noch. Also, ich denke du
liegst
Ich habe meinen Bruder veräppelt. Entschuldigung!
A20
3
let formelems = document.querySelectorAll('input,textarea,select');
formelems.forEach((formelem) => {
  formelem.required = true;

});

Wenn Sie alle erforderlichen Eingaben, Textbereiche und ausgewählten Elemente vornehmen möchten.

Kyle Pennell
quelle
-2

probier das aus ..

document.getElementById("edName").required = true;
Vijay
quelle