HTML5 membentuk atribut yang diperlukan. Setel pesan validasi khusus?

326

Saya mendapatkan formulir HTML5 berikut: 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"/>

Saat ini ketika saya menekan enter ketika keduanya kosong, kotak popup muncul mengatakan "Silakan isi bidang ini". Bagaimana cara saya mengubah pesan default menjadi "Bidang ini tidak dapat dibiarkan kosong"?

EDIT: Juga perhatikan bahwa pesan kesalahan bidang kata sandi jenis ini sederhana *****. Untuk membuat ulang ini beri nilai pada nama pengguna dan tekan kirim.

EDIT : Saya menggunakan Chrome 10 untuk pengujian. Silakan lakukan hal yang sama

Skizit
sumber
1
Oh, +1 untuk pesan validasi kata sandi kosong kosong = / Bagaimana cara melewati QA, saya bertanya-tanya ...
David mengatakan mengembalikan Monica
3
Mengapa tidak menerima saja pesan default browser? Itulah yang dilihat pengguna untuk setiap situs lain yang mereka kunjungi, Anda hanya akan membingungkan pengguna Anda dengan membuat pesan yang tidak standar. (Google mungkin mengelola lebih banyak evaluasi & pengujian UX dalam menentukan kata-kata itu daripada yang Anda miliki!).
ChrisV
12
@ChrisV Bagaimana dengan situs multilanguage?
inemanja
1
Dalam kasus saya, saya ingin memeriksa bahwa nilainya adalah angka sebelum memposting tetapi saya tidak dapat menggunakan atribut type = "number" (untuk alasan.) Jadi saya mengatur atribut pola untuk memeriksa angka dan desimal opsional yang memberikan pesan , "Harap cocok dengan format yang diminta," pada kesalahan. Saya lebih suka mengatakan, "Kamu harus memberi kita sejumlah uang."
Kristopher

Jawaban:

267

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

Saya berubah menjadi JavaScript vanilla dari Mootools seperti yang disarankan oleh @itpastorn di komentar, tetapi Anda harus dapat bekerja di luar setara Mootools jika perlu.

Edit

Saya telah memperbarui kode di sini karena setCustomValidityberfungsi sedikit berbeda dengan apa yang saya pahami ketika saya awalnya menjawab. Jika setCustomValiditydiatur ke selain string kosong itu akan menyebabkan bidang dianggap tidak valid; karena itu Anda harus menghapusnya sebelum menguji validitas, Anda tidak bisa hanya mengatur dan melupakannya.

Sunting lebih lanjut

Seperti yang ditunjukkan dalam komentar @ thomasvdb di bawah ini, Anda perlu menghapus validitas khusus dalam beberapa kejadian di luar invalidjika tidak, mungkin ada pass tambahan melalui oninvalidhandler untuk menghapusnya.

robertc
sumber
Saya mencoba ini tetapi masih ada kesalahan. Jika Anda membiarkan bidang kosong itu menunjukkan pesan, lalu masukkan sesuatu di bidang tetapi sekarang menunjukkan pesan kosong dan tindakan tidak dijalankan. Jika sekarang Anda mengklik tombol lagi, itu akan melalui.
thomasvdb
1
@thomasvdb Cobalah mengatur validitas khusus ke string kosong pada inputacara tersebut. Saat ini hanya dibersihkan jika invalidacara dipecat.
robertc
Ini memang solusinya. Menemukannya dengan solusi @hleinone. Terima kasih atas tanggapannya!
thomasvdb
4
Solusi di atas hanya menggunakan JQuery untuk menunggu dokumen dimuat. Yang lainnya murni JS dan DOM. Peramban yang cukup modern untuk mendukung setCustomValidity juga harus mendukung acara DOMContentLoaded, artinya JQuery tidak diperlukan, jika tidak digunakan untuk hal lain.
itpastorn
1
@ Lai32290 karena Anda tidak mengakses objek DOM yang sebenarnya. $("")mengembalikan array objek, bahkan jika hanya ada satu. $("")[i]kemungkinan besar apa yang Anda inginkan.
Noah Passalacqua
290

Berikut adalah kode untuk menangani Pesan Kesalahan Khusus dalam HTML5

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

Bagian ini penting karena menyembunyikan pesan kesalahan ketika pengguna memasukkan data baru:

oninput="this.setCustomValidity('')"
Somnath Kadam
sumber
Berfungsi sempurna pada Firefox 29.0 dan Chrome 34.0.1847.137.
Fernando Kosh
sempurna dan dalam FF 38 sejauh ini. Memperbaiki bug dalam validasi email jika hanya oninvalid () yang digunakan.
andrew
Tidak bekerja di Safari di iPad atau iPhone. Bekerja seperti yang diharapkan di Chrome desktop.
Nabeel
2
@ somnath-kadam Apakah ini suatu kesalahan atau Anda sengaja melakukan oninput = "setCustomValidity ('')" alih-alih oninput = "this.setCustomValidity (''" "
tormuto
3
Terima kasih telah menandai oninput = "setCustomValidity ('')" sebagai yang paling penting. Ini menyelamatkan hari saya.
singhpradeep
99

Sangat mudah untuk mengontrol pesan khusus dengan bantuan HTML5acaraoninvalid

Ini kode:

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

Ini yang paling penting:

onvalid="this.setCustomValidity('')"
Ashwini Jain
sumber
3
Periksa juga validasi lain juga seperti pola, nilai min / maks, dll ... sanalksankar.blogspot.com/2010/12/
Jaider
10
Ini menyebabkan bug di firefox di mana ia memvalidasi saat refresh, namun gagal saat perubahan dan koreksi.
Ryan Charmley
12
@RyanCharmley dengan menggunakan onchange="this.setCustomValidity('')"bug akan hilang. Periksa jawaban saya di bawah ini.
Salar
4
Jika ini tidak berhasil (misalnya tidak di Safari, misalnya), gunakan oninputsebagai ganti onvalid.
Jimothy
2
@ Jimothy benar tentang ini, oninputadalah solusi yang lebih universal, onvalidtidak bekerja bahkan di Chrome untuk saya.
ThisGuyCantEven
68

Catatan: Ini tidak lagi berfungsi di Chrome, tidak diuji di peramban lain. Lihat hasil edit di bawah. Jawaban ini ditinggalkan di sini untuk referensi sejarah.

Jika Anda merasa bahwa string validasi benar-benar tidak boleh diatur oleh kode, Anda dapat mengatur atribut judul elemen input Anda untuk membaca "Bidang ini tidak dapat dibiarkan kosong". (Bekerja di Chrome 10)

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

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

Dan di Firefox, Anda dapat menambahkan atribut ini:

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

Edit

Ini tampaknya telah berubah sejak saya awalnya menulis jawaban ini. Sekarang menambahkan judul tidak mengubah pesan validitas, itu hanya menambahkan addendum ke pesan. Biola di atas masih berlaku.

Edit 2

Chrome sekarang tidak melakukan apa pun dengan atribut title pada Chrome 51. Saya tidak yakin versi mana yang diubah.

kzh
sumber
1
Ini tidak mengubah konten pesan yang sebenarnya.
Wesley Murch
2
Saat itu saya mengujinya.
kzh
3
Kesalahan saya, OP yang ditentukan Chrome 10, saya menggunakan FF5. Penghapusan unduhan, permintaan maaf saya. Wow, pesan kesalahan di Chrome itu adalah hal terburuk yang pernah saya lihat.
Wesley Murch
2
Untuk pesan kesalahan deklaratif di Firefox, gunakan atribut:x-moz-errormessage="This field should not be left blank."
robertc
2
Ini menambahkan pesan deskriptif di bawah "Silakan isi bidang ini".
Magne
41

Sangat mudah untuk mengontrol pesan khusus dengan bantuan HTML5 oninvalidacara

Ini kodenya:

User ID 
<input id="UserID"  type="text" required 
       oninvalid="this.setCustomValidity('User ID is a must')">
Dharmendra Jha
sumber
4
itu diperlukan untuk mengatur pesan validitas ke kosong setelah kontrol mengungkapkan input lain pesan validitas pertama dieksekusi akan ditampilkan untuk semua bidang. Tambahkan oninput = "setCustomValidity ('')" setiap kali memanggil setCustomValidity (). +1 untuk jawaban Somnath.
Tarang
41

Dengan mengatur dan membatalkan pengaturan setCustomValiditypada waktu yang tepat, pesan validasi akan berfungsi dengan sempurna.

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

Saya menggunakan onchangealih-alih oninputyang lebih umum dan terjadi ketika nilainya diubah dalam kondisi apa pun bahkan melalui JavaScript.

Salar
sumber
Ini harus menjadi jawaban yang diterima. Bekerja di Windows 10 1709 di browser berikut: Chrome 66.0.3359.139 64 bit, Firefox 59.0.3 (64-bit), Internet Explorer 11.431.16299.0, Edge 41.16299.402.0. Bekerja di macOS 10.13.2 di Safari 11.0 (13604.1.38.1.6). Bekerja di Android 4.4.4 di Chrome 66.0.3359.158. Bagi mereka yang mencari cara BEJ: onInvalid={(e) => { e.target.setCustomValidity('foo') }} onChange={(e) => { e.target.setCustomValidity('') }}.
GuiRitter
Tambahan: emungkin nol, misalnya ketika opsi dihapus dari bidang Pilih Bereaksi. Jangan lupa untuk memeriksa itu.
GuiRitter
Errata: untuk menggunakan ini dengan React Select, Anda harus lulus onChangedan onInvalidsebagaiinputProps={{ onInvalid: …, onChange: …, }}
GuiRitter
Addendum: type='email'sedikit lebih sulit untuk mengobati, karena menggunakan setCustomValidityset customError: trueke e.target.validitybahkan jika input tersebut valid. Saya mencoba mencari cara untuk memperbaikinya.
GuiRitter
@ GuiRitter Apakah Anda mengetahui hal ini?
EvilJordan
39

Saya telah membuat perpustakaan kecil untuk memudahkan mengubah dan menerjemahkan pesan kesalahan. Anda bahkan dapat mengubah teks berdasarkan jenis kesalahan yang saat ini tidak tersedia menggunakan titledi Chrome atau x-moz-errormessagedi Firefox. Go check it out di GitHub , dan memberikan umpan balik.

Ini digunakan seperti:

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

Ada demo yang tersedia di jsFiddle .

hleinone
sumber
Terima kasih! Memecahkan bug kecil saya yang disebutkan sebagai komentar dalam jawaban yang diterima.
thomasvdb
Selamat juga, karena OP menggunakan Google Chrome; apakah ini tidak akan berhasil di IE Edge
CoderHawk
23

Coba yang ini, lebih baik dan teruji:

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/

Rikin Patel
sumber
hei .... solusi bagus tapi ketik = email tidak berfungsi di browser safari. lihat w3schools.com/html/html_form_input_types.asp
Bhawna Malhotra
2
Ya, itu tidak didukung untuk safari, tetapi saya memberikan jawaban untuk pesan validasi khusus yang disetel.
Rikin Patel
10

Cara termudah dan terbersih yang saya temukan adalah menggunakan atribut data untuk menyimpan kesalahan khusus Anda. Uji simpul untuk validitas dan atasi kesalahan dengan menggunakan beberapa html khusus.masukkan deskripsi gambar di sini

le javascript

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

dan beberapa HTML5 super

<input type="text" id="city" name="city" data-pattern-error="Please use only letters for your city." pattern="[A-z ']*" required>
Collin White
sumber
3
Meskipun kesalahan hanya mengatakan huruf, polanya memungkinkan ruang dan tanda kutip? Juga, A-zizinkan '[', '\', ']', '^', '_', dan '`'.
Lawrence Dol
5

Solusi untuk mencegah pesan kesalahan Google Chrome pada input setiap simbol:

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

Saya punya satu-satunya solusi vanilla js yang lebih sederhana:

Untuk kotak centang:

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

Untuk input:

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

Mengadaptasi jawaban Salar ke JSX dan React, saya perhatikan bahwa React Select tidak berperilaku seperti<input/> bidang tentang validasi. Tampaknya, beberapa solusi diperlukan untuk hanya menampilkan pesan khusus dan agar tidak muncul pada waktu yang tidak nyaman.

Saya telah mengangkat masalah di sini , jika itu membantu apa pun. Berikut adalah CodeSandbox dengan contoh yang berfungsi, dan kode paling penting di sana direproduksi di sini:

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

Oke, oninvalid berfungsi dengan baik tetapi itu menunjukkan kesalahan bahkan jika pengguna memasukkan data yang valid. Jadi saya telah menggunakan di bawah ini untuk mengatasinya, berharap itu akan bekerja untuk Anda juga,

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

Umesh Patil
sumber
-7

Dapat dengan mudah ditangani dengan hanya menempatkan 'judul' dengan bidang:

<input type="text" id="username" required title="This field can not be empty"  />
Deepti
sumber
Ini tidak mengubah pesan kesalahan yang ditampilkan. Itu hanya menunjukkan judul pada input saat Anda mengarahkan kursor.
Mathieu Dumoulin
Ini bukan kegunaan yang benar dari "judul" untuk menunjukkan beberapa peringatan untuk bidang input.
sajad saderi