Django中JavaScript创建的隐藏字段提交时value为undefined问题
问题根因
- 事件绑定范围错误
你使用document.querySelectorAll('[data-price]')绑定点击事件时,提交按钮本身也带有data-price属性,会被一同选中绑定事件。点击提交按钮时会触发对应回调,而提交按钮没有data-optionid属性,传入update_option的option_id为undefined,直接覆盖了之前选项点击时设置的正确值,这是提交时拿到undefined的核心原因,同时也是你感觉到事件触发两次的原因。 - 隐藏字段初始化逻辑错误
如果初始HTML没有硬编码option_id隐藏字段,DOMContentLoaded阶段执行option_element = document.getElementsByName('option_id')[0]会拿到null,后续直接给option_element.value赋值会失效。
解决步骤
第一步:修正事件绑定范围
给你的可选选项元素添加统一类名(比如hamper-option),修改选择器仅选中真正的选项元素,排除提交按钮:
// 修改前 // let options = document.querySelectorAll('[data-price]') // 修改后 let options = document.querySelectorAll('.hamper-option[data-price]')
如果不想加类名,也可以直接排除提交按钮:
let options = document.querySelectorAll('[data-price]:not(#price_button)')
第二步:修正隐藏字段逻辑
方案1(更简单):直接在初始HTML中硬编码空值的隐藏字段,不需要动态创建:
<form action="{% url 'add_hamper' hamper_id=hamper.slug %}" method="post" novalidate id="form"> {% csrf_token %} <input type="hidden" name="option_id" id="option_element" value=""> <button type="submit" class="btn btn-sm btn-success" id="price_button" data-price="{{ hamper.sale_price }}">{{ hamper.sale_price }}</button> </form>
方案2(动态创建):修改update_option中的隐藏字段处理逻辑,不存在时先创建再赋值:
function update_option(price, option_id) { let add_to_price = parseFloat(price.substring(2)); let button_price = parseFloat(base_hamper_price.substring(2)); let new_total = add_to_price + button_price; price_button.innerText = "A$" + new_total.toFixed(2); const form = document.getElementById('form'); let option_element = document.getElementById('option_element'); // 隐藏字段不存在则先创建 if (!option_element) { option_element = document.createElement("input"); option_element.setAttribute("type", "hidden"); option_element.setAttribute("name", "option_id"); option_element.setAttribute("id", "option_element"); form.prepend(option_element); } option_element.value = option_id; }
第三步:检查data属性命名
确认你的选项元素上的自定义属性命名和取值匹配:如果属性写的是data-option-id,则取值要改成e.currentTarget.dataset.optionId(dataset会自动把连字符格式转换为驼峰格式),如果属性写的是data-optionid,则保持e.currentTarget.dataset.optionid即可。
内容的提问来源于stack exchange,提问作者Darren
相关产品推荐
相关产品推荐

