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

IT技术 javascript forms html validation tooltip
2021-03-05 20:32:52

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

但是要完成 HTML5 表单验证,需要提交事件,如果它通过了基本的表单验证 Ajax 操作,则在单击提交时执行,但是当结果出现时,我想使用相同的浏览器工具提示来保持界面一致性(而且我就像他们的样子)。

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

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

6个回答

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

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

如果不支持 checkValidity if(!$('#form')[0].checkValidity()) setTimeout(function () { $('#form button').click();}, 100);
2021-04-20 20:32:52
Chrome 和 Opera 现在支持.reportValidity() developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/...
2021-05-19 20:32:52

您可以在此链接中找到答案:如何在不通过 jQuery 提交的情况下强制进行 html5 表单验证

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

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

您还可以在检查电子邮件地址是否正在使用后更改验证消息,然后按上述方式强制进行表单验证:

document.getElementById("email").setCustomValidity("This email is already registered!");
document.getElementById("submitbutton").click()
jQuery 在这里无关紧要,同样可以使用 vanilla JS 来完成。
2021-05-01 20:32:52
你如何为 ie8 填充它?
2021-05-06 20:32:52
@Madbreaks jQuery 是相关的,因为这是 oldbam 找到解决方案的地方,并且引用您的来源是合适的。他的回答没有任何地方说它依赖于拥有 jQuery。事实上,oldbam 的原始答案仅指定了一个 URL(恰好在其中包含“jquery”)。该页面的实际标题是由 StackOverflow 机器人插入的!
2021-05-08 20:32:52
但是如果表单有效呢?然后它会提交它。:/ Alexxandar 只想检查有效性并显示有效性消息而不提交。
2021-05-12 20:32:52
通过使用空字符串以外的任何内容调用 setCustomValidity,您将强制表单无效。因此,它不会提交。
2021-05-15 20:32:52

它实际上非常简单 - 在表单中添加一个隐藏的输入元素:

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

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

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

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

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

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

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>

正如大多数人所说,您必须使用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();
    });
});