2020-12-08更新
修复了一些小bug
- 在规格参数中输入1个字符以上时会根据字符串长度n生成n个列
- 在只有一个规格时,计算生成表格行时会出错
添加的功能
- 计算表格数据
更改后的demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.js"></script>
<style>
.form-control {width: 200px!important;}
</style>
</head>
<body>
<div class="container mt-5">
<div class="mb-3">
<input type="button" class="btn btn-sm btn-primary" value="添加商品规格" id="add-spec">
<input type="button" class="btn btn-sm btn-primary" value="生成表格" id="reflash">
<input type="button" class="btn btn-sm btn-primary" value="计算表格" id="conputeTable">
</div>
<div id="content">
</div>
<div id="table-list"></div>
</div>
</body>
<script>
// 笛卡尔积
var Cartesian = function(a, b) {
var ret = [];
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < b.length; j++) {
ret.push(ft(a[i], b[j]));
}
}
return ret;
}
var ft = function(a, b) {
if (! (a instanceof Array)) a = a;
var ret = Array();
ret.push(a, b);
return ret;
}
//多个一起做笛卡尔积
multiCartesian = function(data) {
var len = data.length;
if (len == 0) return [];
else if (len == 1) return data[0];
else {
var r = data[0];
for (var i = 1; i < len; i++) {
r = Cartesian(r, data[i]);
}
return r;
}
}
// 规格模板
var specNameHtml = `<div class="spec-list mb-2">
<div class="d-flex align-items-center spec-item">
<input type="text" class="form-control" name="spec_name" placeholder="规格名称">
<input type="button" class="btn btn-sm btn-dark ml-1 mr-1" value="添加参数" id="add-params">
<input type="button" class="btn btn-sm btn-dark ml-1 mr-1" value="删除规格" id="del-spec">
</div>
<div class="mt-2 params-list">
</div>
</div>`;
var specParamsHtml = `<div class="d-flex align-items-center mt-1 ml-3">
<input type="text" class="form-control" name="spec_param" placeholder="参数名称">
<input type="button" class="btn btn-sm btn-dark ml-1 mr-1" value="删除参数" id="del-params">
</div>`;
// 添加规格
$(document).on('click', '#add-spec', function () {
$('#content').append(specNameHtml);
})
// 删除规格
$(document).on('click', '#del-spec', function () {
$(this).parents('.spec-list').remove();
})
// 添加参数
$(document).on('click', '#add-params', function () {
$(this).parents('.spec-list').find('.params-list').append(specParamsHtml)
})
// 删除参数
$(document).on('click', '#del-params', function () {
$(this).parent().remove();
})
// // 刷新表格
$(document).on('click', '#reflash', function () {
if ($('#content').children().length == 0) {
return;
}
// 存放规格名称
var spec_name = [];
// 存放规格参数
var spec_param = [];
// 规格名称输入框组
var specNameList = $('input[name="spec_name"]');
// 将表单内的用户输入加入数组中
for (var i = 0; i < specNameList.length; i++) {
spec_name.push($(specNameList[i]).val())
// 规格参数组
var paramsList = $(specNameList[i]).parents('.spec-list').find('.params-list').find('input[name="spec_param"]')
var params = []
if (paramsList.length > 0) {
for (var j = 0; j < paramsList.length; j++) {
params.push($(paramsList[j]).val())
}
}
spec_param.push(params)
}
console.log(spec_param)
// 笛卡尔积计算得出一共有多少规格
var cartesianList = multiCartesian(spec_param)
console.log(cartesianList)
// 表格渲染
var tb = '';
tb += `<table id="spec_table" class="table table-stiped">
<thead>
<tr>`;
// 将规格名称加入表格列中
for (var i = 0; i < spec_name.length; i++) {
tb += ` <th>`+ spec_name[i] +`</th>`;
}
// 扩展字段,可删减
tb += ` <th>原价</th>
<th>折扣价</th>
<th>库存</th>`;
tb += ` </tr>`;
tb += `</thead>`;
tb += `<tbody>`;
// 将上面计算出来的规格数组进行拆分重组,再加入表格中
for (var i = 0; i < cartesianList.length; i++) {
tb += `<tr>`;
try {
var rows = cartesianList[i].flat()
for (var j = 0; j < rows.length; j++) {
tb += `<td>`+ rows[j] +`</td>`;
}
} catch {
var rows = cartesianList[i]
tb += `<td>`+ rows +`</td>`;
}
// 扩展字段,可删减
tb += ` <td>
<input type="text" class="form-control" name="[spec_cost_price]" placeholder="原价" value="0">
</td>`;
tb += ` <td>
<input type="text" class="form-control" name="[spec_discount_price]" placeholder="折扣价" value="0">
</td>`;
tb += ` <td>
<input type="text" class="form-control" name="[spec_sku]" placeholder="库存" value="0">
</td>`;
tb += `</tr>`;
}
tb += `</tbody>`;
tb += `</table>`;
$('#table-list').html(tb);
})
$('#conputeTable').on('click', function () {
if ($('#table-list').children().length == 0) {
return
}
var data = []
var table = $('#table-list').find('#spec_table');
var content = $(table).find('tbody');
$(content).find('tr').each((k, i) => {
let row = [];
$(i).find('td').each((tdk, tditem) => {
if ($(tditem).find('input').length > 0) {
row.push($(tditem).find('input').val())
}else {
row.push($(tditem).text().trim())
}
})
data.push(row)
})
console.log(data)
})
</script>
</html>
以下是原文
整理整合一份后台管理中商品规格添加显示的demo供大家参考,cv就可以看到效果,如果有更好的方法欢迎讨论
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/js/bootstrap.js"></script>
<style>
.form-control {width: 200px!important;}
</style>
</head>
<body>
<div class="container mt-5">
<div class="mb-3">
<input type="button" class="btn btn-sm btn-primary" value="添加商品规格" id="add-spec">
<input type="button" class="btn btn-sm btn-primary" value="刷新表格" id="reflash">
</div>
<div id="content">
</div>
<div id="table-list"></div>
</div>
</body>
<script>
// 笛卡尔积
var Cartesian = function(a, b) {
var ret = [];
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < b.length; j++) {
ret.push(ft(a[i], b[j]));
}
}
return ret;
}
var ft = function(a, b) {
if (! (a instanceof Array)) a = [a];
var ret = Array.call(null, a);
ret.push(b);
return ret;
}
//多个一起做笛卡尔积
multiCartesian = function(data) {
var len = data.length;
if (len == 0) return [];
else if (len == 1) return data[0];
else {
var r = data[0];
for (var i = 1; i < len; i++) {
r = Cartesian(r, data[i]);
}
return r;
}
}
// 规格模板
var specNameHtml = `<div class="spec-list mb-2">
<div class="d-flex align-items-center spec-item">
<input type="text" class="form-control" name="spec_name" placeholder="规格名称">
<input type="button" class="btn btn-sm btn-info ml-1 mr-1" value="添加参数" id="add-params">
<input type="button" class="btn btn-sm btn-info ml-1 mr-1" value="删除规格" id="del-spec">
</div>
<div class="mt-2 params-list">
</div>
</div>`;
var specParamsHtml = `<div class="d-flex align-items-center mt-1 ml-3">
<input type="text" class="form-control" name="spec_param" placeholder="参数名称">
<input type="button" class="btn btn-sm btn-info ml-1 mr-1" value="删除参数" id="del-params">
</div>`;
// 添加规格
$(document).on('click', '#add-spec', function () {
$('#content').append(specNameHtml);
})
// 删除规格
$(document).on('click', '#del-spec', function () {
$(this).parents('.spec-list').remove();
})
// 添加参数
$(document).on('click', '#add-params', function () {
$(this).parents('.spec-list').find('.params-list').append(specParamsHtml)
})
// 删除参数
$(document).on('click', '#del-params', function () {
$(this).parent().remove();
})
// // 刷新表格
$(document).on('click', '#reflash', function () {
if ($('#content').children().length == 0) {
return;
}
// 存放规格名称
var spec_name = [];
// 存放规格参数
var spec_param = [];
// 规格名称输入框组
var specNameList = $('input[name="spec_name"]');
// 将表单内的用户输入加入数组中
for (var i = 0; i < specNameList.length; i++) {
spec_name.push($(specNameList[i]).val())
// 规格参数组
var paramsList = $(specNameList[i]).parents('.spec-list').find('.params-list').find('input[name="spec_param"]')
var params = []
if (paramsList.length > 0) {
for (var j = 0; j < paramsList.length; j++) {
params.push($(paramsList[j]).val())
}
}
spec_param.push(params)
}
// 笛卡尔积计算得出一共有多少规格
var cartesianList = multiCartesian(spec_param)
// 表格渲染
var tb = '';
tb += `<table class="table table-stiped">
<thead>
<tr>`;
// 将规格名称加入表格列中
for (var i = 0; i < spec_name.length; i++) {
tb += ` <th>`+ spec_name[i] +`</th>`;
}
// 扩展字段,可删减
tb += ` <th>原价</th>
<th>折扣价</th>
<th>库存</th>`;
tb += ` </tr>`;
tb += `</thead>`;
tb += `<tbody>`;
tb += `</tbody>`;
// 将上面计算出来的规格数组进行拆分重组,再加入表格中
for (var i = 0; i < cartesianList.length; i++) {
tb += `<tr>`;
var rows = cartesianList[i] instanceof Array ? cartesianList[i].join('').split(',') : cartesianList[i].split(',');
for (var j = 0; j < rows.length; j++) {
tb += `<td>`+ rows[j] +`</td>`;
}
// 扩展字段,可删减
tb += ` <td>
<input type="text" class="form-control" name="`+ rows[j] +`[cost_price]" placeholder="原价">
</td>`;
tb += ` <td>
<input type="text" class="form-control" name="`+ rows[j] +`[discount_price]" placeholder="折扣价">
</td>`;
tb += ` <td>
<input type="text" class="form-control" name="`+ rows[j] +`[sku]" placeholder="库存">
</td>`;
tb += `</tr>`;
}
tb += `</table>`;
$('#table-list').html(tb);
})
</script>
</html>