Jak ustawić wymagany atrybut HTML5 w JavaScript?


93

Próbuję oznaczyć textpole wejściowe jako wymagane w JavaScript.

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

Jeśli pole jest początkowo oznaczone jako required:

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

kiedy użytkownik próbuje przesłać, pojawia się błąd weryfikacji:

wprowadź opis obrazu tutaj

Ale teraz chcę ustawić requiredatrybut na „runtime” za pomocą JavaScript:

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

z odpowiednim skryptem:

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

Z wyjątkiem sytuacji, gdy prześlę teraz, nie ma sprawdzania poprawności ani bloku.

Jaki jest prawidłowy sposób ustawienia wartości boolowskiej walidacji HTML5 ?

jsFiddle

Pytasz, jaka jest wartość tego atrybutu?

requiredAtrybut walidacji HTML5 jest udokumentowany jako Boolean:

4.10.7.3.4 requiredAtrybut

requiredAtrybut jest atrybutem logiczna . Gdy określony, element jest wymagany.

W kwestii definiowania booleanatrybutu trzeba się dużo załamywać . Uwagi do specyfikacji HTML5:

Obecność atrybutu logicznego w elemencie reprezentuje wartość prawdziwą, a brak atrybutu reprezentuje wartość fałszywą.

Jeśli atrybut jest obecny, jego wartość musi być pustym ciągiem lub wartością będącą dopasowaniem ASCII bez rozróżniania wielkości liter dla nazwy kanonicznej atrybutu, bez wiodących ani końcowych białych znaków.

Oznacza to, że możesz określić atrybut required boolowski na dwa różne sposoby:

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

Ale jaka jest naprawdę wartość tego atrybutu ?

Kiedy spojrzysz na moje jsFiddle tego problemu , zauważysz, że jeśli requiredatrybut jest zdefiniowany w znaczniku:

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

Wtedy wartość atrybutu nie jest pustym ciągiem ani kanoniczną nazwą atrybutu:

edName.attributes.required = [object Attr]

To może doprowadzić do rozwiązania.


4
Nie rozumiem, dlaczego nie pozwalają required="false", czy kiedykolwiek napisali szablon przed napisaniem standardu? Atrybuty warunkowe są zwykle uciążliwe, o wiele łatwiej jest po prostu umieścić tę wartość logiczną w wartości atrybutu ...
Christophe Roussy

Czy możliwe jest ręczne wyświetlenie tego tekstu na wymaganym polu wejściowym: „Proszę wypełnić to pole”?
zygimantus

Odpowiedzi:


121

requiredJest to widoczne właściwość (na przykład id, name, typei taka), a więc:

element.required = true;

... gdzie elementjest rzeczywisty inputelement DOM, np:

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

(Tylko dla kompletności.)

Re:

Wtedy wartość atrybutu nie jest pustym ciągiem ani kanoniczną nazwą atrybutu:

edName.attributes.required = [object Attr]

Dzieje się tak, ponieważ requiredw tym kodzie znajduje się obiekt atrybutu , a nie łańcuch; attributesjest a NamedNodeMapktórego wartościami są Attrobiekty . Aby poznać wartość jednego z nich, przyjrzyj się jego valuewłasności. Jednak w przypadku atrybutu logicznego wartość nie jest odpowiednia; atrybut jest obecny na mapie (prawda) lub nieobecny (fałsz).

Więc jeśli required nie zostały odzwierciedlone, można to ustawić, dodając atrybut:

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

... co jest odpowiednikiem element.required = true. Możesz to wyczyścić, usuwając go całkowicie:

element.removeAttribute("required");

... co jest odpowiednikiem element.required = false.

Ale nie musimy tego robić required, ponieważ jest to odzwierciedlone.


Czy możesz tu dodać coś o .prop?
mplungjan

@mplungjan - Nie jestem pewien, co masz na myśli ...? jQuery?
TJ Crowder

Tak, ponieważ to mylące, że prod nie działa w DOM
mplungjan

110

Krótka wersja

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

Długa wersja

Gdy TJ Crowderowi udało się wskazać odzwierciedlone właściwości , dowiedziałem się, że następująca składnia jest nieprawidłowa :

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

Państwo musi przejść przez element.getAttributei element.setAttribute:

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

Dzieje się tak, ponieważ atrybut w rzeczywistości zawiera specjalny obiekt HtmlAttribute :

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

Ustawiając wartość atrybutu na „true”, przez pomyłkę ustawiasz go na obiekt String , a nie obiekt HtmlAttribute, którego wymaga:

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

Koncepcyjnie poprawna idea (wyrażona w języku maszynistym) to:

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

Dlatego:

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

istnieć. Wykonują pracę nad przypisaniem wartości do obiektu HtmlAttribute wewnątrz.

Oprócz tego odzwierciedlane są pewne atrybuty . Oznacza to, że możesz uzyskać do nich ładniejszy dostęp z poziomu 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;

To, czego nie chcesz, to omyłkowe użycie .attributeskolekcji:

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

Przypadki testowe

Doprowadziło to do przetestowania użycia requiredatrybutu, porównania wartości zwróconych przez atrybut i odzwierciedlonej właściwości

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

z wynikami:

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)

Próba .attributesbezpośredniego dostępu do kolekcji jest błędna. Zwraca obiekt, który reprezentuje atrybut DOM:

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

To wyjaśnia, dlaczego nigdy nie powinieneś rozmawiać .attributesbezpośrednio z kolektą. Nie manipulujesz wartościami atrybutów, ale obiektami, które reprezentują same atrybuty.

Jak ustawić wymagane?

Jaki jest prawidłowy sposób ustawienia requiredatrybutu? Masz dwie możliwości: właściwość odzwierciedloną lub poprzez prawidłowe ustawienie atrybutu:

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

Ściśle mówiąc, każda inna wartość „ustawi” atrybut. Ale definicja Booleanatrybutów mówi, że powinien być ustawiony tylko na pusty łańcuch, ""aby wskazywać na prawdę . Wszystkie poniższe metody działają, aby ustawić wartość required logiczną atrybut,

ale nie używaj ich:

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

Dowiedzieliśmy się już, że próba bezpośredniego ustawienia atrybutu jest błędna:

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

Jak wyczyścić wymagane?

Sztuką gdy próbuje usunąć ten requiredatrybut jest to, że łatwo przypadkowo włączyć go:

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

Z nieprawidłowymi sposobami:

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!

Korzystając z .requiredwłaściwości odbitej , możesz również użyć dowolnego „falsey” wartości , aby ją wyłączyć, oraz prawdziwych wartości, aby ją włączyć. Ale po prostu trzymaj się prawdy i fałszu dla jasności.

Jak sprawdzić dla required?

Sprawdź obecność atrybutu za pomocą .hasAttribute("required")metody:

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

Możesz to również sprawdzić za pomocą właściwości odzwierciedlonej w wartości logicznej.required :

if (edName.required)
{
}

1
Jaka jest różnica między zmiennymi elementa edName?
faintsignal

1
Jednym z nich jest sytuacja, w której zapomniałem przekonwertować konkretną nazwę elementu edName(tj. Pole wprowadzania nazwy) na ogólną element.
Ian Boyd

„Państwo musi przejść przez element.getAttributei element.setAttribute:” Tak dla jasności, można użyć attributes NamedNodeMap, aby zmienić wartość atrybutu, jeśli wiesz, że atrybut jest już tam, po prostu nie można go używać, aby dodać atrybut, który nie jest tam (lub usunięcia taki, który jest). Więc to podejście nie jest przydatne w przypadku atrybutów boolowskich, takich jak requiredponieważ liczy się dla nich to, czy istnieją, a nie jaka jest ich wartość. Ale tak, odbite właściwości są zwykle łatwiejsze. :-)
TJ Crowder

10

Liczy się nie atrybut, ale właściwość , a jej wartość jest wartością logiczną.

Możesz to ustawić za pomocą

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

10

Oraz wersja jquery:

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

Wiem, że to nie podlega dyskusji, ale może komuś to pomoże :)


2
właściwie użyj prop()zamiast attr():)
Poul Kruijt

1
@PierreDuc Jest 2019 ... nie używamy :) już więcej
a20

@ a20 ostatnim razem, gdy sprawdzałem, nadal go używam. Więc myślę, że się mylisz
Poul Kruijt

Żartowałem z mojego brata ... przepraszam!
a20

3
let formelems = document.querySelectorAll('input,textarea,select');
formelems.forEach((formelem) => {
  formelem.required = true;

});

Jeśli chcesz wprowadzić wszystkie wymagane dane wejściowe, pole tekstowe i wybierz wymagane elementy.


-2

wypróbuj to ..

document.getElementById("edName").required = true;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.