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

Spring Boot+Thymeleaf中JS控制textarea必填属性失效问题排查

问题排查与解决方案

核心问题分析

你的代码存在4个关键问题,导致动态设置textarea必填属性的功能失效:

  1. 重复ID导致DOM元素获取错误
    由于Thymeleaf通过th:each循环生成多行提问,所有下拉框的默认选项和textarea都使用了相同的固定ID(noSelectOption2、commentAreaForQuestion2)。document.getElementById()只能返回第一个匹配的元素,后续行的元素完全无法被JS正确定位。

  2. 事件绑定错误
    下拉框选项变更的正确触发事件是onchange,你误用了onselect(该事件用于文本输入框的文本选中操作)。

  3. 逻辑判断颠倒
    需求是「选择非默认选项时textarea必填,选默认选项时移除必填」,但你的JS逻辑正好相反:当默认选项值为空时设置required=true,完全不符合需求。

  4. HTML标签语法错误
    select标签被写成了自闭合形式<select .../>,后续又添加了</select>,导致浏览器解析HTML结构异常。


修改后的代码实现

Thymeleaf模板代码

重点为循环生成的元素添加唯一ID,修正事件绑定和标签语法:

<div class="container-fluid bg-light">
    <div class="form-group table" th:if="${answeredQuestionnaire.answers.size()==0}">
        <table>
            <thead style="background-color: dimgrey; color: white">
                <tr class="d-flex">
                    <th scope="col" class="col-4 text-center">[[#{questionnaire.question}]]</th>
                    <th scope="col" class="col-4 text-center">[[#{questionnaire.answer}]]</th>
                    <th scope="col" class="col-4 text-center" >[[#{questionnaire.comment}]]<font color="red">*</font></th>
                </tr>
            </thead>
            <tbody th:field="*{questionnaire}">
                <tr th:each="question,iStat : ${answeredQuestionnaire.questionnaire.getQuestions()}"
                    class="d-flex">
                    <td class="col-4" th:inline="text">
                        <input type="hidden"  th:value="${question.id}"
                               th:field="*{questionnaire.questions[__${iStat.index}__].id}"
                               th:text="${question.questionNumber + 1}+') '+#{'question'+${question.questionNumber}}"/>
                    </td>
                    <td class="col-4 text-center">
                        <!-- 修正select标签闭合,使用onchange事件并传递当前元素和索引 -->
                        <select th:field="*{questionnaire.questions[__${iStat.index}__].possibleAnswers[0].id}"
                                class="form-control" 
                                onchange="toggleCommentRequired(this, [[${iStat.index}]])">
                            <!-- 生成唯一ID -->
                            <option value="" default th:id="'noSelectOption_' + ${iStat.index}" >[[#{pleaseSelect}]]</option>
                            <option th:each="possibleAnswer, paStat : ${question.getPossibleAnswers()}"
                                    th:value="${possibleAnswer.id}"
                                    th:text="#{'question'+${question.questionNumber}+'.pa'+${paStat.index}}">
                            </option>
                        </select>
                    </td>
                    <td class="col-4">
                        <!-- 生成唯一ID -->
                        <textarea th:id="'commentArea_' + ${iStat.index}" th:value="${question.comment}" placeholder="comment"
                                  class="form-control"
                                  th:field="*{questionnaire.questions[__${iStat.index}__].comment}"
                                  th:placeholder="#{comment}"
                                  rows="3" ></textarea>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

actions.js代码

修正逻辑,通过传递的参数定位对应元素:

function toggleCommentRequired(selectElement, index) {
    const selectedValue = selectElement.value;
    const commentArea = document.getElementById(`commentArea_${index}`);
    
    if (selectedValue !== "") {
        // 选中非默认选项,设置必填属性
        commentArea.setAttribute("required", "required");
    } else {
        // 选中默认选项,移除必填属性
        commentArea.removeAttribute("required");
    }
}

验证建议

  1. 打开浏览器开发者工具的Console面板,在函数内添加console.log(selectedValue, commentArea),确认是否能正确获取选中值和对应textarea元素。
  2. 手动切换下拉选项后,在Console中执行commentArea.hasAttribute('required'),验证属性是否按预期设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:45:03