Bagaimana cara mengatur atribut HTML5 yang diperlukan di Javascript?

93

Saya mencoba menandai textkotak input seperti yang diharuskan dalam Javascript.

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

Jika bidang awalnya ditandai sebagai required:

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

ketika pengguna mencoba untuk mengirimkan mereka diberi kesalahan validasi:

masukkan deskripsi gambar di sini

Tapi sekarang saya ingin menyetel requiredatribut pada "runtime" , melalui Javascript:

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

dengan skrip yang sesuai:

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

Kecuali saat saya kirim sekarang, tidak ada pemeriksaan validasi, tidak ada blokir.

Apa cara yang benar untuk menyetel atribut boolean validasi HTML5 ?

jsFiddle

Apa nilai atributnya, Anda bertanya?

requiredAtribut validasi HTML5 didokumentasikan sebagai Boolean:

4.10.7.3.4 requiredAtribut

The requiredatribut adalah atribut boolean . Saat ditentukan, elemen harus diisi.

Ada banyak pertanyaan tentang bagaimana mendefinisikan booleanatribut. Catatan spesifikasi HTML5:

Kehadiran atribut boolean pada sebuah elemen merepresentasikan nilai sebenarnya, dan ketiadaan atribut merepresentasikan nilai false.

Jika atribut ada, nilainya harus berupa string kosong atau nilai yang merupakan kecocokan peka huruf besar / kecil ASCII untuk nama kanonis atribut, tanpa spasi di depan atau di belakang.

Ini berarti Anda dapat menentukan atribut required boolean dengan dua cara berbeda:

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

Tapi apa adalah nilai dari atribut benar-benar ?

Saat Anda melihat jsFiddle saya tentang masalah ini , Anda akan melihat bahwa jika requiredatribut ditentukan dalam markup:

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

Maka nilai atribut bukanlah string kosong, atau nama kanonik dari atribut tersebut:

edName.attributes.required = [object Attr]

Itu mungkin mengarah pada solusi.

Ian Boyd
sumber
4
Saya tidak mengerti mengapa mereka tidak mengizinkan required="false", apakah mereka pernah menulis template sebelum menulis standar? Atribut bersyarat biasanya menyebalkan, jauh lebih mudah untuk meletakkan boolean itu dalam nilai atribut ...
Christophe Roussy
Apakah mungkin secara manual menampilkan teks tersebut di atas masukan yang diperlukan: "Harap isi bidang ini."?
zygimantus

Jawaban:

121

requiredadalah properti tercermin (seperti id, name, type, dan semacamnya), sehingga:

element.required = true;

... di mana elemen DOM elementsebenarnya input, misalnya:

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

(Hanya untuk kelengkapan.)

Kembali:

Maka nilai atribut bukanlah string kosong, atau nama kanonik dari atribut tersebut:

edName.attributes.required = [object Attr]

Itu karena requireddalam kode itu ada objek atribut , bukan string; attributesadalah NamedNodeMapyang nilainya adalah Attrobjek . Untuk mendapatkan nilai salah satunya, Anda akan melihat valuepropertinya. Tetapi untuk atribut boolean, nilainya tidak relevan; atribut ada di peta (benar) atau tidak ada (salah).

Jadi jika required tidak tercermin, Anda akan mengaturnya dengan menambahkan atribut:

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

... yang setara dengan element.required = true. Anda akan menghapusnya dengan menghapus seluruhnya:

element.removeAttribute("required");

... yang setara dengan element.required = false.

Tapi kita tidak harus melakukan itu dengan required, karena sudah tercermin.

TJ Crowder
sumber
Bisakah Anda menambahkan sesuatu tentang .prop di sini?
mplungjan
@mplungjan - Saya tidak yakin apa yang Anda maksud ...? jQuery?
TJ Crowder
Ya, karena membingungkan prod tidak bekerja di DOM
mplungjan
110

Versi pendek

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

Versi Panjang

Setelah TJ Crowder berhasil menunjukkan properti yang direfleksikan , saya mengetahui bahwa sintaks berikut salah :

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

Anda harus melalui element.getAttributedan element.setAttribute:

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

Ini karena atribut sebenarnya berisi objek HtmlAttribute khusus :

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

Dengan menyetel nilai atribut ke "true", Anda salah menyetelnya ke objek String , bukan objek HtmlAttribute yang diperlukan:

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

Secara konseptual ide yang benar (diekspresikan dalam bahasa yang diketik), adalah:

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

Ini sebabnya:

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

ada. Mereka melakukan pekerjaan untuk menetapkan nilai ke objek HtmlAttribute di dalamnya.

Selain itu, beberapa atribut juga tercermin . Ini berarti Anda dapat mengaksesnya dengan lebih baik dari 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;

Yang tidak ingin Anda lakukan adalah salah menggunakan .attributeskoleksi:

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

Menguji Kasus

Hal ini menyebabkan pengujian seputar penggunaan requiredatribut, membandingkan nilai yang dikembalikan melalui atribut, dan properti yang direfleksikan

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

dengan hasil:

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)

.attributesSalah mencoba mengakses koleksi secara langsung. Ini mengembalikan objek yang mewakili atribut DOM:

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

Ini menjelaskan mengapa Anda tidak boleh berbicara .attributeslangsung dengan kolektor. Anda tidak memanipulasi nilai atribut, tetapi objek yang merepresentasikan atribut itu sendiri.

Bagaimana cara mengatur wajib?

Apa cara yang benar untuk menyetel requiredatribut? Anda memiliki dua pilihan, baik properti yang tercermin , atau melalui pengaturan atribut yang benar:

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

Sebenarnya, nilai lain apa pun akan "menyetel" atribut tersebut. Tetapi definisi Booleanatribut menentukan bahwa itu hanya boleh disetel ke string kosong ""untuk menunjukkan benar . Berikut metode semua bekerja untuk mengatur para required Boolean atribut,

tapi jangan gunakan mereka:

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

Kami telah mempelajari bahwa mencoba menyetel atribut secara langsung adalah salah:

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

Bagaimana cara membersihkan dibutuhkan?

Trik ketika mencoba untuk menghapus yang requiredatribut adalah bahwa hal itu mudah untuk sengaja menyalakannya:

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

Dengan cara yang tidak valid:

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!

Saat menggunakan .requiredproperti yang tercermin , Anda juga dapat menggunakan "falsey" apa pun nilai untuk menonaktifkannya, dan nilai kebenaran untuk mengaktifkannya. Tapi tetap berpegang pada benar dan salah untuk kejelasan.

Cara memeriksa untuk required?

Periksa keberadaan atribut melalui .hasAttribute("required")metode:

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

Anda juga dapat memeriksanya melalui properti tercermin Boolean.required :

if (edName.required)
{
}
Ian Boyd
sumber
1
Apa perbedaan antara variabel elementdan edName?
faintsignal
1
Salah satunya adalah di mana saya lupa untuk mengubah nama elemen tertentu edName(yaitu Name Input Box) menjadi generik element.
Ian Boyd
"Anda harus melalui element.getAttributedan element.setAttribute:" Hanya untuk kejelasan, Anda dapat menggunakan attributes NamedNodeMapuntuk mengubah nilai atribut jika Anda tahu atribut tersebut sudah ada, Anda tidak dapat menggunakannya untuk menambahkan atribut yang tidak ada (atau untuk menghapus salah satunya). Jadi pendekatan itu tidak berguna untuk atribut boolean seperti requiredkarena yang penting adalah apakah atribut ada, bukan nilainya. Tapi ya, properti yang dipantulkan biasanya lebih mudah. :-)
TJ Crowder
10

Yang penting bukanlah atribut tetapi properti , dan nilainya adalah boolean.

Anda dapat mengaturnya menggunakan

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

Dan versi jquery:

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

Saya tahu itu di luar pertanyaan, tetapi mungkin seseorang akan menganggap ini berguna :)

vladCovaliov
sumber
2
sebenarnya, gunakan prop()sebagai pengganti attr():)
Poul Kruijt
1
@PierreDuc Ini tahun 2019 .. kami tidak menggunakan :) lagi
a20
@ a20 terakhir kali saya memeriksa, saya masih menggunakannya. Jadi, saya kira Anda salah
Poul Kruijt
Aku bercanda dengan saudaraku .. maaf!
a20
3
let formelems = document.querySelectorAll('input,textarea,select');
formelems.forEach((formelem) => {
  formelem.required = true;

});

Jika Anda ingin membuat semua input, textarea, dan elemen pilih diperlukan.

Kyle Pennell
sumber
-2

coba ini ..

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