
本文介绍如何在 pos 系统的购物表中,通过 javascript 检测重复商品并自动累加其数量,而非新增行,从而提升数据整洁性与用户体验。
本文介绍如何在 pos 系统的购物表中,通过 javascript 检测重复商品并自动累加其数量,而非新增行,从而提升数据整洁性与用户体验。
在开发收银或库存类系统(如 POS)时,频繁扫描同一商品是常见场景。若每次扫描都新增一行,会导致表格冗余、统计困难、UI 杂乱。理想行为应是:首次添加时插入新行,后续同名商品仅将对应行的 quantity 单元格值 +1。下面我们将基于 jQuery 实现这一逻辑,并确保代码健壮、可维护。
✅ 核心思路
- 点击“添加商品”按钮时,先动态插入一个空行(含搜索框和数量输入框);
- 用户从搜索结果中选择商品后,遍历现有所有行,检查是否已存在相同商品名称;
- 若存在,则读取当前数量、转为整数、+1 后更新;若不存在,则填充该行的商品名,并保留数量为 1;
- 关键细节:若检测到重复,需立即移除刚创建的空行,避免残留无效 DOM。
✅ 优化后的完整实现(含注释)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$(document).on('click', '.btnaddstockTransfer', function() {
// 动态生成新行(注意:追加到 tbody 内,语义更规范)
const html = `
<tr>
<td>
<div class="search-box">
<input class="form-control is-warning stock"
type="text" name="stock[]" placeholder="Search by name or code">
<div class="result"></div>
</div>
</td>
<td>
<input class="form-control qty" type="text" name="qty[]" required size="2" value="1">
</td>
</tr>`;
$('#stockTransfer tbody').append(html);
});
// 实时搜索(简化版,仅演示交互逻辑)
$(document).on('keyup input', '.search-box input[type="text"]', function() {
const inputVal = $(this).val().trim();
const $result = $(this).siblings('.result');
if (inputVal.length > 0) {
$result.html('<p>Result 1</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill11083" title="Java调试"><img
src="https://img.php.cn/upload/skill/001/246/273/6adaf20dbae7c507.jpg" alt="Java调试" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill11083" title="Java调试">Java调试</a>
<p>通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。
术语注解
JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议)
remote JVM:远程 Java 虚拟机
step through code:代码单步调试(步入 / 步过 / 步出调试)
inspect variables:变量查看 / 变量检视
stac</p>
</div>
<a href="/xiazai/skill11083" title="Java调试" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>Result 2</p>');
} else {
$result.empty();
}
});
// 点击搜索结果项
$(document).on('click', '.result p', function() {
const selectedStock = $(this).text().trim();
const $tr = $(this).closest('tr'); // 安全获取当前行(兼容嵌套结构)
const $qtyInput = $tr.find('.qty');
let found = false;
// 遍历 tbody 中所有已有商品行(跳过空行或 header)
$('#stockTransfer tbody tr').each(function() {
const $row = $(this);
const existingStock = $row.find('.stock').val()?.trim();
if (existingStock === selectedStock) {
const currentQty = parseInt($row.find('.qty').val()) || 0;
$row.find('.qty').val(currentQty + 1);
found = true;
return false; // break 循环
}
});
if (found) {
$tr.remove(); // 移除本次新建的冗余行
} else {
$tr.find('.stock').val(selectedStock); // 填充商品名
$qtyInput.val(1); // 显式设为 1(虽初始值已是 1,但确保逻辑清晰)
}
$(this).parent('.result').empty(); // 清空下拉结果
});
});
</script>
<button class="btnaddstockTransfer" type="button">Add stock transfer</button>
<div style="overflow-x:auto">
<table id="stockTransfer" class="table">
<thead>
<tr>
<th style="color:blue">Search Product (Name/Code)</th>
<th style="color:blue">Quantity</th>
</tr>
</thead>
<tbody>
<!-- 初始为空,由 JS 动态填充 -->
</tbody>
</table>
</div>⚠️ 注意事项与最佳实践
-
DOM 查询性能:
.each()遍历在小规模表格(stock → row index 提升查找效率。 -
输入校验:示例中未做防注入处理,生产环境应对
selectedStock做 HTML 转义(如$.text()替代.text()直接赋值),或使用textContent。 -
数值安全:
parseInt(...)+|| 0可防止NaN导致计算异常;也可改用Number()并配合isNaN()判断。 -
空行清理:务必移除重复触发时产生的空行(
$tr.remove()),否则会积累无意义<tr>,影响后续遍历逻辑。 <li> <strong>语义化结构</strong>:始终将动态行插入 <code><tbody>,而非整个 <code><table>,符合 HTML 表格标准,利于 CSS 样式与屏幕阅读器支持。<p>通过以上实现,你的 POS 表格将具备智能去重与数量聚合能力——既保持界面简洁,又为后续结算、导出、库存同步等环节提供干净可靠的数据基础。</p> <p><span>立即学习</span>“<a href="https://pan.quark.cn/s/c1c2c2ed740f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">Java免费学习笔记(深入)</a>”;</p> </table>

















