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

如何为Choices.js组件添加is-invalid错误类?

问题描述

使用validate.js进行表单验证,通过choices.min.js替换原生<select>组件实现带搜索功能的下拉选择,但测试时发现错误消息无法正常显示,is-invalid错误类也无法正确添加到可视化元素上。已尝试查阅官方文档及AI工具解决,但未成功。

原始HTML代码

<div class="form-group mb-3">
<div class="choices" data-type="select-one" tabindex="0" role="listbox" aria-haspopup="true" aria-expanded="false">
<div class="choices__inner">
<select class="form-control choices__input" data-trigger="" name="choices_single_default" id="choices_single_default" hidden="" tabindex="-1" data-choice="active">
    <option value="" data-custom-properties="[object Object]">--</option>
</select>
  <div class="choices__list choices__list--single">
    <div class="choices__item choices__placeholder choices__item--selectable" data-item="" data-id="1" data-value="" data-custom-properties="[object Object]" aria-selected="true">--</div>
  </div>
</div>
<div class="choices__list choices__list--dropdown" aria-expanded="false">
  <div class="choices__list" role="listbox">
    <div id="choices--choices_single_default-item-choice-1" class="choices__item choices__item--choice is-selected choices__placeholder choices__item--selectable is-highlighted" role="option" data-choice="" data-id="1" data-value="" data-select-text="" data-choice-selectable="" aria-selected="true">--</div>
    <div id="choices--choices_single_default-item-choice-2" class="choices__item choices__item--choice choices__item--selectable" role="option" data-choice="" data-id="2" data-value="Choice 1" data-select-text="" data-choice-selectable="">Choice 1</div>
    <div id="choices--choices_single_default-item-choice-3" class="choices__item choices__item--choice choices__item--selectable" role="option" data-choice="" data-id="3" data-value="Choice 2" data-select-text="" data-choice-selectable="">Choice 2</div>
    <div id="choices--choices_single_default-item-choice-4" class="choices__item choices__item--choice choices__item--selectable" role="option" data-choice="" data-id="4" data-value="Choice 3" data-select-text="" data-choice-selectable="">Choice 3</div>
  </div>
</div>

原始JavaScript代码

$('#signin-form').validate({
rules: {
  email: {
    required: true,
    email: true
  },
  choices_single_default: {
    required: true,
  },
  password: {
    required: true
  }
},
messages: {
  email: {
    required: 'Please enter your email address',
    email: 'Please enter a valid email address'
  },
  choices_single_default: {
    required: 'Please enter your choice'
  },
  password: {
    required: 'Please enter your password'
  }
},
errorPlacement: function(error, element) {
  if (element.parent('.input-group').length) {
      error.insertAfter(element.parent());
  } else if (element.hasClass('choices__input')) {
      error.insertAfter(element.siblings('.choices__list--dropdown'));
  } else {
      error.insertAfter(element);
  }
},
highlight: function(element) {
    if ($(element).hasClass('choices__input')) {
        $(element).siblings('.choices__list--dropdown').addClass('is-invalid');
    } else {
        $(element).addClass('is-invalid');
    }
},
unhighlight: function(element) {
    if ($(element).hasClass('choices__input')) {
        $(element).siblings('.choices__list--dropdown').removeClass('is-invalid');
    } else {
        $(element).removeClass('is-invalid');
    }
},
submitHandler: function(form) {
  // ajax code

  return false;
}
});

解决方案

核心问题是validate.js默认操作的是被隐藏的原生<select>元素,而choices.js的可视化交互区域是上层的自定义DOM结构,需要调整验证逻辑中的元素定位:

修改后的JavaScript代码

$('#signin-form').validate({
  rules: {
    email: {
      required: true,
      email: true
    },
    choices_single_default: {
      required: true,
    },
    password: {
      required: true
    }
  },
  messages: {
    email: {
      required: '请输入您的邮箱地址',
      email: '请输入有效的邮箱地址'
    },
    choices_single_default: {
      required: '请选择您的选项'
    },
    password: {
      required: '请输入您的密码'
    }
  },
  errorPlacement: function(error, element) {
    if (element.parent('.input-group').length) {
      error.insertAfter(element.parent());
    } else if (element.hasClass('choices__input')) {
      // 定位到choices组件最外层容器,将错误消息放在组件后方
      error.insertAfter(element.closest('.choices'));
    } else {
      error.insertAfter(element);
    }
  },
  highlight: function(element) {
    const $element = $(element);
    if ($element.hasClass('choices__input')) {
      // 给choices可视化输入区域添加错误类
      $element.closest('.choices').find('.choices__inner').addClass('is-invalid');
    } else {
      $element.addClass('is-invalid');
    }
  },
  unhighlight: function(element) {
    const $element = $(element);
    if ($element.hasClass('choices__input')) {
      // 移除choices可视化输入区域的错误类
      $element.closest('.choices').find('.choices__inner').removeClass('is-invalid');
    } else {
      $element.removeClass('is-invalid');
    }
  },
  submitHandler: function(form) {
    // ajax代码
    return false;
  }
});

关键调整说明

  1. 错误消息位置:使用closest('.choices')定位到组件最外层容器,确保错误消息显示在用户可见的组件下方,而非隐藏元素附近
  2. 错误类绑定:将is-invalid类绑定到.choices__inner元素——这是用户实际交互的可视化区域,操作隐藏的原生select不会产生视觉反馈
  3. 值同步保障:确保choices.js初始化时已正确绑定原生select,这样用户选择的值会同步到原生元素,validate.js才能正确获取值进行验证

内容的提问来源于stack exchange,提问作者lawrence agulto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:12:49