移除Django模板中{{ choice.tag }}致单选按钮JS更新函数失效
解决方案
问题核心在于你之前重复渲染了单选按钮(手动编写的<input> + Django的{{ choice.tag }}生成的按钮),移除{{ choice.tag }}后,需要确保自定义单选按钮的属性正确,同时补上卡片点击的交互逻辑来实现“点击卡片选值”的需求,具体步骤如下:
1. 清理并修正HTML模板
移除{{ choice.tag }},并给选中状态的卡片添加高亮类(比如active),确保单选按钮的checked属性由Django正确渲染:
{% for choice in form.meals_per_week %} <div class="flex-fill mx-1"> <div class="card mb-4 custom-card {% if choice.is_checked %}active{% endif %}" data-input-id="{{ choice.id_for_label }}"> <div class="card-body text-center"> <input type="radio" class="hidden-input" id="{{ choice.id_for_label }}" name="{{ choice.name }}" value="{{ choice.choice_value }}" {% if choice.is_checked %}checked{% endif %}> <label class="form-check-label d-block" for="{{ choice.id_for_label }}"> {{ choice.choice_label }} </label> </div> </div> </div> {% endfor %}
2. 完善JavaScript逻辑
添加卡片点击的交互、高亮状态切换,同时给代码加上防错处理,避免找不到选中元素时抛出错误:
async function updateSummary() { // 防错处理:先确认选中的单选按钮存在 const selectedMealInput = document.querySelector('input[name="meals_per_week"]:checked'); if (!selectedMealInput) { console.warn('未选择每周餐数'); return; } const mealsPerWeek = parseInt(selectedMealInput.value); const mealPreferences = Array.from(document.querySelectorAll('input[name="meal_preference_type"]:checked')).map(el => el.value); let response = await fetch(`/get_price?meals_per_week=${mealsPerWeek}`); let data = await response.json(); const pricePerServing = data.price_per_serving.toFixed(2); const planPrice = (pricePerServing * mealsPerWeek).toFixed(2); document.getElementById('meal_preference_type').innerText = mealPreferences.join(', ') || '无偏好'; document.getElementById('meals_per_week').innerText = mealsPerWeek; document.getElementById('price_per_serving').innerText = pricePerServing; document.getElementById('plan_price').innerText = planPrice; } document.addEventListener('DOMContentLoaded', () => { // 页面加载时初始化摘要 updateSummary(); // 给餐数卡片添加点击交互 const mealCards = document.querySelectorAll('.custom-card'); mealCards.forEach(card => { card.addEventListener('click', () => { const inputId = card.getAttribute('data-input-id'); const targetInput = document.getElementById(inputId); // 切换单选按钮选中状态 targetInput.checked = true; // 切换卡片高亮样式 mealCards.forEach(c => c.classList.remove('active')); card.classList.add('active'); // 更新摘要 updateSummary(); }); }); // 给餐食偏好复选框添加实时更新逻辑 const preferenceCheckboxes = document.querySelectorAll('input[name="meal_preference_type"]'); preferenceCheckboxes.forEach(checkbox => { checkbox.addEventListener('change', updateSummary); }); });
3. 补充CSS高亮样式
给选中的卡片添加高亮效果,比如改变背景色:
.custom-card.active { border-color: #007bff; background-color: rgba(0,123,255,0.1); }
关键说明
- 移除
{{ choice.tag }}后,页面中只剩你手动编写的单选按钮,Django的choice.is_checked会正确给初始选中的按钮加上checked属性,确保页面加载时updateSummary能拿到初始值。 - 卡片点击事件通过
data-input-id关联到对应的单选按钮,实现“点击卡片选值”的交互,同时同步更新卡片高亮状态。 - 防错处理避免了因没有选中元素导致的JS报错,提升页面稳定性。
内容的提问来源于stack exchange,提问作者Itika Sharma
相关产品推荐
相关产品推荐

