如何为HTML表单设置自定义验证消息?

How to set custom validation messages for HTML forms?

提问人:Skizit 提问时间:3/11/2011 最后编辑:TylerHSkizit 更新时间:5/5/2023 访问量:825246

问:

我有以下 HTML 表单: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"/>

目前,当我在它们都为空时按回车键时,会出现一个弹出框,上面写着“请填写此字段”。如何将默认消息更改为“此字段不能留空”?

键入密码字段的错误消息只是 。要重新创建此值,请为用户名指定一个值并点击提交。*****

JavaScript HTML 表单 验证 约束-validation-api

评论

4赞 ChrisV 12/4/2011
为什么不直接接受浏览器默认消息?这就是用户在他们访问的所有其他网站上看到的内容,您只会通过创建非标准消息来混淆您的用户。(谷歌在确定措辞方面可能比你管理了更多的用户体验评估和测试!
18赞 inemanja 11/26/2013
@ChrisV 多语言网站呢?
3赞 Kristopher 3/29/2017
就我而言,我想在发布之前检查该值是否为数字,但我不能使用 type=“number” 属性(出于原因。因此,我设置了 pattern 属性来检查数字和可选小数,这在出错时会显示消息“请匹配请求的格式”。我宁愿它说,“你们必须给我们一个数字的bucko。

答:

339赞 robertc 3/12/2011 #1

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

按照@itpastorn在评论中的建议,我从 Mootools 改用了普通的 JavaScript,但如有必要,您应该能够计算出 Mootools 等效项。

如果设置为空字符串以外的任何值,则会导致该字段被视为无效;因此,您必须在测试有效性之前清除它,您不能只是设置它并忘记它。setCustomValidity

正如@thomasvdb在下面的评论中指出的那样,您需要在特定事件中清除自定义有效性,否则可能会有额外的处理程序通过来清除它。invalidoninvalid

评论

0赞 Lai32290 3/23/2014
为什么当我将 elements[i] 替换为 $(“#name”) 时,它不起作用?如果我设置了 2 个验证,例如需要 type='number',我可以为它们设置不同的自定义消息吗?
1赞 Noah Passalacqua 5/22/2016
@Lai32290,因为您没有访问实际的 DOM 对象。 返回一个对象数组,即使只有一个对象。 很可能是你想要的。$("")$("")[i]
1赞 John 8/1/2018
我并不是说这段代码好不好,但是在 HTML5 中进行表单验证的意义在于不需要 JavaScript 进行表单验证,因此即使对于“纯粹主义者”使用该属性也是完全没有意义的。oninvalid
0赞 Mathias Zaja 4/21/2019
这适用于具有必需属性的输入。但是,它不适用于输入 type=“email”。输入电子邮件地址的第一个字符后,您将回退到标准错误消息“请包含'@'到...”我试图用else if(e.target.validity.typeMismatch){ e.target.setCustomValidity(“我自己的消息”)来捕获它。没有成功。有什么建议吗?
71赞 kzh 4/19/2011 #2

注意:这在 Chrome 中不再有效,在其他浏览器中也未进行测试。请参阅下面的编辑。这个答案留在这里供历史参考。

如果您觉得验证字符串确实不应该通过代码设置,则可以将输入元素的 title 属性设置为“此字段不能留空”。(适用于 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 51 起,Chrome 现在不对 title 属性执行任何操作。我不确定这在哪个版本中发生了变化。

评论

1赞 kzh 8/2/2011
我不认为 title 属性应该是最好的地方。也许浏览器应该实现一些其他属性并就此达成一致。
2赞 robertc 9/9/2011
对于 Firefox 中的声明性错误消息,请使用以下属性:x-moz-errormessage="This field should not be left blank."
2赞 Magne 11/19/2013
这将在“请填写此字段”下添加一条描述性消息。
0赞 kzh 11/20/2013
@Magne 自从我最初写这个答案以来,这似乎发生了变化。
43赞 hleinone 4/2/2012 #3

我制作了一个小库,以方便更改和翻译错误消息。您甚至可以按错误类型更改文本,目前在Chrome或Firefox中不可用。在 GitHub 上查看并提供反馈。titlex-moz-errormessage

它的用法如下:

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

jsFiddle 上有一个演示

52赞 Dharmendra Jha 7/20/2012 #4

借助事件控制自定义消息非常简单HTML5oninvalid

代码如下:

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

评论

8赞 Tarang 4/27/2015
一旦控件拒绝输入,需要将有效性消息设置为空白,否则将显示所有字段的首次执行有效性消息。每当调用 setCustomValidity() 时,添加 oninput=“setCustomValidity('')”。+1 到 Somnath 的答案。
115赞 Ashwini Jain 8/13/2012 #5

借助事件控制自定义消息非常简单HTML5oninvalid

代码如下:

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

这是最重要的:

onvalid="this.setCustomValidity('')"

评论

3赞 Jaider 11/25/2012
还要检查其他验证,例如模式、最小值/最大值等......sanalksankar.blogspot.com/2010/12/......
10赞 Ryan Charmley 8/30/2013
这会导致 firefox 中出现一个错误,它在刷新时进行验证,但在更改和更正时失败。
12赞 Salar 4/1/2014
使用该错误@RyanCharmley将消失。在下面查看我的答案。onchange="this.setCustomValidity('')"
8赞 Jimothy 3/28/2018
如果这不起作用(例如,在 Safari 中不起作用),请使用 代替 。oninputonvalid
4赞 ThisGuyCantEven 6/11/2018
@Jimothy对此是正确的,是更通用的解决方案,即使在 Chrome 中也对我不起作用。oninputonvalid
15赞 Collin White 4/18/2013 #6

我发现的最简单、最干净的方法是使用数据属性来存储您的自定义错误。测试节点的有效性,并使用一些自定义 html 处理错误。enter image description here

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>

评论

4赞 Lawrence Dol 9/1/2013
尽管错误只说字母,但模式允许空格和撇号?此外,还允许 '['、'\'、']'、'^'、'_' 和 '''。A-z
490赞 Somnath Kadam 11/25/2013 #7

下面是一些用于显示自定义错误消息的代码:

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

这部分很重要,因为它会在用户输入新数据时隐藏错误消息:

oninput="setCustomValidity('')"

注意:内联事件处理程序不需要该关键字,但您可能希望无论如何都使用它以保持一致性。this

评论

4赞 phil294 10/3/2019
请注意,在这种情况下,您甚至可以省略 ,因为内联事件处理程序使用 with(this) 运行(不是说您应该这样做)this.
36赞 Rikin Patel 3/14/2014 #8

试试这个,它更好,经过测试:

    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;
    }
<form id="myform">
    <input id="email" 
           oninvalid="InvalidMsg(this);" 
           oninput="InvalidMsg(this);"
           name="email"  
           type="email" 
           required="required" />
    <input type="submit" />
</form>

演示:

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

评论

0赞 Bhawna Malhotra 4/16/2016
嘿。。。。不错的解决方案,但 type=email 在 Safari 浏览器中不起作用。看一看 w3schools.com/html/html_form_input_types.asp
2赞 Rikin Patel 4/19/2016
是的,它不支持 safari,但我给出了设置自定义验证消息的答案。
47赞 Salar 4/1/2014 #9

通过在正确的时间设置和取消设置,验证消息将完美运行。setCustomValidity

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

我使用的 instead of which 更通用,并且当值在任何条件下更改时都会发生,即使通过 JavaScript 也是如此。onchangeoninput

评论

0赞 GuiRitter 5/17/2018
这应该是公认的答案。在以下浏览器中适用于 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。在 Safari 10.13.2 (13604.1.38.1.6) 的 macOS 11.0 中工作。在Chrome 4.4.4.4的Android 66.0.3359.158中工作。对于那些寻找 JSX 方式的人:.onInvalid={(e) => { e.target.setCustomValidity('foo') }} onChange={(e) => { e.target.setCustomValidity('') }}
0赞 GuiRitter 5/17/2018
附录:可能为 null,例如,当从 React Select 字段中删除选项时。别忘了检查一下。e
0赞 GuiRitter 5/21/2018
勘误表:要将其与 React Select 一起使用,您必须通过 和 asonChangeonInvalidinputProps={{ onInvalid: …, onChange: …, }}
0赞 GuiRitter 5/21/2018
附录:有点难以处理,因为即使输入有效,也要使用集合。我正在努力找到一种方法来修复它。type='email'setCustomValiditycustomError: truee.target.validity
1赞 GuiRitter 9/20/2019
@EvilJordan 在这里发送电子邮件
7赞 bernhardh 8/18/2016 #10

我有一个更简单的仅限香草 js 的解决方案:

对于复选框:

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

对于输入:

document.getElementById("id").oninvalid = function () {
    this.setCustomValidity(this.value ? '' : 'My message');
};
2赞 GuiRitter 5/24/2018 #11

Salar 的答案改编为 JSX 和 React,我注意到 React Select 的行为并不像一个关于验证的字段。显然,需要几种解决方法来仅显示自定义消息并防止它在不方便的时间显示。<input/>

我在这里提出了一个问题,如果它有什么帮助的话。下面是一个带有工作示例的 CodeSandbox,其中最重要的代码在这里复制:

你好 .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>
    );
  }
}

选择有效 .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}
      />
    );
  }
}
4赞 Umesh Patil 8/28/2018 #12

好的,oninvalid 运行良好,但即使用户输入有效数据,它也会显示错误。所以我在下面用它来解决这个问题,希望它也对你有用,

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

9赞 Andrei Veshtard 2/20/2019 #13

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

评论

0赞 Matt 8/10/2021
乍一看,我以为我知道为什么会这样,但我无法弄清楚。有人可以解释一下吗?(IIFE如何改变这一点?
-15赞 Deepti 5/17/2019 #14

只需将“title”与字段放在一起即可轻松处理:

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

评论

1赞 Mathieu Dumoulin 7/17/2019
这不会更改显示的错误消息。当您将鼠标悬停时,它只会在输入上显示标题。
1赞 S.Saderi 4/11/2020
这不是“title”的正确可用性,无法显示输入字段的某些警报。
1赞 Pinaki 2/17/2021
“title”不会更改默认的“required”消息。
0赞 hackernewbie 9/6/2021
标题有一个完全不同的目的。
6赞 Carson 11/10/2021 #15

如果您的错误消息是一条,请尝试以下操作。

<input oninvalid="this.setCustomValidity('my error message')"
       oninput="this.setCustomValidity('')">  <!-- 👈 don't forget it. -->

要处理多个错误,请尝试以下操作

<input oninput="this.setCustomValidity('')">
<script>
inputElem.addEventListener("invalid", ()=>{
    if (inputElem.validity.patternMismatch) {
      return inputElem.setCustomValidity('my error message')
    }
    return inputElem.setCustomValidity('') // default message
})
</script>

您可以测试输入非法文件名valueMissing

<form>
<input pattern="[^\\/:\x22*?<>|]+"
       placeholder="input file name"       
       oninput="this.setCustomValidity('')"
       required
>
  <input type="submit">
</form>

<script>
  const form = document.querySelector("form")

  const inputElem = document.querySelector(`input`)

  inputElem.addEventListener("invalid", ()=>{   
    if (inputElem.validity.patternMismatch) {
      return inputElem.setCustomValidity('Illegal Filename Characters \\/:\x22*?<>|')
    }
    return inputElem.setCustomValidity('') // return default message according inputElem.validity.{badInput, customError, tooLong, valueMissing ...}
  })

  form.onsubmit = () => {
    return false
  }
</script>

1赞 Ajay 4/7/2022 #16
const username= document.querySelector('#username');
const submit=document.querySelector('#submit');

submit.addEventListener('click',()=>{
    if(username.validity.typeMismatch){
        username.setCustomValidity('Please enter User Name');
    }else{
        username.setCustomValidity('');
    }
if(pass.validity.typeMismatch){
        pass.setCustomValidity('Please enter Password');
    }else{
        pass.setCustomValidity('');
    }

})

评论

1赞 TylerH 2/22/2023
这似乎并没有为现有答案增加任何新内容。
1赞 Baro 6/26/2022 #17

对于完全自定义的检查逻辑:

$(document).ready(function() {

  $('#form').on('submit', function(e) {
    if ($('#customCheck').val() != 'apple') {
      $('#customCheck')[0].setCustomValidity('Custom error here! "apple" is the magic word');
      $('#customCheck')[0].reportValidity();
      e.preventDefault();
    }
  });

  $('#customCheck').on('input', function() {
    $('#customCheck')[0].setCustomValidity('');
  });


});
input {
  display: block;
  margin-top: 15px;
}

input[type="text"] {
  min-width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id="form">
  <input type="text" placeholder="dafault check with 'required' TAG" required/>
  <input type="text" placeholder="custom check for word 'apple'" id="customCheck" />
  <input type="submit">
</form>