Laravel Blade多步骤表单:仅勾选选项后显示下一步按钮
问题:Laravel Blade多步骤表单“下一步”按钮需勾选单选框才显示的功能失效
我基于多步骤表单方案在Laravel Blade视图中构建了考试表单,需求是只有勾选当前页面的单选框选项后,才显示“下一步”按钮,但目前该功能无法正常工作。以下是代码分析及修复方案:
原代码问题分析
validateForm函数中的核心验证逻辑被注释,无法判断单选框是否选中- 当前tab内存在一个
hidden类型的input(值为空),会干扰验证判断 - “下一步”按钮默认显示,未实现初始隐藏
- 缺少单选框选择事件监听,无法实时更新按钮状态
修复方案
1. 修改Blade表单代码(添加单选框监听类)
给所有单选框添加统一类名question-radio,方便绑定事件:
<form method="POST" action="{{ route('stagiaire.theorique.test.store_seul',['id'=>$eval->id]) }}" id="questionform" name="examForm"> @csrf <div style="text-align:center;margin-top:10px;"> <span class="step"></span> <span class="step"></span> <span class="step"></span> <span class="step"></span> </div> @foreach($questioncat as $key => $category) @foreach($category->getQuestion as $question) <fieldset class="theorique-body" id="categorie_{{ $key }}"> <div class="header-question" id="q{{ $question->id}}"> <h2 class="nomcat">{{ $category->nom }}</h2> <h3 class="question">{{ $question->question_text }}</h3> </div> <div class="body-question"> <div class="image"> <img src="{{ asset('storage/' . $question->image) }}" alt=""> </div> <div class="reponsebouton"> <input type="hidden" name="questions[{{ $question->id }}]" value=""> <p>Merci de choisir votre réponse</p> @foreach($question->reponse as $option) <div class="button-check"> <input class="form-check-input question-radio" type="radio" name="questions[{{ $question->id }}]" id="option-{{ $option->id }}" value="{{ $option->id }}"@if(old("questions.$question->id") == $option->id) checked @endif> <label class="form-check-label" for="option-{{ $option->id }}"> {{ $option->option_text }} </label> </div> @endforeach </div> </div> </fieldset> @if($errors->has("questions.$question->id")) <p class="font-bold">Attention :</p> <span style="margin-top: .25rem; font-size: 80%; color: #e3342f;" role="alert"> <strong>{{ $errors->first("questions.$question->id") }}</strong> </span> @endif @endforeach @endforeach <div style="overflow:auto;" id="butform"> <div style="float:right;"> <button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button> <button class="text-white bg-gradient-to-br from-purple-600 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 rounded-lg text-m px-5 py-4 font-bold uppercase text-center mr-2 mb-2" type="button" id="nextBtn" onclick="nextPrev(1)" style="display:none;">Suivant</button> </div> </div> </form>
2. 修改JavaScript代码(完善验证与监听逻辑)
var currentTab = 0; // 当前选中的标签页索引 showTab(currentTab); // 显示初始标签页 // 给所有单选框绑定选择事件监听 document.querySelectorAll('.question-radio').forEach(radio => { radio.addEventListener('change', updateNextButtonStatus); }); function showTab(n) { const tabs = document.getElementsByClassName("theorique-body"); // 隐藏所有标签页 for(let i = 0; i < tabs.length; i++){ tabs[i].style.display = "none"; } // 显示当前标签页 tabs[n].style.display = "block"; // 处理上一步按钮显示逻辑 document.getElementById("prevBtn").style.display = n === 0 ? "none" : "inline-block"; // 处理下一步按钮文本 document.getElementById("nextBtn").innerHTML = n === tabs.length - 1 ? "Terminer le test" : "Suivant"; // 更新下一步按钮状态 updateNextButtonStatus(); // 更新步骤指示器 fixStepIndicator(n); } function nextPrev(n) { const tabs = document.getElementsByClassName("theorique-body"); // 下一步时验证当前表单 if (n === 1 && !validateForm()) return false; tabs[currentTab].style.display = "none"; currentTab += n; // 到达表单末尾则提交 if (currentTab >= tabs.length) { document.getElementById("questionform").submit(); return false; } showTab(currentTab); } function validateForm() { const currentTabEl = document.getElementsByClassName("theorique-body")[currentTab]; // 仅获取当前tab内的单选框 const radios = currentTabEl.querySelectorAll('input[type="radio"]'); let valid = false; // 检查是否有单选框被选中 for(let i = 0; i < radios.length; i++){ if(radios[i].checked){ valid = true; break; } } // 标记步骤为已完成 if (valid) { document.getElementsByClassName("step")[currentTab].className += " finish"; } return valid; } // 更新下一步按钮显示状态 function updateNextButtonStatus(){ const nextBtn = document.getElementById("nextBtn"); nextBtn.style.display = validateForm() ? "inline-block" : "none"; } function fixStepIndicator(n) { const steps = document.getElementsByClassName("step"); for (let i = 0; i < steps.length; i++) { steps[i].className = steps[i].className.replace(" active", ""); } steps[n].className += " active"; }
关键修改说明
- 给单选框添加
question-radio类,统一监听选择事件 - 初始隐藏“下一步”按钮,通过
updateNextButtonStatus函数实时控制显示/隐藏 - 修复
validateForm函数,仅检查当前tab内的单选框是否被选中,排除hidden input干扰 - 优化
showTab函数,先隐藏所有标签页再显示当前页,避免显示混乱 - 提取
updateNextButtonStatus函数,专门处理按钮状态更新
内容的提问来源于stack exchange,提问作者Chrisdev
相关产品推荐
相关产品推荐

