复选框交互问题:点击切换增删Span内容、自定义输入处理及样式需求
修复复选框与文本同步的三个问题
我来帮你搞定这三个问题!下面是修复后的完整代码,之后我会逐个拆解每个问题的解决思路:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <style> input:disabled { opacity: 0; } input:enabled { opacity: 1; } .summary.empty { border: 1px solid red; } </style> <div class="container"> <div class="row"> <div class="col-sm-3"> <div class="input-item"> <input type="checkbox" name="fruits" id="fruit-pineapple" value="Ananas" class="fruits checkbox"> <label for="fruit-pineapple"><img src="img/ananas.png"></label> <p class="description">Ananas</p> </div> </div> <div class="col-sm-3"> <div class="input-item"> <input type="checkbox" name="fruits" id="fruit-apple" value="Jabłko" class="fruits checkbox"> <label for="fruit-apple"><img src="img/jablko.png"></label> <p class="description">Jabłko</p> </div> </div> <div class="col-sm-3"> <div class="input-item"> <input type="checkbox" name="fruits" id="fruits-oth" class="component-other"> <label for="fruits-oth"><img src="img/owoce-wlasne.png"></label> <p class="description">Własna propozycja</p> </div> </div> <input type="text" name="fruits-other" id="fruits-other" class="component-other-value" data-product="fruits" placeholder="Wpisz owoce" disabled> <div class="col-sm-3"> <div class="input-item"> <input type="checkbox" name="fruits" id="fruit-nofruit" value="Bez owoców" class="fruits checkbox"> <label for="fruit-nofruit"><img src="img/owoce-brak.png"></label> <p class="description">Bez owoców</p> </div> </div> </div> <p> Owoce: <br> <span id="summary_fruits" class="summary"></span> <span id="summary_other_fruits" class="summary"></span> </p> </div> <script> // 工具函数:更新空元素的红色边框 function updateEmptyBorder() { $('.summary').each(function() { if ($(this).text().trim() === '') { $(this).addClass('empty'); } else { $(this).removeClass('empty'); } }); } // 初始化时检查边框 updateEmptyBorder(); $('.checkbox').on('click', function(){ var $this = $(this); var dataAttr = $this.attr('name'); var dataAttrVal = $this.val(); var $summarySpan = $('#summary_' + dataAttr); var $hiddenInput = $('[name="' + dataAttr + '-value"]'); if ($this.is(':checked')) { // 选中时添加值 $summarySpan.append(dataAttrVal + ", "); $hiddenInput.append(dataAttrVal + ", "); } else { // 取消选中时移除对应值,处理逗号问题 var currentText = $summarySpan.text().trim(); // 替换掉 "值, " 或者 ", 值" 的情况 var newText = currentText.replace(new RegExp(dataAttrVal + ',\\s*|,\\s*' + dataAttrVal), '').replace(/,$/, '').trim(); $summarySpan.text(newText ? newText + ", " : ""); // 同步处理隐藏输入框 var hiddenVal = $hiddenInput.val().trim(); var newHiddenVal = hiddenVal.replace(new RegExp(dataAttrVal + ',\\s*|,\\s*' + dataAttrVal), '').replace(/,$/, '').trim(); $hiddenInput.val(newHiddenVal ? newHiddenVal + ", " : ""); } // 更新边框状态 updateEmptyBorder(); }); $('.component-other-value').on('change input', function(){ var $this = $(this); var dataName = $this.attr('data-product'); var value = $this.val().trim(); var $summarySpan = $('#summary_other_' + dataName); var $hiddenInput = $('[name="' + dataName + '-value"]'); // 先移除原来的自定义值 var hiddenVal = $hiddenInput.val().trim(); var oldCustomVal = $summarySpan.text().trim(); if (oldCustomVal) { hiddenVal = hiddenVal.replace(new RegExp(oldCustomVal + ',\\s*|,\\s*' + oldCustomVal), '').replace(/,$/, '').trim(); } // 添加新值 if (value) { $summarySpan.text(value); $hiddenInput.val(hiddenVal ? hiddenVal + ", " + value : value + ", "); } else { $summarySpan.text(""); $hiddenInput.val(hiddenVal ? hiddenVal + ", " : ""); } // 更新边框状态 updateEmptyBorder(); }); $('.component-other').on('click', function(){ var $this = $(this); var $input = $(this).closest('.container').find('.component-other-value'); var dataName = $input.attr('data-product'); var $summarySpan = $('#summary_other_' + dataName); var $hiddenInput = $('[name="' + dataName + '-value"]'); $input.prop("disabled", !this.checked); if (!this.checked) { // 取消时清空自定义内容 var customVal = $summarySpan.text().trim(); if (customVal) { var hiddenVal = $hiddenInput.val().trim(); hiddenVal = hiddenVal.replace(new RegExp(customVal + ',\\s*|,\\s*' + customVal), '').replace(/,$/, '').trim(); $hiddenInput.val(hiddenVal ? hiddenVal + ", " : ""); } $summarySpan.text(""); $input.val(""); } // 更新边框状态 updateEmptyBorder(); }); </script>
逐个问题的解决思路
1. 复选框选中/取消时的添加/删除逻辑
原来的代码不管复选框是否选中,都会执行append,所以取消选中时反而会重复添加值。咱们现在做了这几点修改:
- 先判断复选框的
checked状态:if ($this.is(':checked')) - 选中时正常追加值;取消时,用正则表达式从span和隐藏输入框中移除对应的值,同时处理残留的逗号(比如避免出现开头/结尾的逗号)
2. 自定义文本复选框的同步处理
针对自定义文本的复选框,咱们优化了两个场景:
- 当取消自定义复选框时,自动清空输入框内容、对应的summary span,同时从隐藏输入框中移除这个自定义值
- 输入框内容变化时,先移除原来的自定义值,再添加新值,避免重复追加;如果输入为空,就清空对应的span
3. 为空元素添加红色边框
我们添加了一个.summary.empty的CSS类,然后写了一个updateEmptyBorder工具函数:
- 每次修改span内容后,遍历所有
.summary元素 - 如果元素文本为空(trim后),就添加
empty类(红色边框);否则移除这个类 - 初始化页面时也会调用一次,确保初始状态正确
内容的提问来源于stack exchange,提问作者MMPL1
相关产品推荐
相关产品推荐

