Attributo richiesto modulo HTML5. Impostare un messaggio di convalida personalizzato?


326

Ho il seguente modulo 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"/>

Attualmente quando premo invio quando sono entrambi vuoti, viene visualizzata una finestra popup che dice "Per favore compila questo campo". Come cambierei quel messaggio predefinito in "Questo campo non può essere lasciato vuoto"?

EDIT: nota anche che il messaggio di errore del campo password tipo è semplicemente *****. Per ricrearlo, dai un valore al nome utente e premi invio.

EDIT : sto usando Chrome 10 per i test. Per favore, fai lo stesso


1
Oh, +1 per il folle messaggio di convalida della password vuota = / Come è passato il QA, mi chiedo ...
David dice che ripristini Monica il

3
Perché non accettare semplicemente il messaggio predefinito del browser? Questo è ciò che gli utenti vedono per ogni altro sito che visitano, confonderai i tuoi utenti creando un messaggio non standard. (Google ha probabilmente gestito più test e valutazioni UX nel determinare quella formulazione di quanto tu abbia!).
ChrisV,

12
@ChrisV E i siti multilingua?
Inemanja,

1
Nel mio caso voglio verificare che il valore sia un numero prima di pubblicare ma non posso usare l'attributo type = "number" (per motivi). Quindi ho impostato l'attributo pattern per verificare la presenza di numeri e decimali opzionali che danno il messaggio , "Abbina il formato richiesto" in caso di errore. Preferirei dire "Devi darci un numero di dollari".
Kristopher,

Risposte:


267

Utilizzare 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("");
        };
    }
})

Ho cambiato JavaScript di vaniglia da Mootools come suggerito da @itpastorn nei commenti, ma dovresti essere in grado di elaborare l'equivalente di Mootools se necessario.

modificare

Ho aggiornato il codice qui perché setCustomValidityfunziona in modo leggermente diverso da quello che ho capito quando ho risposto inizialmente. Se setCustomValidityè impostato su un valore diverso dalla stringa vuota, il campo verrà considerato non valido; pertanto è necessario cancellarlo prima di testare la validità, non è possibile impostarlo e dimenticare.

Ulteriore modifica

Come sottolineato nel commento di @ thomasvdb di seguito, è necessario cancellare la validità personalizzata in alcuni eventi al di fuori di invalidaltrimenti potrebbe esserci un passaggio aggiuntivo attraverso il oninvalidgestore per cancellarlo.


Ho provato questo ma c'è ancora un errore. Se lasci il campo vuoto, mostra il messaggio, quindi inserisci qualcosa nel campo, ma ora mostra un messaggio vuoto e l'azione non viene eseguita. Se ora fai di nuovo clic sul pulsante, passerà attraverso.
thomasvdb,

1
@thomasvdb Prova a impostare la validità personalizzata su una stringa vuota inputsull'evento. Al momento viene cancellato solo se l' invalidevento viene generato.
robertc,

Questa è davvero la soluzione. L'ho scoperto con la soluzione di @hleinone. Grazie per la risposta!
thomasvdb,

4
La soluzione precedente utilizza solo JQuery per attendere il caricamento del documento. Tutto il resto è JS e DOM puri. Un browser abbastanza moderno da supportare setCustomValidity dovrebbe anche supportare l'evento DOMContentLoaded, il che significa che JQuery non è necessario, se non viene utilizzato per nient'altro.
itpastorn,

1
@ Lai32290 perché non si accede all'oggetto DOM effettivo. $("")restituisce un array di oggetti, anche se ce n'è solo uno. $("")[i]è molto probabilmente quello che vuoi.
Noah Passalacqua,

290

Ecco il codice per gestire il messaggio di errore personalizzato in HTML5

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

Questa parte è importante perché nasconde il messaggio di errore quando l'utente immette nuovi dati:

oninput="this.setCustomValidity('')"

Funziona perfettamente su Firefox 29.0 e Chrome 34.0.1847.137.
Fernando Kosh,

perfetto e in FF 38 finora. Correzione del bug nella convalida dell'email se si utilizza solo oninvalid ().
Andrew,

Non funziona in Safari su iPad o iPhone. Funziona come previsto nel desktop Chrome però.
Nabeel,

2
@ somnath-kadam È un errore o hai fatto intenzionalmente oninput = "setCustomValidity ('')" invece di oninput = "this.setCustomValidity ('')"
tormuto

3
Grazie per aver contrassegnato oninput = "setCustomValidity ('')" come più importante. Questo mi ha salvato la giornata.
singhpradeep,

99

È molto semplice controllare i messaggi personalizzati con l'aiuto HTML5dell'eventooninvalid

Ecco il codice:

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

Questo è molto importante:

onvalid="this.setCustomValidity('')"

3
Controlla anche altre convalide come pattern, valori min / max, ecc ... sanalksankar.blogspot.com/2010/12/…
Jaider

10
Ciò provoca un bug in Firefox in cui si convalida al momento dell'aggiornamento, ma fallisce in caso di modifica e correzione.
Ryan Charmley,

12
@RyanCharmley usando onchange="this.setCustomValidity('')"il bug sparirà . Controlla la mia risposta qui sotto.
Salar,

4
Se questo non funziona (ad esempio in Safari non funziona), utilizzare oninputinvece di onvalid.
Jimothy,

2
@Jimothy ha ragione su questo, oninputè la soluzione più universale, onvalidnon ha funzionato nemmeno in Chrome per me.
ThisGuyCantEven

68

Nota: questo non funziona più in Chrome, non testato in altri browser. Vedi le modifiche di seguito. Questa risposta viene lasciata qui per riferimento storico.

Se ritieni che la stringa di convalida non debba essere impostata in base al codice, puoi impostare l'attributo title dell'elemento di input in modo da leggere "Questo campo non può essere lasciato vuoto". (Funziona in Chrome 10)

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

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

E in Firefox, puoi aggiungere questo attributo:

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

modificare

Questo sembra essere cambiato da quando ho scritto originariamente questa risposta. Ora l'aggiunta di un titolo non modifica il messaggio di validità, ma aggiunge semplicemente un addendum al messaggio. Il violino sopra si applica ancora.

Modifica 2

Chrome ora non fa nulla con l'attributo title a partire da Chrome 51. Non sono sicuro di quale versione sia cambiata.


1
Ciò non modifica il contenuto effettivo del messaggio.
Wesley Murch,

2
Al momento l'ho provato.
kzh

3
Il mio errore, OP ha specificato Chrome 10, ero su FF5. Rimosso il voto negativo, le mie scuse. Caspita, quel messaggio di errore in Chrome è la cosa più brutta che abbia mai visto.
Wesley Murch,

2
Per i messaggi di errore dichiarativi in ​​Firefox, utilizzare l'attributo:x-moz-errormessage="This field should not be left blank."
robertc

2
Ciò aggiunge un messaggio descrittivo nel campo "Compila questo campo".
Magne,

41

È molto semplice controllare i messaggi personalizzati con l'aiuto HTML5 oninvaliddell'evento

Ecco il codice:

User ID 
<input id="UserID"  type="text" required 
       oninvalid="this.setCustomValidity('User ID is a must')">

4
è necessario impostare il messaggio di validità su vuoto una volta che il controllo riceve input altrimenti verrà visualizzato il primo messaggio di validità eseguito per tutti i campi. Aggiungi oninput = "setCustomValidity ('')" ogni volta che chiami setCustomValidity (). +1 alla risposta di Somnath.
Tarang,

41

Impostando e annullando l'impostazione setCustomValidityal momento giusto, il messaggio di convalida funzionerà in modo impeccabile.

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

Ho usato al onchangeposto del oninputquale è più generale e si verifica quando il valore viene modificato in qualsiasi condizione, anche tramite JavaScript.


Questa dovrebbe essere la risposta accettata. Ha funzionato in Windows 10 1709 nei seguenti browser: Chrome 66.0.3359.139 64 bit, Firefox 59.0.3 (64 bit), Internet Explorer 11.431.16299.0, Edge 41.16299.402.0. Ha funzionato in macOS 10.13.2 in Safari 11.0 (13604.1.38.1.6). Ha funzionato in Android 4.4.4 in Chrome 66.0.3359.158. Per chi cerca il modo JSX: onInvalid={(e) => { e.target.setCustomValidity('foo') }} onChange={(e) => { e.target.setCustomValidity('') }}.
GuiRitter

Addendum: epotrebbe essere nullo, ad esempio quando un'opzione viene rimossa da un campo React Select. Non dimenticare di verificarlo.
GuiRitter

Errata: per usarlo con React Select, devi passare onChangee onInvalidcomeinputProps={{ onInvalid: …, onChange: …, }}
GuiRitter

Addendum: type='email'è un po 'più difficile da trattare, in quanto utilizzando setCustomValidityset customError: truea e.target.validityanche se l'ingresso è valido. Sto cercando di trovare un modo per risolverlo.
GuiRitter,

@GuiRitter L'hai capito?
EvilJordan,

39

Ho creato una piccola libreria per facilitare la modifica e la traduzione dei messaggi di errore. Puoi persino modificare i testi per tipo di errore che al momento non è disponibile utilizzando titlein Chrome o x-moz-errormessageFirefox. Vai a dare un'occhiata su GitHub e dai un feedback.

È usato come:

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

C'è una demo disponibile su jsFiddle .


Grazie! Risolto il mio piccolo bug menzionato come commento nella risposta accettata.
thomasvdb,

Buona risposta, poiché OP utilizza Google Chrome; anche se questo non funzionerà in IE Edge
CoderHawk,

23

Prova questo, è migliore e testato:

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

demo:

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


hey .... bella soluzione ma type = email non funziona nel browser Safari. dai un'occhiata w3schools.com/html/html_form_input_types.asp
Bhawna Malhotra

2
Sì, non è supportato per Safari, ma ho dato una risposta per impostare un messaggio di convalida personalizzato.
Rikin Patel,

10

Il modo più semplice e pulito che ho trovato è utilizzare un attributo di dati per memorizzare l'errore personalizzato. Verifica la validità del nodo e gestisci l'errore utilizzando un codice HTML personalizzato.inserisci qui la descrizione dell'immagine

le javascript

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

e alcuni super HTML5

<input type="text" id="city" name="city" data-pattern-error="Please use only letters for your city." pattern="[A-z ']*" required>

3
Nonostante l'errore che dice solo lettere, il modello consente spazio e apostrofo? Inoltre, A-zconsente '[', '\', ']', '^', '_' e '`'.
Lawrence Dol

5

La soluzione per prevenire i messaggi di errore di Google Chrome sull'input di ciascun simbolo:

<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

Ho una soluzione js jsilla più semplice:

Per le caselle di controllo:

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

Per gli ingressi:

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

1

Adattamento Salar risposta s' a JSX e reagire, ho notato che reagiscono Select non si comporta proprio come un <input/>campo per quanto riguarda la convalida. Apparentemente, sono necessarie diverse soluzioni alternative per mostrare solo il messaggio personalizzato e per impedirne la visualizzazione in momenti scomodi.

Ho sollevato un problema qui , se aiuta qualcosa. Ecco un CodeSandbox con un esempio funzionante e qui viene riprodotto il codice più importante:

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

1

Ok, oninvalid funziona bene ma mostra errori anche se l'utente ha inserito dati validi. Quindi ho usato di seguito per affrontarlo, spero che funzioni anche per te,

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


-7

Può essere facilmente gestito semplicemente inserendo 'title' nel campo:

<input type="text" id="username" required title="This field can not be empty"  />

Questo non cambia il messaggio di errore visualizzato. Mostra solo un titolo sull'input quando si passa con il mouse.
Mathieu Dumoulin,

Questa non è la corretta usabilità di "titolo" per mostrare un avviso per il campo di input.
sajad saderi,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.