首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HTML 5验证定制

HTML 5验证定制
EN

Stack Overflow用户
提问于 2022-03-29 06:56:34
回答 1查看 48关注 0票数 -1

我想要一份表格:

  1. 以自定义格式而不是默认样式显示验证消息。
  2. 一次显示所有无效字段气泡,而不是一次显示一个。

现在,我陷入了无聊的浏览器特有的消息外观,我没有看到下一个错误,直到我纠正最后一个。这是一个非常糟糕的用户体验,因此寻找一些关于如何解决这个问题的建议。

这是我当前的JavaScript代码:

代码语言:javascript
复制
const contactUsForm = document.querySelector('#Form');

if (contactUsForm) {

    function Validate() {
    
        validatedFields = contactUsForm.querySelectorAll('[data-validation-required],[data-validation-format]');
        validatedFields.forEach(field => {
            /* RegEx patterns */
            const emailPattern = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
                
            if (field.getAttribute('type') === 'email')
            {
                field.setAttribute('pattern', emailPattern);
            }


            if (field.validity.valueMissing) {
                field.setCustomValidity(field.dataset.validationRequired);
            }
            else if (field.validity.patternMismatch) {
                field.setCustomValidity(field.dataset.validationFormat);
            }
            else {
                field.setCustomValidity('');
            }

            
            field.reportValidity();
            contactUsForm.checkValidity();


            /* Recheck on field value change */
            field.addEventListener('change', function() {
                field.setCustomValidity('');
                Validate();
            });
        });
    }

    Validate();
    
    
    contactUsForm.addEventListener('submit', function(e) {
        e.preventDefault;
        
        if (e.checkValidity() == false) {
            return false;
        }
        else {
            // form.submit()
        }
    });

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-29 12:26:36

造型验证气泡/工具提示过去是功能,但只限于Chrome,但它被删除。有关它的更多信息,请在这里:如何设置HTML5表单验证消息的样式?

但是,您可以创建自己的工具提示或气泡来显示验证消息。通过使用div容器、span和一些CSS,您可以创建一个具有几乎任何外观的气泡。

代码语言:javascript
复制
.ttCont {
  position: relative;
  display: inline-block;
}
.ttCont .ttText {
  display: inline-block;
  visibility: hidden;
  min-width: 200px;
  background-color: darkblue;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px;
  opacity: 0;
  transition: opacity 0.5s;

  /* Place bubble to the right of container */
  position: absolute;
  z-index: 1;
  top: 5px;
  left: 105%;
}
.ttCont .ttText::after {
  content: " ";
  position: absolute;
  top: 50%;
  right: 100%; /* To the left of the bubble */
  margin-top: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent darkblue transparent transparent;
}
.ttCont .ttText.active{
  visibility: visible;
  opacity: 1;
}

现在使用自定义气泡意味着您可能需要更少地使用ValidityState API,但是仍然可以使用相同的方法验证您的字段。与使用field.reportValidity()不同,您可以创建一个自定义函数,在每个字段验证时显示一个气泡。

代码语言:javascript
复制
function customReportValidatity(elem, type) {
  let msg = "";
  ///check if validity is based on required or mismatch///
  switch (type) {
    case 'required':
      msg = $(elem).attr('data-validation-required');
      ///without jQuery
      // msg = elem.dataset.validationRequired;
      break;
    case 'format':
      msg = $(elem).attr('data-validation-format');
      ///without jQuery
      // msg = elem.dataset.validationFormat;
      break;
    default:
      break;
  }
  ///make popup appear///

  let ttText = $(elem).parent().children('.ttText');
  $(ttText).text(msg);
  $(ttText).addClass('active');

  ///without jQuery
  // let ttText = elem.parentElement.querySelector('.ttText');
  // ttText.innerText = msg;
  // ttText.classList.add('active');

}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>

使用该样式和自定义函数,您可以将它应用到您愿意应用到的任何形式的现有代码中。在这种情况下,我制作了一个示例表单,它接受所需的名称和电子邮件,而不需要描述。

代码语言:javascript
复制
const contactUsForm = document.querySelector('#Form');
const submitBtn = document.querySelector('#submitBtn');

if (contactUsForm) {
  function customReportValidatity(elem, type) {
    let msg = "";
    ///check if validity is based on required or mismatch///
    switch (type) {
      case 'required':
        msg = $(elem).attr('data-validation-required');
        ///without jQuery
        // msg = elem.dataset.validationRequired;
        break;
      case 'format':
        msg = $(elem).attr('data-validation-format');
        ///without jQuery
        // msg = elem.dataset.validationFormat;
        break;
      default:
        break;
    }
    ///make popup appear///

    let ttText = $(elem).parent().children('.ttText');
    $(ttText).text(msg);
    $(ttText).addClass('active');

    ///without jQuery
    // let ttText = elem.parentElement.querySelector('.ttText');
    // ttText.innerText = msg;
    // ttText.classList.add('active');

  }

  function Validate() {
    let isValid = true;

    /* RegEx patterns */
    const emailPattern = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;

    let validatedFields = contactUsForm.querySelectorAll('[data-validation-required],[data-validation-format]');
    validatedFields.forEach(field => {

      if (field.getAttribute('type') === 'email') {
        field.setAttribute('pattern', emailPattern);
      }

      if (field.validity.valueMissing) {
        field.setCustomValidity(field.dataset.validationRequired);
        customReportValidatity(field, 'required');
        isValid = false;
      } else if (field.validity.typeMismatch) {
        //using typeMismatch instead of patternMismatch because the regex is not working for emails
        field.setCustomValidity(field.dataset.validationFormat);
        customReportValidatity(field, 'format');
        isValid = false;
      }

      contactUsForm.checkValidity();


      /// Recheck on field value change ///
      field.addEventListener('change', function() {
        $('.ttText').removeClass('active');

        ///without jquery
        /*document.querySelectorAll('.ttText').forEach((tt)=>{
          tt.classList.remove('active');
        });*/

        Validate();
      });

    });
    return isValid;
  }

  submitBtn.addEventListener('click', function(e) {
    e.preventDefault();
    e.stopPropagation();

    if (Validate()) {
      // contactUsForm.submit();
      //you can use this output to check if the form will submit
      console.log("Form Submitted!");
    } else {
      return false;
    }

  });

}
代码语言:javascript
复制
.ttCont {
  position: relative;
  display: inline-block;
}

.ttCont .ttText {
  display: inline-block;
  visibility: hidden;
  min-width: 200px;
  background-color: darkblue;
  color: #fff;
  text-align: center;
  border-radius: 6px;
  padding: 5px;
  opacity: 0;
  transition: opacity 0.5s;
  position: absolute;
  z-index: 1;
  top: 5px;
  left: 105%;
}

.ttCont .ttText::after {
  content: " ";
  position: absolute;
  top: 50%;
  right: 100%;
  margin-top: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent darkblue transparent transparent;
}

.ttCont .ttText.active {
  visibility: visible;
  opacity: 1;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<form id="Form">
  <div class="ttCont">
    <label for="name">Name</label><br/>
    <input type="text" name="name" required data-validation-required="Name is required!" /><br/>
    <span class="ttText"></span>
  </div>
  <br/><br/>

  <div class="ttCont">
    <label for="email">Email</label><br/>
    <input type="email" name="email" required data-validation-required="Email is required" data-validation-format="Email must have the format similar to example@email.com!" /><br/>
    <span class="ttText"></span>
  </div>
  <br/><br/>

  <div class="ttCont">
    <label for="desc">Description</label><br/>
    <input type="text" name="desc" data-validation-required="Description is required!" /><br/>
    <span class="ttText"></span>
  </div>
  <br/><br/>

  <button type="button" id="submitBtn">Submit</button>
</form>

您可以在这里阅读更多有关如何创建和处理自定义工具提示的内容:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71657677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档