Wymagany atrybut formularza HTML5. Ustawić niestandardowy komunikat sprawdzania poprawności?

326

Mam następujący formularz 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"/>

Obecnie, gdy klikam Enter, gdy oba są puste, pojawia się wyskakujące okienko z napisem „Proszę wypełnić to pole”. Jak zmienić domyślną wiadomość na „To pole nie może być puste”?

EDYCJA: Zauważ też, że komunikat o błędzie pola hasła typu jest po prostu *****. Aby odtworzyć to, podaj nazwę użytkownika i naciśnij „Prześlij”.

EDYCJA : Używam Chrome 10 do testowania. Zrób to samo

Skizit
źródło
1
Och, +1 za szaloną wiadomość dotyczącą sprawdzania poprawności pustego hasła = / Jak to się zdało, zastanawiam się ...
David mówi przywrócenie Moniki
3
Dlaczego nie zaakceptować domyślnego komunikatu przeglądarki? Tak widzą użytkownicy w każdej innej odwiedzanej witrynie, po prostu pomylisz użytkowników, tworząc niestandardową wiadomość. (Google prawdopodobnie zarządza większą oceną i testowaniem UX w określaniu tego sformułowania niż ty!).
ChrisV
12
@ChrisV Co z witrynami wielojęzycznymi?
inemanja
1
W moim przypadku chcę sprawdzić, czy wartość jest liczbą przed wysłaniem, ale nie mogę użyć atrybutu type = "number" (z przyczyn.) Ustawiłem więc atrybut wzorca, aby sprawdzał liczby i opcjonalne liczby dziesiętne, które dają komunikat , „Proszę dopasować żądany format” w przypadku błędu. Wolałbym powiedzieć: „Musisz podarować nam numer Bucko”.
Kristopher

Odpowiedzi:

267

Użyj 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("");
        };
    }
})

I zmieniono wanilii JavaScript z Mootools jak sugeruje @itpastorn w komentarzach, ale powinieneś być w stanie wypracować Mootools równoważne, jeżeli jest to konieczne.

Edytować

Zaktualizowałem tutaj kod, ponieważ setCustomValiditydziała nieco inaczej niż zrozumiałem, kiedy pierwotnie odpowiedziałem. Jeśli setCustomValidityzostanie ustawiona wartość inna niż pusty ciąg, spowoduje to, że pole zostanie uznane za nieprawidłowe; dlatego musisz to wyczyścić przed przetestowaniem poprawności, nie możesz po prostu ustawić i zapomnieć.

Dalsza edycja

Jak wskazano w komentarzu @ thomasvdb poniżej, musisz wyczyścić niestandardową ważność w niektórych przypadkach poza, w invalidprzeciwnym razie może istnieć dodatkowe przejście przez program oninvalidobsługi, aby je wyczyścić.

robertc
źródło
Próbowałem tego, ale nadal występuje błąd. Jeśli pozostawisz puste pole, wyświetli się komunikat, a następnie wpisz coś w polu, ale teraz wyświetli pustą wiadomość i akcja nie zostanie wykonana. Jeśli teraz ponownie klikniesz przycisk, przejdzie on przez.
thomasvdb
1
@thomasvdb Spróbuj ustawić niestandardową ważność na pusty ciąg inputzdarzenia. W tej chwili jest to usuwane tylko wtedy, gdy invalidwydarzenie zostanie uruchomione .
robertc
To jest rzeczywiście rozwiązanie. Znalazłem to dzięki rozwiązaniu @leinone. Dzięki za odpowiedzi!
thomasvdb
4
Powyższe rozwiązanie używa JQuery tylko do oczekiwania na załadowanie dokumentu. Cała reszta to czysta JS i DOM. Przeglądarka wystarczająco nowoczesna, aby obsługiwać setCustomValidity, powinna również obsługiwać zdarzenie DOMContentLoaded, co oznacza, że ​​JQuery nie jest potrzebny, jeśli nie jest używany do niczego innego.
itpastorn
1
@ Lai32290, ponieważ nie masz dostępu do rzeczywistego obiektu DOM. $("")zwraca tablicę obiektów, nawet jeśli jest tylko jeden. $("")[i]jest najprawdopodobniej tym, czego chcesz.
Noah Passalacqua
288

Oto kod do obsługi niestandardowego komunikatu o błędzie w HTML5

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

Ta część jest ważna, ponieważ ukrywa komunikat o błędzie, gdy użytkownik wprowadza nowe dane:

oninput="this.setCustomValidity('')"
Somnath Kadam
źródło
Działa doskonale w Firefox 29.0 i Chrome 34.0.1847.137.
Fernando Kosh
idealne i jak dotąd w FF 38. Naprawiono błąd w sprawdzaniu poprawności wiadomości e-mail, jeśli używany jest tylko oninvalid ().
andrew
Nie działa w Safari na iPadzie ani iPhonie. Jednak działa zgodnie z oczekiwaniami na pulpicie Chrome.
Nabeel
2
@ somnath-kadam Czy to pomyłka, czy celowo zrobiłeś oninput = "setCustomValidity ('')" zamiast oninput = "this.setCustomValidity ('')"
tormuto 31.03.17
3
Dziękujemy za zaznaczenie oninput = "setCustomValidity ('')" jako najważniejsze. To uratowało mi dzień.
singhpradeep
99

Sterowanie komunikatami niestandardowymi za pomocą HTML5zdarzenia jest bardzo prosteoninvalid

Oto kod:

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

To jest najważniejsze:

onvalid="this.setCustomValidity('')"
Ashwini Jain
źródło
3
Sprawdź także inne walidacje, takie jak wzorzec, wartości min / max itp. Sanalksankar.blogspot.com/2010/12/…
Jaider
10
Powoduje to błąd w firefoxie, który sprawdza poprawność po odświeżeniu, ale nie powiedzie się po zmianie i korekcie.
Ryan Charmley,
12
@RyanCharmley przy użyciu onchange="this.setCustomValidity('')"błędu zniknie. Sprawdź moją odpowiedź poniżej.
Salar
4
Jeśli to nie działa (na przykład nie działa w przeglądarce Safari), użyj oninputzamiast onvalid.
Jimothy
2
@Jimothy ma rację, oninputjest to bardziej uniwersalne rozwiązanie, onvalidnie działało nawet w Chrome dla mnie.
ThisGuyCantEven
68

Uwaga: to nie działa już w Chrome, nie było testowane w innych przeglądarkach. Zobacz zmiany poniżej. Ta odpowiedź pozostawia się tutaj w celach historycznych.

Jeśli uważasz, że łańcuch sprawdzania poprawności nie powinien być ustawiony kodem, możesz ustawić atrybut tytułu elementu wejściowego na „To pole nie może być puste”. (Działa w Chrome 10)

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

Zobacz http://jsfiddle.net/kaleb/nfgfP/8/

W przeglądarce Firefox możesz dodać ten atrybut:

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

Edytować

Wydaje się, że to się zmieniło, odkąd napisałem tę odpowiedź. Teraz dodanie tytułu nie zmienia komunikatu o ważności, tylko dodaje załącznik do wiadomości. Nadal obowiązuje skrzypka powyżej.

Edytuj 2

Chrome nie robi teraz nic z atrybutem title od Chrome 51. Nie jestem pewien, w której wersji to się zmieniło.

kzh
źródło
1
To nie zmienia faktycznej treści wiadomości.
Wesley Murch,
2
W momencie testowania to zrobiłem.
kzh
3
Mój błąd, OP określił Chrome 10, byłem na FF5. Usunięto głosowanie, przepraszam. Wow, ten komunikat o błędzie w Chrome jest najbrzydszą rzeczą, jaką kiedykolwiek widziałem.
Wesley Murch,
2
W przypadku deklaratywnych komunikatów o błędach w przeglądarce Firefox użyj atrybutu:x-moz-errormessage="This field should not be left blank."
robertc,
2
Dodaje to opisowy komunikat pod „Proszę wypełnić to pole”.
Magne,
41

Kontrolowanie niestandardowych wiadomości za pomocą HTML5 oninvalidwydarzenia jest bardzo proste

Oto kod:

User ID 
<input id="UserID"  type="text" required 
       oninvalid="this.setCustomValidity('User ID is a must')">
Dharmendra Jha
źródło
4
wymagane jest ustawienie pustego komunikatu o ważności, gdy kontrola ujawni dane wejściowe, w przeciwnym razie dla wszystkich pól zostanie wyświetlony pierwszy wykonany komunikat o ważności. Dodaj oninput = "setCustomValidity ('')" przy każdym wywołaniu setCustomValidity (). +1 do odpowiedzi Somnatha.
Tarang
41

Po ustawieniu i rozbrojeniu setCustomValiditywe właściwym czasie komunikat sprawdzania poprawności będzie działał bezbłędnie.

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

Użyłem onchangezamiast tego, oninputktóry jest bardziej ogólny i występuje, gdy wartość jest zmieniana w dowolnym stanie, nawet poprzez JavaScript.

Salar
źródło
To powinna być zaakceptowana odpowiedź. Pracował w systemie Windows 10 1709 w następujących przeglądarkach: Chrome 66.0.3359.139 64 bity, Firefox 59.0.3 (64-bit), Internet Explorer 11.431.16299.0, Edge 41.16299.402.0. Pracował w macOS 10.13.2 w Safari 11.0 (13604.1.38.1.6). Pracował w Androidzie 4.4.4 w Chrome 66.0.3359.158. Dla tych, którzy szukają sposobu JSX: onInvalid={(e) => { e.target.setCustomValidity('foo') }} onChange={(e) => { e.target.setCustomValidity('') }}.
GuiRitter
Dodatek: emoże być pusty, na przykład gdy opcja zostanie usunięta z pola React Select. Nie zapomnij tego sprawdzić.
GuiRitter
Errata: aby użyć tego z React Select, musisz zdać onChangei onInvalidjakoinputProps={{ onInvalid: …, onChange: …, }}
GuiRitter
Uzupełnienie: type='email'jest nieco trudniejsze do wyleczenia, ponieważ przy użyciu setCustomValidityzestawów customError: truedo e.target.validitynawet jeśli wejście jest prawidłowy. Próbuję znaleźć sposób, aby to naprawić.
GuiRitter
@GuiRitter Czy to rozgryzłeś?
EvilJordan,
39

Zrobiłem małą bibliotekę, aby ułatwić zmianę i tłumaczenie komunikatów o błędach. Możesz nawet zmieniać teksty według rodzaju błędu, który obecnie nie jest dostępny titlew Chrome lub x-moz-errormessageFirefox. Go to sprawdzić na GitHub , i przekazywać informacje zwrotne.

Jest używany jak:

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

W jsFiddle dostępna jest wersja demonstracyjna .

hleinone
źródło
Dzięki! Rozwiązałem mój mały błąd wymieniony jako komentarz w zaakceptowanej odpowiedzi.
thomasvdb
Dobra odpowiedź, ponieważ OP używa Google Chrome; ale to nie zadziała w IE Edge
CoderHawk
23

Wypróbuj ten, jest lepszy i przetestowany:

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

Próbny:

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

Rikin Patel
źródło
hej .... fajne rozwiązanie, ale typ = email nie działa w przeglądarce Safari. zajrzyj w3schools.com/html/html_form_input_types.asp
Bhawna Malhotra
2
Tak, nie jest obsługiwany w przypadku safari, ale dałem odpowiedź na niestandardowy komunikat sprawdzania poprawności.
Rikin Patel
10

Najłatwiejszym i najczystszym sposobem, jaki znalazłem, jest użycie atrybutu danych do przechowywania niestandardowego błędu. Przetestuj poprawność węzła i obsłuż błąd, korzystając z niestandardowego kodu HTML.wprowadź opis zdjęcia tutaj

le javascript

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

i trochę super HTML5

<input type="text" id="city" name="city" data-pattern-error="Please use only letters for your city." pattern="[A-z ']*" required>
Collin White
źródło
3
Mimo błędu mówiącego tylko o literach, wzór pozwala na spację i apostrof? Ponadto, A-zpozwala na '[' '\', ']' '^' '_' i ''!'.
Lawrence Dol
5

Rozwiązanie zapobiegające komunikatom o błędach przeglądarki Google Chrome przy wprowadzaniu każdego symbolu:

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

Andrei Veshtard
źródło
3

Mam prostsze rozwiązanie tylko waniliowe js:

W przypadku pól wyboru:

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

Dla danych wejściowych:

document.getElementById("id").oninvalid = function () {
    this.setCustomValidity(this.value ? '' : 'My message');
};
Bernhardh
źródło
1

Dostosowując odpowiedź Salara do JSX i React, zauważyłem, że React Select nie zachowuje się tak jak<input/> pole dotyczące sprawdzania poprawności. Najwyraźniej potrzeba kilku obejść, aby wyświetlić tylko niestandardowy komunikat i nie wyświetlać go w niewygodnych momentach.

Podniosłem tutaj problem , jeśli coś to pomaga. Oto CodeSandbox z działającym przykładem, a najważniejszy kod jest tutaj odtworzony:

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>
    );
  }
}

WybierzValid.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
źródło
1

Ok, oninvalid działa dobrze, ale pokazuje błąd, nawet jeśli użytkownik wprowadził prawidłowe dane. Użyłem więc poniżej, aby go rozwiązać, mam nadzieję, że to również zadziała dla ciebie,

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

Umesh Patil
źródło
-7

Można to łatwo obsłużyć, umieszczając „tytuł” ​​w polu:

<input type="text" id="username" required title="This field can not be empty"  />
Deepti
źródło
Nie zmienia to wyświetlanego komunikatu o błędzie. Pokazuje tylko tytuł na wejściu po najechaniu myszką.
Mathieu Dumoulin,
To nie jest poprawna użyteczność „tytułu” do wyświetlania ostrzeżenia dla pola wejściowego.
sajad saderi