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

使用jquery-repeater渲染PHP SQL结果实现嵌套增删表单的问题

嵌套编码分组增删实现方案

不需要强制适配jquery-repeater,直接用Twig渲染基础结构+原生/jQuery事件委托的方式实现,完全规避插件嵌套配置的结构错误问题,逻辑可控改造成本低。


第一步:后端数据预处理

SQL查询出结果后先整理成分组结构,忽略不需要处理的productcode字段,直接按id升序排序后传给Twig,结构参考:

// 处理后传入模板的数组示例
$codeGroups = [
    [
        'id' => 203,
        'main' => ['code' => '对应主编码值', 'type' => 'Main'],
        'subs' => [
            ['code' => '子编码1值', 'type' => 'Sub'],
            ['code' => '子编码2值', 'type' => 'Sub']
        ]
    ],
    [
        'id' => 204,
        'main' => ['code' => '对应主编码值', 'type' => 'Main'],
        'subs' => [
            ['code' => '子编码A值', 'type' => 'Sub']
        ]
    ]
];

第二步:Twig模板结构编写

直接按两层容器嵌套写结构,不要套错层级:

{# 最外层:所有主分组容器 #}
<div class="main-group-container">
    {% for group in codeGroups %}
    <div class="main-group-block" data-group-id="{{ group.id }}">
        {# 主编码行 #}
        <div class="main-code-row">
            <input type="text" class="main-code-input" name="groups[{{ group.id }}][main][code]" value="{{ group.main.code }}">
            <button type="button" class="btn-delete-main">删除主编码</button>
        </div>
        {# 子编码容器 #}
        <div class="sub-group-container" data-group-id="{{ group.id }}">
            {% for sub in group.subs %}
            <div class="sub-code-row">
                <input type="text" class="sub-code-input" name="groups[{{ group.id }}][subs][{{ loop.index }}][code]" value="{{ sub.code }}">
                <button type="button" class="btn-delete-sub">删除子项</button>
            </div>
            {% endfor %}
        </div>
        <button type="button" class="btn-add-sub">Add Sub Repeater</button>
    </div>
    {% endfor %}
</div>
<button type="button" id="btn-add-main">Add MAIN REPEATER</button>

第三步:交互逻辑实现

用事件委托方式绑定所有操作,支持动态新增元素的事件响应,jQuery示例如下,原生JS逻辑一致:

$(function () {
    // 删除主编码:连带移除整个分组(含所有子项)
    $(document).on('click', '.btn-delete-main', function () {
        $(this).closest('.main-group-block').remove();
    });

    // 删除单个子编码:仅移除当前子项
    $(document).on('click', '.btn-delete-sub', function () {
        $(this).closest('.sub-code-row').remove();
    });

    // 为当前分组新增子编码输入框
    $(document).on('click', '.btn-add-sub', function () {
        const $currentGroup = $(this).closest('.main-group-block');
        const groupId = $currentGroup.data('group-id');
        const tempIndex = Date.now(); // 用时间戳生成临时索引避免name冲突
        const subTpl = `
            <div class="sub-code-row">
                <input type="text" class="sub-code-input" name="groups[${groupId}][subs][${tempIndex}][code]" value="">
                <button type="button" class="btn-delete-sub">删除子项</button>
            </div>
        `;
        $currentGroup.find('.sub-group-container').append(subTpl);
    });

    // 新增完整主+子编码分组
    $('#btn-add-main').on('click', function () {
        const newGroupId = 'new_' + Date.now(); // 新增分组用临时id,提交后后端做持久化
        const newSubIndex = Date.now() + 1;
        const mainTpl = `
            <div class="main-group-block" data-group-id="${newGroupId}">
                <div class="main-code-row">
                    <input type="text" class="main-code-input" name="groups[${newGroupId}][main][code]" value="">
                    <button type="button" class="btn-delete-main">删除主编码</button>
                </div>
                <div class="sub-group-container" data-group-id="${newGroupId}">
                    <div class="sub-code-row">
                        <input type="text" class="sub-code-input" name="groups[${newGroupId}][subs][${newSubIndex}][code]" value="">
                        <button type="button" class="btn-delete-sub">删除子项</button>
                    </div>
                </div>
                <button type="button" class="btn-add-sub">Add Sub Repeater</button>
            </div>
        `;
        $('.main-group-container').append(mainTpl);
    });
})

关键适配说明

  • 渲染顺序:后端预处理数据时直接按id升序排列数组,Twig循环默认按数组顺序输出,自然满足先渲染id=203、再渲染id=204的要求
  • 逻辑隔离:主、子项的删除操作通过closest()方法向上查找对应层级的容器做移除,不会出现误删其他分组内容的问题
  • 事件兼容:所有动态生成的按钮都通过委托方式绑定事件,不会出现新增元素点击无响应的问题
  • 字段兼容:新增数据用时间戳生成临时标识,不会和已有数据的name属性冲突,后端提交时可直接通过id判断是更新还是新增
  • 冗余字段处理:模板中完全不输出productcode相关表单项,不需要额外做字段过滤,不影响原有逻辑

该方案不需要依赖第三方重复器插件,所有结构和逻辑完全可控,不会出现jquery-repeater常见的嵌套层级匹配、动态新增字段name错乱的问题,后续调整样式或新增交互不需要翻阅插件文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:27:42