首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何关注必填或无效字段?

如何关注必填或无效字段?
EN

Stack Overflow用户
提问于 2019-08-28 21:45:16
回答 2查看 746关注 0票数 0

我的表单很长,在某些情况下,用户可能会错过一些必需的字段。如果他们一直滚动到Save按钮,然后单击发送表单数据,他们就不会看到错误消息。我想知道是否有一种方法可以触发on focus方法,将用户带到表单中的第一个字段,即requiredinvalid。下面是我的表单示例:

代码语言:javascript
复制
var COMMON_FUNC = {};
$("#save").on("click", function() {
  var frmObject = $(this).closest("form"),
    frmDisabledFlds = frmObject.find(":input:disabled").prop("disabled", false),
    frmData = frmObject.serialize();
  frmDisabledFlds.prop("disabled", true);

  if (COMMON_FUNC.verifyFields("new-record")) {
    console.log('Send Form Data!');
  }
});

COMMON_FUNC.verifyFields = function(containerID, includeInvisible) {
  includeInvisible = includeInvisible || false;
  let isValid = true;
  const hdlMap = {
    'valueMissing': "This field is required",
    'patternMismatch': "This field is invalid",
    'tooLong': "This field is too long",
    'rangeOverflow': "This field is greater than allowed maximum",
    'rangeUnderflow': "This field is less than allowed minimum",
    'typeMismatch': "This field is mistyped"
  };

  const arrV = Object.keys(hdlMap);

  $("#" + containerID).find("input,textarea,select").each(function() {
    var curItem$ = $(this);
    var errMsg = [];
    var dispfld = curItem$.data("dispfld");

    if (includeInvisible || curItem$.is(":visible")) {
      if (curItem$[0].validity.valid) {
        curItem$.removeClass("is-invalid");
        return;
      }

      arrV.forEach(function(prop) {
        if (curItem$[0].validity[prop]) {
          if (prop === "patternMismatch" && dispfld) {
            errMsg.push(dispfld);
          } else {
            errMsg.push(hdlMap[prop]);
          }
        }
      });

      if (errMsg.length) {
        if (!curItem$.next().is(".invalid-feedback")) {
          curItem$.after('<div class="invalid-feedback"></div>');
        }
        curItem$.addClass("is-invalid").next().text(errMsg.join(' and '));
        isValid = false;
      } else {
        curItem$.removeClass("is-invalid");
      }
    }
  });

  return isValid;
};
代码语言:javascript
复制
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="container">
  <div class="card">
    <div class="card-header">
      <h4>New Record</h4>
    </div>
    <div class="card-body">
      <form name="new-record" id="new-record" autocomplete="off">
        <div class="form-group">
          <label for="bldg_name">Building Name:</label>
          <input class="form-control" type="text" name="bldg_name" id="bldg_name" value="" maxlength="500" placeholder="Enter the building name" required>
        </div>

        <div class="row">
          <div class="col-12"><strong><u>Manager</u></strong></div>
        </div>

        <div class="form-row">
          <div class="form-group col-6">
            <label for="salutation">Salutation:</label>
            <select class="custom-select browser-default" name="salutation" id="salutation">
              <option value="">--Select Salutation--</option>
              <option value="1">Mrs</option>
              <option value="2">Ms</option>
              <option value="3">Miss</option>
              <option value="4">Mr</option>
            </select>
          </div>
          <div class="form-group col-6">
            <label for="title">Business Title:</label>
            <select class="custom-select browser-default" name="title" id="title">
              <option value="">--Select Title--</option>
              <option value="1">Region Manager</option>
              <option value="2">State Manager</option>
              <option value="3">Building Manager</option>
            </select>
          </div>
        </div>
        <div class="form-row">
          <div class="form-group col-6 required">
            <label for="fname">First Name:</label>
            <input class="form-control" type="text" name="fname" id="fname" value="" maxlength="20" placeholder="Enter First name" required>
          </div>

          <div class="form-group col-6 required">
            <label for="lname">Last Name:</label>
            <input class="form-control" type="text" name="lname" id="lname" value="" maxlength="30" placeholder="Enter Last name" required>
          </div>
        </div>
        <div class="form-group required">
          <label for="email">Email:</label>
          <input class="form-control email" type="email" name="email" id="email" maxlength="50" placeholder="Enter Email address" required>
        </div>
        <div class="form-group row">
          <div class="col-5 offset-2"><strong><u>Physical Address</u></strong></div>
          <div class="col-5"><strong><u>Mailing Address</u></strong></div>
        </div>
        <div class="form-group row required">
          <label for="address1" class="col-2 col-form-label">Address 1:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address1" id="p_address1" value="" placeholder="Enter Physical Address 1" maxlength="40" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address1" id="m_address1" value="" placeholder="Enter Mailing Address 1" maxlength="40" required>
          </div>
        </div>
        <div class="form-group row">
          <label for="address2" class="col-2 col-form-label">Address 2:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address2" id="p_address2" value="" placeholder="Enter Physical Address 2" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address2" id="m_address2" value="" placeholder="Enter Mailing Address 2" maxlength="40">
          </div>
        </div>
        <div class="form-group row">
          <label for="address3" class="col-2 col-form-label">Address 3:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address3" id="p_address3" value="" placeholder="Enter Physical Address 3" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address3" id="m_address3" value="" placeholder="Enter Mailing Address 3" maxlength="40">
          </div>
        </div>
        <div class="form-group row">
          <label for="address4" class="col-2 col-form-label">Address 4:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address4" id="p_address4" value="" placeholder="Enter Physical Address 4" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address4" id="m_address4" value="" placeholder="Enter Mailing Address 4" maxlength="40">
          </div>
        </div>
        <div class="form-group row required">
          <label for="city" class="col-2 col-form-label">City:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_city" id="p_city" value="" placeholder="Enter City" maxlength="25" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_city" id="m_city" value="" placeholder="Enter City" maxlength="25" required>
          </div>
        </div>
        <div class="form-group row required">
          <label for="state" class="col-2 col-form-label">State:</label>
          <div class="col-5">
            <select class="custom-select browser-default physical" name="p_state" id="p_state" required>
              <option value="">--Select State--</option>
              <option value="az">Arizona</option>
              <option value="ia">Iowa</option>
              <option value="mo">Missouri</option>
              <option value="ny">New York</option>
              <option value="va">Virginia</option>
            </select>
          </div>
          <div class="col-5">
            <select class="custom-select browser-default mailing" name="m_state" id="m_state" required>
              <option value="">--Select State--</option>
              <option value="az">Arizona</option>
              <option value="ia">Iowa</option>
              <option value="mo">Missouri</option>
              <option value="ny">New York</option>
              <option value="va">Virginia</option>
            </select>
          </div>
        </div>
        <div class="form-group row required">
          <label for="zip" class="col-2 col-form-label">Zip:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_zip" id="p_zip" value="" pattern="(\d{5}([\-]\d{4})?)" data-dispfld="The required format is: xxxxx or xxxxx-xxxx" placeholder="Enter Zip Code, formatted: 99999 or 99999-9999" maxlength="10" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_zip" id="m_zip" value="" pattern="(\d{5}([\-]\d{4})?)" data-dispfld="The required format is: xxxxx or xxxxx-xxxx" placeholder="Enter Zip Code, formatted: 99999 or 99999-9999" maxlength="10" required>
          </div>
        </div>

        <div class="row">
          <div class="col-12 text-center">
            <button class="btn btn-outline-secondary" type="button" name="save" id="save">Save</button>
            <button class="btn btn-outline-secondary" type="button" name="cancel" id="cancel">Cancel</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>

您可以运行此示例并在表单中输入除Building Name之外的所有信息。然后您可以单击保存按钮,您将无法在顶部看到错误消息。如果任何人有建议如何处理这个问题,请让我知道。对于这种情况,我愿意听到不同的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-28 21:57:09

DOM在元素上有一个“焦点”函数,这些元素可以做您想要做的事情。

将所有有效元素推送到invalidInputs数组中,然后可以选择第一个无效的元素,并对该元素调用.focus()。

代码语言:javascript
复制
var COMMON_FUNC = {};
$("#save").on("click", function() {
  var frmObject = $(this).closest("form"),
    frmDisabledFlds = frmObject.find(":input:disabled").prop("disabled", false),
    frmData = frmObject.serialize();
  frmDisabledFlds.prop("disabled", true);

  if (COMMON_FUNC.verifyFields("new-record")) {
    console.log('Send Form Data!');
  }
});

COMMON_FUNC.verifyFields = function(containerID, includeInvisible) {
  includeInvisible = includeInvisible || false;
  let isValid = true;
  const hdlMap = {
    'valueMissing': "This field is required",
    'patternMismatch': "This field is invalid",
    'tooLong': "This field is too long",
    'rangeOverflow': "This field is greater than allowed maximum",
    'rangeUnderflow': "This field is less than allowed minimum",
    'typeMismatch': "This field is mistyped"
  };

  const arrV = Object.keys(hdlMap);

  // Create an array for the invalid fields.
  const invalidInputs = [];

  $("#" + containerID).find("input,textarea,select").each(function() {
    var curItem$ = $(this);
    var errMsg = [];
    var dispfld = curItem$.data("dispfld");

    if (includeInvisible || curItem$.is(":visible")) {
      if (curItem$[0].validity.valid) {
        curItem$.removeClass("is-invalid");
        return;
      }

      arrV.forEach(function(prop) {
        if (curItem$[0].validity[prop]) {
          if (prop === "patternMismatch" && dispfld) {
            errMsg.push(dispfld);
          } else {
            errMsg.push(hdlMap[prop]);
          }
        }
      });

      if (errMsg.length) {
        if (!curItem$.next().is(".invalid-feedback")) {
          curItem$.after('<div class="invalid-feedback"></div>');
        }
        curItem$.addClass("is-invalid").next().text(errMsg.join(' and '));
        isValid = false;
        
        //Push the invalid inputs onto the invalidInputs array.
        invalidInputs.push(curItem$);
      } else {
        curItem$.removeClass("is-invalid");
      }
    }
  });
 
  // Focus on the first element that is invalid.
  invalidInputs[0].focus();

  return isValid;
};
代码语言:javascript
复制
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<div class="container">
  <div class="card">
    <div class="card-header">
      <h4>New Record</h4>
    </div>
    <div class="card-body">
      <form name="new-record" id="new-record" autocomplete="off">
        <div class="form-group">
          <label for="bldg_name">Building Name:</label>
          <input class="form-control" type="text" name="bldg_name" id="bldg_name" value="" maxlength="500" placeholder="Enter the building name" required>
        </div>

        <div class="row">
          <div class="col-12"><strong><u>Manager</u></strong></div>
        </div>

        <div class="form-row">
          <div class="form-group col-6">
            <label for="salutation">Salutation:</label>
            <select class="custom-select browser-default" name="salutation" id="salutation">
              <option value="">--Select Salutation--</option>
              <option value="1">Mrs</option>
              <option value="2">Ms</option>
              <option value="3">Miss</option>
              <option value="4">Mr</option>
            </select>
          </div>
          <div class="form-group col-6">
            <label for="title">Business Title:</label>
            <select class="custom-select browser-default" name="title" id="title">
              <option value="">--Select Title--</option>
              <option value="1">Region Manager</option>
              <option value="2">State Manager</option>
              <option value="3">Building Manager</option>
            </select>
          </div>
        </div>
        <div class="form-row">
          <div class="form-group col-6 required">
            <label for="fname">First Name:</label>
            <input class="form-control" type="text" name="fname" id="fname" value="" maxlength="20" placeholder="Enter First name" required>
          </div>

          <div class="form-group col-6 required">
            <label for="lname">Last Name:</label>
            <input class="form-control" type="text" name="lname" id="lname" value="" maxlength="30" placeholder="Enter Last name" required>
          </div>
        </div>
        <div class="form-group required">
          <label for="email">Email:</label>
          <input class="form-control email" type="email" name="email" id="email" maxlength="50" placeholder="Enter Email address" required>
        </div>
        <div class="form-group row">
          <div class="col-5 offset-2"><strong><u>Physical Address</u></strong></div>
          <div class="col-5"><strong><u>Mailing Address</u></strong></div>
        </div>
        <div class="form-group row required">
          <label for="address1" class="col-2 col-form-label">Address 1:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address1" id="p_address1" value="" placeholder="Enter Physical Address 1" maxlength="40" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address1" id="m_address1" value="" placeholder="Enter Mailing Address 1" maxlength="40" required>
          </div>
        </div>
        <div class="form-group row">
          <label for="address2" class="col-2 col-form-label">Address 2:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address2" id="p_address2" value="" placeholder="Enter Physical Address 2" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address2" id="m_address2" value="" placeholder="Enter Mailing Address 2" maxlength="40">
          </div>
        </div>
        <div class="form-group row">
          <label for="address3" class="col-2 col-form-label">Address 3:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address3" id="p_address3" value="" placeholder="Enter Physical Address 3" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address3" id="m_address3" value="" placeholder="Enter Mailing Address 3" maxlength="40">
          </div>
        </div>
        <div class="form-group row">
          <label for="address4" class="col-2 col-form-label">Address 4:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_address4" id="p_address4" value="" placeholder="Enter Physical Address 4" maxlength="40">
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_address4" id="m_address4" value="" placeholder="Enter Mailing Address 4" maxlength="40">
          </div>
        </div>
        <div class="form-group row required">
          <label for="city" class="col-2 col-form-label">City:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_city" id="p_city" value="" placeholder="Enter City" maxlength="25" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_city" id="m_city" value="" placeholder="Enter City" maxlength="25" required>
          </div>
        </div>
        <div class="form-group row required">
          <label for="state" class="col-2 col-form-label">State:</label>
          <div class="col-5">
            <select class="custom-select browser-default physical" name="p_state" id="p_state" required>
              <option value="">--Select State--</option>
              <option value="az">Arizona</option>
              <option value="ia">Iowa</option>
              <option value="mo">Missouri</option>
              <option value="ny">New York</option>
              <option value="va">Virginia</option>
            </select>
          </div>
          <div class="col-5">
            <select class="custom-select browser-default mailing" name="m_state" id="m_state" required>
              <option value="">--Select State--</option>
              <option value="az">Arizona</option>
              <option value="ia">Iowa</option>
              <option value="mo">Missouri</option>
              <option value="ny">New York</option>
              <option value="va">Virginia</option>
            </select>
          </div>
        </div>
        <div class="form-group row required">
          <label for="zip" class="col-2 col-form-label">Zip:</label>
          <div class="col-5">
            <input class="form-control physical" type="text" name="p_zip" id="p_zip" value="" pattern="(\d{5}([\-]\d{4})?)" data-dispfld="The required format is: xxxxx or xxxxx-xxxx" placeholder="Enter Zip Code, formatted: 99999 or 99999-9999" maxlength="10" required>
          </div>
          <div class="col-5">
            <input class="form-control mailing" type="text" name="m_zip" id="m_zip" value="" pattern="(\d{5}([\-]\d{4})?)" data-dispfld="The required format is: xxxxx or xxxxx-xxxx" placeholder="Enter Zip Code, formatted: 99999 or 99999-9999" maxlength="10" required>
          </div>
        </div>

        <div class="row">
          <div class="col-12 text-center">
            <button class="btn btn-outline-secondary" type="button" name="save" id="save">Save</button>
            <button class="btn btn-outline-secondary" type="button" name="cancel" id="cancel">Cancel</button>
          </div>
        </div>
      </form>
    </div>
  </div>
</div>

票数 2
EN

Stack Overflow用户

发布于 2019-08-28 21:50:49

你可以尝试像这样简单的东西(未经测试,但应该可以工作):

代码语言:javascript
复制
document.getElementsByClassName('is-invalid')[0].scrollIntoView({ behavior: 'smooth' });

这将查找错误类is-invalid,然后平滑滚动到找到的第一个错误类

如果发现错误,请在验证之后添加此代码。

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

https://stackoverflow.com/questions/57693937

复制
相关文章

相似问题

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