HTML5 форма обязательный атрибут. Установить пользовательское сообщение проверки?

326

У меня есть следующая форма HTML5: http://jsfiddle.net/nfgfP/

<form id="form" onsubmit="return(login())">
<input name="username" placeholder="Username" required />
<input name="pass"  type="password" placeholder="Password" required/>
<br/>Remember me: <input type="checkbox" name="remember" value="true" /><br/>
<input type="submit" name="submit" value="Log In"/>

В настоящее время, когда я нажимаю клавишу ввода, когда они оба пусты, появляется всплывающее окно с надписью «Пожалуйста, заполните это поле». Как бы изменить это сообщение по умолчанию на «Это поле нельзя оставить пустым»?

РЕДАКТИРОВАТЬ: Также обратите внимание, что сообщение об ошибке поля типа пароля просто *****. Чтобы воссоздать это, введите имя пользователя и нажмите «Отправить».

РЕДАКТИРОВАТЬ : я использую Chrome 10 для тестирования. Пожалуйста, сделайте то же самое

Skizit
источник
1
О, +1 за безумное сообщение о подтверждении пустого пароля = / Как это прошло QA, мне интересно ...
Дэвид говорит восстановить Монику
3
Почему бы просто не принять сообщение браузера по умолчанию? Это то, что пользователи видят для каждого другого сайта, который они посещают, вы просто запутаете своих пользователей, создав нестандартное сообщение. (Google, вероятно, провел больше оценки и тестирования UX при определении этой формулировки, чем вы!).
ChrisV
12
@ChrisV А как насчет мультиязычных сайтов?
Инеманья
1
В моем случае я хочу проверить, что значение представляет собой число перед публикацией, но я не могу использовать атрибут type = "number" (по причинам). Поэтому я установил атрибут pattern для проверки чисел и необязательных десятичных знаков, которые выдают сообщение , «Пожалуйста, укажите требуемый формат» при ошибке. Я бы предпочел, чтобы он сказал: «Вы должны подарить нам номер бако».
Кристофер

Ответы:

267

Используйте setCustomValidity:

document.addEventListener("DOMContentLoaded", function() {
    var elements = document.getElementsByTagName("INPUT");
    for (var i = 0; i < elements.length; i++) {
        elements[i].oninvalid = function(e) {
            e.target.setCustomValidity("");
            if (!e.target.validity.valid) {
                e.target.setCustomValidity("This field cannot be left blank");
            }
        };
        elements[i].oninput = function(e) {
            e.target.setCustomValidity("");
        };
    }
})

Я перешел на ванильный JavaScript из Mootools, как предложено @itpastorn в комментариях, но вы должны быть в состоянии выработать эквивалент Mootools, если это необходимо.

редактировать

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

Дальнейшее редактирование

Как указано в комментарии @ thomasvdb ниже, вам нужно очистить пользовательскую валидность в каком-либо событии вне, invalidиначе может быть дополнительный проход через oninvalidобработчик для его очистки.

robertc
источник
Я пробовал это, но все еще есть ошибка. Если вы оставите поле пустым, оно показывает сообщение, затем введите что-то в поле, но теперь оно показывает пустое сообщение, и действие не выполняется. Если вы сейчас нажмете кнопку еще раз, она пройдет.
thomasvdb
1
@thomasvdb Попробуйте установить для пользовательской действительности пустую строку в inputсобытии. На данный момент это только очищается, если invalidсобытие запускается.
Робертc
Это действительно решение. Выяснил это с помощью решения @hleinone. Спасибо за ответ!
thomasvdb
4
Решение выше использует только JQuery для ожидания загрузки документа. Все остальное - чистый JS и DOM. Браузер, достаточно современный для поддержки setCustomValidity, должен также поддерживать событие DOMContentLoaded, что означает, что JQuery не нужен, если он не используется ни для чего другого.
itpastorn
1
@ Lai32290, потому что у вас нет доступа к реальному объекту DOM. $("")возвращает массив объектов, даже если есть только один. $("")[i]Скорее всего, что вы хотите.
Ноа Пассалаква
290

Вот код для обработки пользовательских сообщений об ошибках в HTML5

<input type="text" id="username" required placeholder="Enter Name"
    oninvalid="this.setCustomValidity('Enter User Name Here')"
    oninput="this.setCustomValidity('')"  />

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

oninput="this.setCustomValidity('')"
Сомнатх Кадам
источник
Отлично работает на Firefox 29.0 и Chrome 34.0.1847.137.
Фернандо Кош
отлично и в FF 38 пока что. Исправляет ошибку в проверке электронной почты, если используется только oninvalid ().
Андрей
Не работает в Safari ни в iPad, ни в iPhone. Работает, как и ожидалось, в Chrome.
Набиль
2
@ somnath-kadam Это ошибка или вы умышленно сделали oninput = "setCustomValidity ('')" вместо oninput = "this.setCustomValidity ('')"
tormuto
3
Спасибо за пометку oninput = "setCustomValidity ('')" как наиболее важную. Это спасло мой день.
singhpradeep
99

Управлять пользовательскими сообщениями с помощью HTML5события очень простоoninvalid

Вот код:

<input id="UserID"  type="text" required="required"
       oninvalid="this.setCustomValidity('Witinnovation')"
       onvalid="this.setCustomValidity('')">

Это самое главное:

onvalid="this.setCustomValidity('')"
Ашвини джайн
источник
3
Также проверьте другие проверки, такие как шаблон, минимальные / максимальные значения и т.д ... sanalksankar.blogspot.com/2010/12/…
Jaider
10
Это приводит к ошибке в Firefox, когда он проверяется при обновлении, но не дает изменений и исправлений.
Райан Чармли
12
@RyanCharmley с помощью onchange="this.setCustomValidity('')"ошибки исчезнет. Проверьте мой ответ ниже.
Салар
4
Если это не работает (например, в Safari), используйте oninputвместо onvalid.
Джимоти
2
@ Джимоти прав в этом, oninputэто более универсальное решение, onvalidу меня не работало даже в Chrome.
ThisGuyCantEven
68

Примечание. Это больше не работает в Chrome и не тестируется в других браузерах. Смотрите правки ниже. Этот ответ оставлен здесь для исторической справки.

Если вы чувствуете, что строка проверки действительно не должна быть задана кодом, вы можете установить атрибут заголовка входного элемента следующим образом: «Это поле нельзя оставлять пустым». (Работает в Chrome 10)

title="This field should not be left blank."

Смотрите http://jsfiddle.net/kaleb/nfgfP/8/

А в Firefox вы можете добавить этот атрибут:

x-moz-errormessage="This field should not be left blank."

редактировать

Это, кажется, изменилось, так как я первоначально написал этот ответ. Теперь добавление заголовка не изменяет достоверность сообщения, оно просто добавляет приложение к сообщению. Скрипка выше все еще применяется.

Редактировать 2

Chrome теперь ничего не делает с атрибутом title в Chrome 51. Я не уверен, в какой версии это изменилось.

КЖ
источник
1
Это не меняет фактическое содержание сообщения.
Уэсли Мерч
2
В то время я тестировал это.
kzh
3
Моя ошибка, OP указал Chrome 10, я был на FF5. Убрал downvote, мои извинения. Вау, это сообщение об ошибке в Chrome - самая уродливая вещь, которую я когда-либо видел.
Уэсли Мерч
2
Для декларативных сообщений об ошибках в Firefox используйте атрибут:x-moz-errormessage="This field should not be left blank."
robertc
2
Это добавляет описательное сообщение под заголовком «Пожалуйста, заполните это поле».
Магн
41

Управлять пользовательскими сообщениями с помощью HTML5 oninvalidсобытия очень просто

Вот код:

User ID 
<input id="UserID"  type="text" required 
       oninvalid="this.setCustomValidity('User ID is a must')">
Дхармендра Джа
источник
4
необходимо установить пустое сообщение о достоверности после того, как элемент управления обнаружит ввод, иначе для всех полей будет отображаться первое выполненное сообщение о достоверности. Добавляйте oninput = "setCustomValidity ('')" при каждом вызове setCustomValidity (). +1 к ответу Сомнатха.
Таранг
41

Если установить и отменить установку setCustomValidityв нужное время, сообщение проверки будет работать без сбоев.

<input name="Username" required 
oninvalid="this.setCustomValidity('Username cannot be empty.')" 
onchange="this.setCustomValidity('')" type="text" />

Я использовал onchangeвместо того, oninputкоторый является более общим и происходит, когда значение изменяется в любом состоянии даже через JavaScript.

Салар
источник
Это должен быть принятый ответ. Работал в Windows 10 1709 в следующих браузерах: Chrome 66.0.3359.139 64 бит, Firefox 59.0.3 (64 бит), Internet Explorer 11.431.16299.0, Edge 41.16299.402.0. Работал в macOS 10.13.2 в Safari 11.0 (13604.1.38.1.6). Работал в Android 4.4.4 в Chrome 66.0.3359.158. Для тех , кто ищет пути JSX: onInvalid={(e) => { e.target.setCustomValidity('foo') }} onChange={(e) => { e.target.setCustomValidity('') }}.
GuiRitter
Addendum: eможет быть нулевым, например, когда опция удалена из поля React Select. Не забудьте проверить это.
GuiRitter
Поправка: чтобы использовать это с React Select, вы должны пройти onChangeи, onInvalidкакinputProps={{ onInvalid: …, onChange: …, }}
GuiRitter
Приложение: type='email'немного более трудно лечить, так как с помощью setCustomValidityнаборов customError: trueдля e.target.validityдаже если вход активен. Я пытаюсь найти способ исправить это.
GuiRitter
@GuiRitter Ты понял это?
EvilJordan
39

Я сделал небольшую библиотеку, чтобы облегчить изменение и перевод сообщений об ошибках. Вы даже можете изменить текст по типу ошибки, который в настоящее время недоступен titleв Chrome или x-moz-errormessageFirefox. Перейти проверить его на GitHub , и давать обратную связь.

Он используется как:

<input type="email" required data-errormessage-value-missing="Please input something">

Там в демо доступны на jsFiddle .

hleinone
источник
Спасибо! Решил мою небольшую ошибку, упомянутую в качестве комментария в принятом ответе.
thomasvdb
Хороший ответ, так как OP использует Google Chrome; хотя это не сработает в IE Edge
CoderHawk
23

Попробуйте это, это лучше и проверено:

HTML:

<form id="myform">
    <input id="email" 
           oninvalid="InvalidMsg(this);" 
           oninput="InvalidMsg(this);"
           name="email"  
           type="email" 
           required="required" />
    <input type="submit" />
</form>

JAVASCRIPT:

function InvalidMsg(textbox) {
    if (textbox.value === '') {
        textbox.setCustomValidity('Required email address');
    } else if (textbox.validity.typeMismatch){
        textbox.setCustomValidity('please enter a valid email address');
    } else {
       textbox.setCustomValidity('');
    }

    return true;
}

Демо-версия:

http://jsfiddle.net/patelriki13/Sqq8e/

Рикин Патель
источник
эй .... хорошее решение, но type = email не работает в браузере Safari. посмотрите w3schools.com/html/html_form_input_types.asp
Бхавна Малхотра
2
Да, это не поддерживается для сафари, но я дал ответ на заданное пользователем сообщение проверки.
Рикин Патель
10

Самый простой и чистый способ, который я нашел, - это использовать атрибут data для хранения вашей ошибки. Проверьте правильность узла и обработайте ошибку, используя некоторый пользовательский HTML.введите описание изображения здесь

Le Javascript

if(node.validity.patternMismatch)
        {
            message = node.dataset.patternError;
        }

и немного супер HTML5

<input type="text" id="city" name="city" data-pattern-error="Please use only letters for your city." pattern="[A-z ']*" required>
Коллин Уайт
источник
3
Несмотря на ошибку, говоря только буквы, шаблон допускает пробел и апостроф? Кроме того, A-zразрешены '[', '\', ']', '^', '_' и '`'.
Лоуренс Дол
5

Решение для предотвращения сообщений об ошибках Google Chrome при вводе каждого символа:

<p>Click the 'Submit' button with empty input field and you will see the custom error message. Then put "-" sign in the same input field.</p>
<form method="post" action="#">
  <label for="text_number_1">Here you will see browser's error validation message on input:</label><br>
  <input id="test_number_1" type="number" min="0" required="true"
         oninput="this.setCustomValidity('')"
         oninvalid="this.setCustomValidity('This is my custom message.')"/>
  <input type="submit"/>
</form>

<form method="post" action="#">
  <p></p>
  <label for="text_number_1">Here you will see no error messages on input:</label><br>
  <input id="test_number_2" type="number" min="0" required="true"
         oninput="(function(e){e.setCustomValidity(''); return !e.validity.valid && e.setCustomValidity(' ')})(this)"
         oninvalid="this.setCustomValidity('This is my custom message.')"/>
  <input type="submit"/>
</form>

Андрей Вештард
источник
3

У меня есть более простое решение vanilla js only:

Для флажков:

document.getElementById("id").oninvalid = function () {
    this.setCustomValidity(this.checked ? '' : 'My message');
};

Для входов:

document.getElementById("id").oninvalid = function () {
    this.setCustomValidity(this.value ? '' : 'My message');
};
bernhardh
источник
1

Приспосабливая ответ Салара к JSX и React, я заметил, что React Select не ведет себя как <input/>поле в отношении проверки. По-видимому, необходимо несколько обходных путей, чтобы показать только пользовательское сообщение и не показывать его в неудобное время.

Я поднял вопрос здесь , если это поможет. Вот CodeSandbox с рабочим примером, и самый важный код там воспроизводится здесь:

Hello.js

import React, { Component } from "react";
import SelectValid from "./SelectValid";

export default class Hello extends Component {
  render() {
    return (
      <form>
        <SelectValid placeholder="this one is optional" />
        <SelectValid placeholder="this one is required" required />
        <input
          required
          defaultValue="foo"
          onChange={e => e.target.setCustomValidity("")}
          onInvalid={e => e.target.setCustomValidity("foo")}
        />
        <button>button</button>
      </form>
    );
  }
}

SelectValid.js

import React, { Component } from "react";
import Select from "react-select";
import "react-select/dist/react-select.css";

export default class SelectValid extends Component {
  render() {
    this.required = !this.props.required
      ? false
      : this.state && this.state.value ? false : true;
    let inputProps = undefined;
    let onInputChange = undefined;
    if (this.props.required) {
      inputProps = {
        onInvalid: e => e.target.setCustomValidity(this.required ? "foo" : "")
      };
      onInputChange = value => {
        this.selectComponent.input.input.setCustomValidity(
          value
            ? ""
            : this.required
              ? "foo"
              : this.selectComponent.props.value ? "" : "foo"
        );
        return value;
      };
    }
    return (
      <Select
        onChange={value => {
          this.required = !this.props.required ? false : value ? false : true;
          let state = this && this.state ? this.state : { value: null };
          state.value = value;
          this.setState(state);
          if (this.props.onChange) {
            this.props.onChange();
          }
        }}
        value={this && this.state ? this.state.value : null}
        options={[{ label: "yes", value: 1 }, { label: "no", value: 0 }]}
        placeholder={this.props.placeholder}
        required={this.required}
        clearable
        searchable
        inputProps={inputProps}
        ref={input => (this.selectComponent = input)}
        onInputChange={onInputChange}
      />
    );
  }
}
GuiRitter
источник
1

Хорошо, oninvalid работает хорошо, но показывает ошибку, даже если пользователь ввел правильные данные. Поэтому я использовал ниже, чтобы заняться этим, надеюсь, это будет работать и для вас,

oninvalid="this.setCustomValidity('Your custom message.')" onkeyup="setCustomValidity('')"

Умеш Патил
источник
-7

Может быть легко обработано, просто поместив 'title' с полем:

<input type="text" id="username" required title="This field can not be empty"  />
Deepti
источник
Это не меняет отображаемое сообщение об ошибке. Он показывает только заголовок на входе при наведении курсора.
Матье Дюмулен
Это не правильное использование «title» для отображения некоторого предупреждения для поля ввода.
Саджад Садери