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

JavaScript切换商品分类时显示/隐藏serial_no字段不生效求助

商品分类切换字段显示异常修复

现有环境信息

  • 商品分类表stores_item_category,用于存储商品分类数据,表结构与初始数据如下:
+----+--------------+--------+
| id |   category   | status |
+----+--------------+--------+
|  1 | Electronic   |      1 |
|  2 | Electric     |      1 |
|  3 | Furniture    |      1 |
|  4 | Vehicle      |      1 |
|  5 | Fixed Assets |      1 |
+----+--------------+--------+
  • 控制器接口(基于CodeIgniter框架):
public function addInventoryItems()
{
    $category =  $this->input->post('category');
    $data =  $this->Item_model->getInventoryProductsByCategory($category);
    echo $data;
}
  • 原有JS切换逻辑(位于stock_update视图文件):
if(category == 1 || category == 2) {
    $('#serial_no').next(".select2-container").show();
    $("#qty").hide();
    $('table th').eq(4).text( 'Serial No' );
    $('table td').eq(4).css("width", "50%")
} else {
    $('#serial_no').next(".select2-container").hide();
    $('table th').eq(4).text( 'Quantity' );
    
    $('#serial_no').val(null).trigger('change');
    $("#qty").prop('type', 'number');
    $("#qty").show();
    $('table td').eq(4).css("width", "10%")
}
  • 对应表单字段HTML结构:
<td  id="headerQty">
    <select name="serial_no0[]" id="serial_no" class="serial_no form-control select2" multiple="multiple" style="width: 100%"></select>
    <input type="hidden" step="any" name="qty0" id="qty" placeholder="Quantity" class="form-control" style="width: 100%"/>
</td>
  • 预期需求:选中分类为Electronic(id=1)或Electric(id=2)时显示serial_no序列号多选框,选中其他分类时隐藏序列号框、显示数量输入框。

问题根因

  1. 元素查找逻辑不可靠:代码用$('#serial_no').next(".select2-container")查找select2渲染的容器,强依赖DOM插入顺序。如果select2初始化时机晚于逻辑执行、或DOM结构有微小变动,就会找不到目标元素,显示/隐藏操作完全不生效。
  2. 触发时机缺失:现有判断逻辑没有绑定到分类下拉框的change事件上,页面加载完只执行一次,用户后续切换分类时不会重新运行逻辑,自然不会切换字段状态。
  3. 初始状态不匹配:#qty输入框初始type设为hidden,序列号select2默认显示,页面首次加载时没有根据分类默认值渲染对应状态,打开页面就会显示错误。
  4. 冗余属性修改:代码中动态修改#qty的type属性,不同浏览器对input type的动态修改兼容性不一致,容易引发异常。

修复方案

1. 调整HTML初始结构

把#qty输入框的初始type改为number,默认设置为隐藏,去掉hidden类型,避免动态修改type的兼容性问题:

<td  id="headerQty">
    <select name="serial_no0[]" id="serial_no" class="serial_no form-control select2" multiple="multiple" style="width: 100%"></select>
    <input type="number" step="any" name="qty0" id="qty" placeholder="Quantity" class="form-control" style="width: 100%; display: none;"/>
</td>

2. 重写JS切换逻辑

  • 用事件委托绑定分类下拉框的change事件,避免元素未渲染导致的绑定失效
  • 用select2官方推荐的实例属性获取渲染容器,不依赖DOM顺序
  • 页面初始化时自动触发一次change事件,保证首次加载状态正确
  • 切换时清空隐藏字段的值,避免提交冗余参数
// 注意将#category替换为你页面中实际的分类下拉框ID
$(document).on('change', '#category', function() {
    // 统一转数字类型,避免字符串/数字类型不匹配导致判断失效
    const category = parseInt($(this).val());
    const $serialSelect = $('#serial_no');
    // 优先通过select2实例获取容器,兼容不同初始化时机
    const $serialContainer = $serialSelect.data('select2') 
        ? $serialSelect.data('select2').$container 
        : $serialSelect.next('.select2-container');
    const $qtyInput = $('#qty');
    const $targetTh = $('table th').eq(4);
    const $targetTd = $('table td').eq(4);

    if (category === 1 || category === 2) {
        $serialContainer.show();
        $qtyInput.hide().val(''); // 隐藏时清空数量值
        $targetTh.text('Serial No');
        $targetTd.css("width", "50%");
    } else {
        $serialContainer.hide();
        $serialSelect.val(null).trigger('change'); // 清空已选序列号
        $qtyInput.show();
        $targetTh.text('Quantity');
        $targetTd.css("width", "10%");
    }
// 初始化时自动执行一次,渲染默认状态
}).trigger('change');

注意事项

  • 代码中#category需要替换为你页面实际使用的分类下拉选择框的ID,确保能正确获取选中的分类ID值。
  • 若页面存在动态新增行的场景,只需把ID选择器改为对应class选择器即可复用逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 05:36:34