Django表单集动态行中,根据输入值互斥禁用输入框的实现
Django Inline-Formset 食材输入互斥禁用解决方案
一、具体实现代码
针对动态生成的formset行,必须用事件委托绑定事件,同时精准定位同一行的对应控件,以下是完整的jQuery代码:
$(document).ready(function() { // 监听rum下拉框变化,控制item输入框 $('#item-ingredients').on('change', '.rhum', function() { const $currentRow = $(this).closest('tr'); const $itemInput = $currentRow.find('.items'); // 选中rum则禁用item,否则启用 $itemInput.prop('disabled', $(this).val() !== ''); // 可选:禁用时清空item输入值,避免数据冲突 if ($(this).val() !== '') { $itemInput.val(''); } }); // 监听item输入框变化,控制rum下拉框 $('#item-ingredients').on('input', '.items', function() { const $currentRow = $(this).closest('tr'); const $rumSelect = $currentRow.find('.rhum'); // 输入item则禁用rum,否则启用 $rumSelect.prop('disabled', $(this).val().trim() !== ''); // 可选:禁用时重置rum选中状态 if ($(this).val().trim() !== '') { $rumSelect.val(''); } }); // 页面加载时初始化已有行的状态 $('#item-ingredients tr').each(function() { const $rum = $(this).find('.rhum'); const $item = $(this).find('.items'); $item.prop('disabled', $rum.val() !== ''); $rum.prop('disabled', $item.val().trim() !== ''); }); });
代码说明:
- 事件委托:绑定事件到父容器
#item-ingredients,不管是页面初始的行还是动态新增的行,事件都能触发。 - 精准定位:用
closest('tr')锁定当前操作的行,再用find()找到该行内的对应控件,避免影响其他行的输入框。 - 初始化状态:页面加载时用
each遍历所有行,确保编辑页面中已有数据的行能正确显示禁用状态。
二、你之前each循环失效的常见原因
- 只给页面初始的静态行绑定了事件,动态新增的行没有绑定到事件,导致新增行不生效。
- 没有限定行范围,循环时操作了所有行的控件,而非当前行的对应元素。
三、提升jQuery循环与DOM操作能力的建议
- 吃透DOM遍历方法:重点掌握
closest()、find()、siblings()这些方法,它们是精准定位元素的核心,比全局循环高效得多。 - 区分静态绑定与事件委托:只要涉及动态生成的DOM元素,必须用事件委托,这是处理动态表单的关键。
- 做小案例练手:比如写一个动态添加的todo列表,每行有互斥的输入项,反复练习遍历和联动逻辑,加深理解。
- 读官方文档:直接看jQuery官方的Traversing(遍历)和Events(事件)章节,官方例子都是最规范的用法。
- 调试优先:循环时用
console.log($(this))打印当前元素,确认是不是你要操作的对象,快速排查问题。
内容的提问来源于stack exchange,提问作者Thomas Doll-Datema
相关产品推荐
相关产品推荐

