如何在没有提交事件的情况下显示 setCustomValidity 消息/工具提示

Posted

技术标签:

【中文标题】如何在没有提交事件的情况下显示 setCustomValidity 消息/工具提示【英文标题】:How to show setCustomValidity message/tooltip without submit event 【发布时间】:2012-09-28 22:01:18 【问题描述】:

我正在使用表单基本验证来检查电子邮件格式是否正确,然后数据由 Ajax 发送,它检查电子邮件地址是否已在使用中,用户是否选择国家/州或在选择框中保留默认值.

但是要完成 html5 表单验证,需要提交事件,如果它通过了基本表单验证,则单击提交时会执行 Ajax 操作,但是当结果出现时,我想使用相同的浏览器工具提示来实现界面一致性(而且我喜欢它们的外观)。

那么有没有办法让它们显示出来,我无法找到它们是否有一些特殊事件或类似触发提交事件但立即停止它的东西。现在该字段只有一个红色边缘,并且在将鼠标悬停在它上面时会出现错误消息,而工具提示会在再次单击提交按钮时显示。

对于没有本机工具提示的浏览器(在我的情况下为 Safari),我使用的是 Webshims Lib,它的行为与 Chrome 和 Firefox 中的完全相同。

【问题讨论】:

【参考方案1】:

查看此链接 (Provide custom validation messages using setCustomValidity in HTML 5 pages)。

在上面的链接中,他使用了“输入”类型是数字,并且在输入上他调用了验证函数。让我知道这就是你要找的。

<input type="number" required="true" value="50" min="18" max="60" step="1" oninput="validate(this)">

【讨论】:

这很好,但是如何显示看起来像浏览器的消息 div? required 是一个布尔属性。您根本不需要将其设置为任何值,只需包含该属性即可。它的存在就足以让布尔属性起作用。【参考方案2】:

您可以在此链接找到答案:How to force a html5 form validation without submitting it via jQuery

基本上,你找到一个提交按钮并调用点击它:

// force form validation
document.getElementById("submitbutton").click()

您也可以在检查电子邮件地址是否正在使用后更改验证消息,然后如上所述强制表单验证:

document.getElementById("email").setCustomValidity("This email is already registered!");
document.getElementById("submitbutton").click()

【讨论】:

但是如果表格是有效的呢?然后它会提交它。 :/ Alexxandar 只想检查有效性并显示有效性消息而不提交。 通过使用空字符串以外的任何内容调用 setCustomValidity,您将强制表单无效。因此,它不会提交。 你如何为 ie8 填充它? jQuery 在这里无关紧要,同样可以使用 vanilla JS 来完成。 @Madbreaks jQuery 是相关的,因为这是 oldbam 找到解决方案的地方,并且引用您的来源是正确的。他的回答没有说​​它依赖于拥有 jQuery。事实上,oldbam 的原始答案只指定了一个 URL(其中恰好有“jquery”)。该页面的实际标题是由 *** 机器人插入的!【参考方案3】:

如果条件为 false,您可以对元素使用 setCustomValidity(您可以在任何事件处理程序中执行此操作,例如 keypress 或 click )。如果输入无效,请提交。这将触发浏览器的消息提示。

【讨论】:

【参考方案4】:

我认为.checkValidity() 可以解决问题,但它不会触发 UI。 (caniuse)

这听起来像.reportValidity() 做你想做的事。 (caniuse)

【讨论】:

Chrome 和 Opera 现在支持 .reportValidity() developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/… 如果不支持 checkValidity if(!$('#form')[0].checkValidity()) setTimeout(function () $('#form button').click();, 100);【参考方案5】:

其实很简单——在表单中添加一个隐藏的输入元素:

<input type="hidden" id="myFormCheck" required="true" value=""/>

在要创建自定义工具提示的输入元素上调用myInputField.setCustomValidity(message),然后调用form.click();

表单有效性过程运行并在该元素上显示消息弹出窗口,但由于隐藏元素,表单不会提交,因此您无需捕获和取消提交事件。

当你完成并真正准备好时,在隐藏元素上设置一个值,表单将正常提交。

通过这种方式,您可以使用表单工具提示来检查可用的用户名,或通过 HTTP 请求匹配任何值等。

【讨论】:

【参考方案6】:

正如大多数人所说,您必须使用input.setCustomValidity("message")

这里的问题是您无法在 submit 事件中检查该验证,因为您需要进行 ajax 调用然后异步设置 setCustomValidity

所以基本上你必须使用输入字段的change 事件并在每次更改时调用 ajax。或者去掉提交按钮,使用普通按钮的click事件,在ajax调用中检查唯一email,然后通过javascript调用submit。

查看使用 jQuery 的最后一个选项的示例:

<form action="/sign-in" id="form">
    <input type="email" id="email" required/>
    <button id="submit">Submit</button>
</form>
// we capture the click instead the submit
$("#submit").on("click",function()
    var $elem = $("#email");
    var email = $elem.val();

    //the ajax call returns true if the email exists
    $.get( "ajax/checkUniqueEmail", function(data) 
        if(data === "true")
            $elem.setCustomValidity("This email already exists.");
        else
            $elem.setCustomValidity("")
        
        //then we submit the form
        $("#form").submit();
    );
);

【讨论】:

【参考方案7】:

Here's a nice live example 自定义验证/提供有关表单输入的反馈。

基本的javascript看起来像:

function checkPasscode() 
    var passcode_input = document.querySelector("#passcode");

    if (passcode_input.value != "Ivy") 
        passcode_input.setCustomValidity("Wrong. It's 'Ivy'.");
     else 
        passcode_input.setCustomValidity(""); // be sure to leave this empty!
        alert("Correct!");
    

HTML:

<form>
    <label for="passcode">Enter Passcode:</label>
    <input id="passcode" 
           type="password" 
           placeholder="Your passcode" 
           oninput="checkPasscode();"
           required/>
    <button type="submit">Submit</button>
</form>

【讨论】:

至少在Chrome中,自定义工具提示/消息只有在点击提交按钮时才会显示【参考方案8】:

HTMLFormElement.reportValidity() 的 polyfill。 用 IE11 和 Edge 测试。但是当在下面的 *** 沙箱中运行 IE11 时,验证消息不显示。

function reportValidityPolyfill() 
  const button = createInvisibleSubmitButton();
  this.appendChild(button);
  this.addEventListener("submit", submitEventHandler);
  var isValid = false;
  button.click();
  this.removeEventListener("submit", submitEventHandler);
  this.removeChild(button);
  return isValid;

  function createInvisibleSubmitButton() 
    const button = document.createElement("button");
    button.type = "submit";
    button.style.display = "none";
    return button;
  

  function submitEventHandler(event) 
    event.preventDefault();
    isValid = true;
  


if (!HTMLFormElement.prototype.reportValidity) 
  HTMLFormElement.prototype.reportValidity = reportValidityPolyfill;
  console.log("ReportValidity polyfill installed.");
 else 
  console.log("ReportValidity polyfill skipped.");
input 
  outline: 1px solid #0f0;


input:invalid 
  outline: 1px solid #f00;
<form id="form1">
  Enter a number from 1 to 5: <input type="number" min="1" max="5" required>
</form>
<br>
<div onclick="console.log('Validity: ' + document.getElementById('form1').reportValidity())">
  Click here to call reportValidity()
</div>

【讨论】:

【参考方案9】:

setCustomValidity() 可以解决我更改密码、确认密码输入的问题。

但问题是当我们设置 setCustomValidity('Passwords do not match) 时,它并没有被清除为附加到表单提交事件。

我刚刚在密码确认输入按键事件中将 setCustomValidity('') 添加到空白。

它对我有用。

 $(document).ready(function() 
            const confirm = document.querySelector('input[name=password2]');
            $('#pass2').on('keyup', function()
                confirm.setCustomValidity('');
            )
            $("#reset-pw-form").on('submit', function(e) 
                e.preventDefault();
                if($('#pass1').val() != $('#pass2').val())  
                    confirm.setCustomValidity('Passwords do not match');
                    confirm.reportValidity();
                    return false;
                

【讨论】:

以上是关于如何在没有提交事件的情况下显示 setCustomValidity 消息/工具提示的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有按钮的情况下提交表单?

Laravel:如何在没有表单操作的情况下提交复选框值?

TableView 不会在焦点丢失事件上提交值

Stack Overflow 如何在不重新加载页面的情况下通知服务器端事件?我在 Firebug 中没有看到任何请求

如何在没有按钮的情况下在 UITextField 中显示来自 UIDataPicker 的值

如何在存在等于“提交”的输入 ID 的情况下进行 javascript 提交