You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bootstrap注册表单验证:如何标记重复用户名输入为无效?

解决Bootstrap表单中重复用户名选项的无效状态标记问题

问题说明

使用Bootstrap验证注册表单时,要求用户输入3个不重复的用户名选项,目前已能阻止表单提交,但重复的输入字段仍显示为有效状态,无法让用户直观知晓错误。

解决方案

Bootstrap表单验证默认仅处理HTML5内置规则(如required),自定义的重复校验需手动控制字段有效性状态,具体修改如下:

1. 优化HTML(可选:细化错误提示)

拆分错误提示,让用户明确区分“未填写”和“重复”两类错误:

<form class="needs-validation" novalidate>
  <h6 class="d-inline-block pt-3">请输入3个登录用户名选项:</h6>
  <div class="col-md-12 mb-3">
    <label for="sys_user_first" class="form-label">
      第一选项 
      <i class="fa-solid fa-star-of-life required-field fa-xs"></i>
    </label>
    <input type="text" class="form-control" id="sys_user_first" required>
    <div class="invalid-feedback required-feedback">
      请填写第一选项
    </div>
    <div class="invalid-feedback duplicate-feedback d-none">
      该用户名与其他选项重复
    </div>

    <label for="sys_user_second" class="form-label">
      第二选项 
      <i class="fa-solid fa-star-of-life required-field fa-xs"></i>
    </label>
    <input type="text" class="form-control" id="sys_user_second" required>
    <div class="invalid-feedback required-feedback">
      请填写第二选项
    </div>
    <div class="invalid-feedback duplicate-feedback d-none">
      该用户名与其他选项重复
    </div>

    <label for="sys_user_third" class="form-label">
      第三选项 
      <i class="fa-solid fa-star-of-life required-field fa-xs"></i>
    </label>
    <input type="text" class="form-control" id="sys_user_third" required>
    <div class="invalid-feedback required-feedback">
      请填写第三选项
    </div>
    <div class="invalid-feedback duplicate-feedback d-none">
      该用户名与其他选项重复
    </div>
  </div>
</form>

2. 修改JavaScript逻辑

手动控制字段验证状态,标记重复字段为无效并切换对应提示:

const form = document.querySelector('.needs-validation');
const firstInput = document.getElementById('sys_user_first');
const secondInput = document.getElementById('sys_user_second');
const thirdInput = document.getElementById('sys_user_third');

form.addEventListener('submit', function (event) {
  // 重置所有字段的验证状态和错误提示
  resetFieldValidation(firstInput);
  resetFieldValidation(secondInput);
  resetFieldValidation(thirdInput);

  let isValid = form.checkValidity();
  const values = [firstInput.value.trim(), secondInput.value.trim(), thirdInput.value.trim()];

  // 检查重复值并标记无效
  if (values[0] === values[1] && values[0] !== '') {
    markFieldAsInvalid(firstInput, 'duplicate');
    markFieldAsInvalid(secondInput, 'duplicate');
    isValid = false;
  }
  if (values[0] === values[2] && values[0] !== '') {
    markFieldAsInvalid(firstInput, 'duplicate');
    markFieldAsInvalid(thirdInput, 'duplicate');
    isValid = false;
  }
  if (values[1] === values[2] && values[1] !== '') {
    markFieldAsInvalid(secondInput, 'duplicate');
    markFieldAsInvalid(thirdInput, 'duplicate');
    isValid = false;
  }

  if (!isValid) {
    event.preventDefault();
    event.stopPropagation();
  }

  form.classList.add('was-validated');
}, false);

// 重置字段验证状态
function resetFieldValidation(field) {
  field.setCustomValidity('');
  field.classList.remove('is-invalid');
  field.classList.add('is-valid');
  field.nextElementSibling.classList.remove('d-none');
  const duplicateFeedback = field.parentElement.querySelector('.duplicate-feedback');
  if (duplicateFeedback) duplicateFeedback.classList.add('d-none');
}

// 标记字段为无效
function markFieldAsInvalid(field, errorType) {
  field.setCustomValidity('invalid');
  field.classList.remove('is-valid');
  field.classList.add('is-invalid');
  // 切换对应错误提示
  if (errorType === 'duplicate') {
    field.nextElementSibling.classList.add('d-none');
    const duplicateFeedback = field.parentElement.querySelector('.duplicate-feedback');
    if (duplicateFeedback) duplicateFeedback.classList.remove('d-none');
  }
}

关键说明

  • 用setCustomValidity()手动控制字段有效性:传入非空字符串时,字段会被标记为无效。
  • 通过切换is-invalid/is-valid类触发Bootstrap的样式反馈。
  • 每次提交前重置验证状态,避免旧结果残留。
  • 拆分错误提示后,用户能精准识别错误类型。

内容的提问来源于stack exchange,提问作者Leonard Kawhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:05:23