Как установить обязательный атрибут HTML5 в Javascript?

93

Я пытаюсь пометить textполе ввода как требуется в Javascript.

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

Если поле изначально помечено как required:

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

когда пользователь пытается отправить, ему выдается ошибка проверки:

введите описание изображения здесь

Но теперь я хочу установить requiredатрибут «во время выполнения» через Javascript:

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

с соответствующим скриптом:

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

За исключением тех случаев, когда я отправляю сейчас, нет ни проверки, ни блокировки.

Как правильно установить логический атрибут проверки HTML5 ?

jsFiddle

Вы спросите, какое значение имеет атрибут?

requiredАтрибут проверки HTML5 задокументирован как Boolean:

4.10.7.3.4 requiredАтрибут

requiredАтрибут является логическим атрибутом . Если указано, элемент является обязательным.

Очень часто приходится ломать руки над тем, как определить booleanатрибут. В спецификации HTML5 указано:

Наличие логического атрибута в элементе представляет истинное значение, а отсутствие атрибута представляет ложное значение.

Если атрибут присутствует, его значение должно быть либо пустой строкой, либо значением, которое является нечувствительным к регистру ASCII совпадением для канонического имени атрибута, без начальных или конечных пробелов.

Это означает, что вы можете указать required логический атрибут двумя разными способами:

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

Но каково на самом деле значение атрибута ?

Когда вы посмотрите на мой jsFiddle, посвященный этой проблеме , вы заметите, что если requiredатрибут определен в разметке:

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

Тогда значение атрибута не будет ни пустой строкой, ни каноническим именем атрибута:

edName.attributes.required = [object Attr]

Это может привести к решению.

Ян Бойд
источник
4
Я не понимаю, почему не разрешают required="false", они когда-нибудь писали шаблон до написания стандарта? Условные атрибуты обычно вызывают затруднения, гораздо проще просто поместить это логическое значение в значение атрибута ...
Кристоф Русси,
Можно ли вручную отобразить этот текст поверх обязательного ввода: «Пожалуйста, заполните это поле»?
zygimantus

Ответы:

121

requiredэто отражено свойство (например id, name, type, и такой), так что :

element.required = true;

... где elementнаходится фактический inputэлемент DOM, например:

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

(Для полноты картины.)

Re:

Тогда значение атрибута - это не пустая строка или каноническое имя атрибута:

edName.attributes.required = [object Attr]

Это потому, что requiredв этом коде есть объект атрибута , а не строка; attributesявляется NamedNodeMap, значениями которого являются Attrобъекты . Чтобы узнать ценность одного из них, вы должны посмотреть на его valueсвойство. Но для логического атрибута значение не имеет значения; атрибут либо присутствует на карте (true), либо отсутствует (false).

Итак, если required не было отражено, вы бы установили его, добавив атрибут:

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

... что эквивалентно element.required = true. Вы бы очистили его, полностью удалив:

element.removeAttribute("required");

... что эквивалентно element.required = false.

Но мы не должны этого делать required, поскольку это отражено.

TJ Crowder
источник
Вы можете добавить сюда что-нибудь о .prop?
mplungjan
@mplungjan - Я не понимаю, что вы имеете в виду ...? jQuery?
TJ Crowder
Да, потому что сбивает с толку тот факт, что prod не работает в DOM
mplungjan
110

Укороченная версия

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

Длинная версия

Как только TJ Crowder удалось указать на отраженные свойства , я узнал, что следующий синтаксис неверен :

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

Вы должны пройти element.getAttributeи element.setAttribute:

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

Это потому, что атрибут фактически содержит специальный объект 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

Устанавливая для атрибута значение "true", вы ошибочно устанавливаете его для объекта String , а не для объекта HtmlAttribute, который ему нужен:

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

Концептуально правильная идея (выраженная на типизированном языке):

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

Вот почему:

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

существовать. Они выполняют работу по присвоению значения объекту HtmlAttribute внутри.

Вдобавок к этому отражаются некоторые атрибуты . Это означает, что вы можете получить к ним более удобный доступ из 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;

Чего вы не хотите делать, так это по ошибке использовать .attributesколлекцию:

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

Примеры тестирования

Это привело к тестированию использования requiredатрибута, сравнения значений, возвращаемых через атрибут, и отраженного свойства.

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

с результатами:

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)

Попытка получить доступ к .attributesколлекции напрямую неверна. Он возвращает объект, представляющий атрибут DOM:

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

Это объясняет, почему вам никогда не следует .attributesнапрямую обращаться к коллекционеру. Вы манипулируете не значениями атрибутов, а объектами, которые представляют сами атрибуты.

Как установить обязательное?

Как правильно установить requiredатрибут? У вас есть два варианта: либо отраженное свойство , либо правильная установка атрибута:

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

Строго говоря, любое другое значение будет «устанавливать» атрибут. Но определение Booleanатрибутов диктует, что ""для указания истины следует устанавливать только пустую строку . Следующие методы все работы , чтобы установить на required булевой атрибут,

но не используйте их:

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

Мы уже узнали, что пытаться установить атрибут напрямую неправильно:

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

Как очистить требуется?

Хитрость при попытке удалить в requiredатрибут является то , что это легко случайно включить его:

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

Недействительными способами:

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!

При использовании отраженного .requiredсвойства вы также можете использовать любые «ложные» значения, чтобы выключить его, и истинные значения, чтобы включить его. Но для ясности просто придерживайтесь истинного и ложного.

Как проверить для required?

Проверить наличие атрибута .hasAttribute("required")методом:

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

Вы также можете проверить это с помощью логического отраженного .requiredсвойства:

if (edName.required)
{
}
Ян Бойд
источник
1
В чем разница между переменными elementи edName?
faintsignal
1
Во-первых, я забыл преобразовать конкретное имя элемента edName(например, поле ввода имени) в общее element.
Ian Boyd
"Вы должны пройти element.getAttributeи element.setAttribute:" Для ясности вы можете использовать attributes NamedNodeMapдля изменения значения атрибута, если вы знаете, что атрибут уже существует, вы просто не можете использовать его для добавления атрибута, которого нет (или для удаления тот, что есть). Так что этот подход бесполезен для логических атрибутов, например, requiredпотому что для них важно то, есть ли они там, а не их значение. Но да, отраженные свойства обычно проще. :-)
TJ Crowder
10

Важен не атрибут, а свойство , а его значение является логическим.

Вы можете установить его, используя

 document.getElementById("edName").required = true;
Дени Сегюре
источник
10

И версия jquery:

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

Я знаю, что это не подлежит сомнению, но, возможно, кому-то это поможет :)

vladCovaliov
источник
2
на самом деле, используйте prop()вместо attr():)
Poul Kruijt
1
@PierreDuc Это 2019 год .. мы больше не используем :)
a20
@ a20 в прошлый раз проверял, до сих пор им пользуюсь. Думаю, вы ошибаетесь
Поул Круйт
Я шутил над своим братом ... прости!
a20
3
let formelems = document.querySelectorAll('input,textarea,select');
formelems.forEach((formelem) => {
  formelem.required = true;

});

Если вы хотите сделать все элементы input, textarea и select обязательными.

Кайл Пеннелл
источник
-2

попробуйте это ..

document.getElementById("edName").required = true;
Виджай
источник