系列文章介绍
本文是Jquery动态表单系列文章,有一些常见的表单知识以前都没有去深究,现在回过头来需要用到得去学习,原理都是Jquery对dom的操作,这里不选用原生Js采用Jquery简洁明了方便大家阅读,也不去用vue可以直接用组件。
本文是表单的动态追加
文章目录
系列文章介绍
前言
组件效果
点击:添加属性值
点击:添加属性值
二、效果实现
1.引入Jquery并写好模板
html页面
Js实现功能
初始效果
2.完整代码
三、Bug优化
分析:
改进:
修改后的完整代码
总结
前言
上班一年了,有一些以前觉得很厉害的功能觉得很麻烦学不会的功能,现在也能做了,写下来给刚学习的学弟学妹们做参考。
之前都没怎么能搜得到这些东西,也就觉得这个功能很高级。
一、组件来源
博主上班的地方是做跨境有自己的后台,做商品管理的时候有需要用到多规格sku这些,它这个还有点特殊不需要每个sku单独计算库存,因为是啥都发货啥都有货的嘛,只需要做前台商品详情页下单页能看到就行。
组件效果
话不多说先给大家看看这个组件效果
点击:添加属性值
点击:添加属性值
二、效果实现
1.引入Jquery并写好模板
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <!-- 引入 Material Icons --> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
html页面
<div class="container mt-4">
<h4>属性管理</h4>
<div id="attributes">
//这块是模板
<div class="form-group row">
<div class="col-sm-2">
<input type="text" placeholder="属性名称,例如(尺码,颜色)" class="form-control form-control-sm">
</div>
<div class="col-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUpload">
<label class="btn btn-info btn-sm" for="fileUpload" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-secondary btn-sm addValue">添加属性值</button>
<button type="button" class="btn btn-danger btn-sm removeAttribute">删除属性</button>
</div>
<div class="col-sm-12 mt-2 added-values"></div>
</div>
</div>
<button id="addAttribute" type="button" class="btn btn-primary btn-sm mt-2">添加属性</button>
<button id="submitBtn" type="button" class="btn btn-success btn-sm mt-2">提交</button>
</div>
效果:(第一行刚好没有删除属性值的按钮,至少要有个属性值生的写了)
Js实现功能
1.添加属性:(蓝色按钮)
//添加属性
$('#addAttribute').on('click', function() {
//克隆模板
var newAttribute = $('.form-group:first').clone();
newAttribute.find('input[type="text"]').val(''); // 清空输入框
newAttribute.find('input[type="file"]').val(''); // 清空文件输入
$('#attributes').append(newAttribute);
});
2.删除属性:(红色按钮)
//处理删除按钮的点击事件
$('#attributes').on('click', '.removeAttribute', function() {
$(this).closest('.form-group').remove();
});
3.添加属性值:(灰色按钮)
//处理添加属性值的点击事件
$('#attributes').on('click', '.addValue', function() {
var valueInput = `
<div class="form-group row mt-2">
<div class="col-sm-2 offset-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUploadValue">
<label class="btn btn-info btn-sm" for="fileUploadValue" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm removeValue">删除属性值</button>
</div>
</div>
`;
$(this).closest('.form-group').find('.added-values').append(valueInput);
});
4.删除属性值:(红色按钮,上图还没体现出来,等下就看到了)
//处理删除属性值的点击事件
$('#attributes').on('click', '.removeValue', function() {
$(this).closest('.form-group.row').remove();
});
5.提交按钮:(没有写Ajax的,只是把数据打印出来看看对不对)
//提交按钮事件
$('#submitBtn').on('click', function() {
let attributes = [];
$('#attributes .form-group').each(function() {
let attributeName = $(this).find('input[type="text"]').eq(0).val();
let attributeValue = $(this).find('input[type="text"]').eq(1).val();
let attributeImage = $(this).find('input[type="file"]').eq(0).prop('files')[0];
attributes.push({
name: attributeName,
value: attributeValue,
image: attributeImage ? attributeImage.name : null
});
});
console.log(JSON.stringify(attributes));
alert("提交的属性数据已打印到控制台。");
});
初始效果
1.添加属性值
2.删除属性值,同上,一整块删掉。
3.添加属性值
4.删除属性值
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<title>动态表单</title>
</head>
<body>
<div class="container mt-4">
<h4>属性管理</h4>
<div id="attributes">
<!-- 模板 -->
<div class="form-group row">
<div class="col-sm-2">
<input type="text" placeholder="属性名称,例如(尺码,颜色)" class="form-control form-control-sm">
</div>
<div class="col-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUpload">
<label class="btn btn-info btn-sm" for="fileUpload" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-secondary btn-sm addValue">添加属性值</button>
<button type="button" class="btn btn-danger btn-sm removeAttribute">删除属性</button>
</div>
<div class="col-sm-12 mt-2 added-values"></div>
</div>
</div>
<button id="addAttribute" type="button" class="btn btn-primary btn-sm mt-2">添加属性</button>
<button id="submitBtn" type="button" class="btn btn-success btn-sm mt-2">提交</button>
</div>
<script>
$(document).ready(function() {
$('#addAttribute').on('click', function() {
//克隆模板
var newAttribute = $('.form-group:first').clone();
newAttribute.find('input[type="text"]').val(''); // 清空输入框
newAttribute.find('input[type="file"]').val(''); // 清空文件输入
$('#attributes').append(newAttribute);
});
//处理删除按钮的点击事件
$('#attributes').on('click', '.removeAttribute', function() {
$(this).closest('.form-group').remove();
});
//处理添加属性值的点击事件
$('#attributes').on('click', '.addValue', function() {
var valueInput = `
<div class="form-group row mt-2">
<div class="col-sm-2 offset-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUploadValue">
<label class="btn btn-info btn-sm" for="fileUploadValue" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm removeValue">删除属性值</button>
</div>
</div>
`;
$(this).closest('.form-group').find('.added-values').append(valueInput);
});
//处理删除属性值的点击事件
$('#attributes').on('click', '.removeValue', function() {
$(this).closest('.form-group.row').remove();
});
//提交按钮事件
$('#submitBtn').on('click', function() {
let attributes = [];
$('#attributes .form-group').each(function() {
let attributeName = $(this).find('input[type="text"]').eq(0).val();
let attributeValue = $(this).find('input[type="text"]').eq(1).val();
let attributeImage = $(this).find('input[type="file"]').eq(0).prop('files')[0];
attributes.push({
name: attributeName,
value: attributeValue,
image: attributeImage ? attributeImage.name : null
});
});
console.log(JSON.stringify(attributes));
alert("提交的属性数据已打印到控制台。");
});
});
</script>
<!-- 引入 Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</body>
</html>
2.完整代码
上面是一个完整的教程,正常咱要实现功能也是这样的一个想法、步骤。
实际解决问题也是这样,上大学的时候听得懂,但是无从下手,所以还是喜欢写这种手把手教程来引导一下你们,希望对你们有帮助。下面代码有小bug,所以还会有第三小节讲改bug。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<title>动态表单</title>
</head>
<body>
<div class="container mt-4">
<h4>属性管理</h4>
<div id="attributes">
<!-- 模板 -->
<div class="form-group row">
<div class="col-sm-2">
<input type="text" placeholder="属性名称,例如(尺码,颜色)" class="form-control form-control-sm">
</div>
<div class="col-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUpload">
<label class="btn btn-info btn-sm" for="fileUpload" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-secondary btn-sm addValue">添加属性值</button>
<button type="button" class="btn btn-danger btn-sm removeAttribute">删除属性</button>
</div>
<div class="col-sm-12 mt-2 added-values"></div>
</div>
</div>
<button id="addAttribute" type="button" class="btn btn-primary btn-sm mt-2">添加属性</button>
<button id="submitBtn" type="button" class="btn btn-success btn-sm mt-2">提交</button>
</div>
<script>
$(document).ready(function() {
$('#addAttribute').on('click', function() {
//克隆模板
var newAttribute = $('.form-group:first').clone();
newAttribute.find('input[type="text"]').val(''); // 清空输入框
newAttribute.find('input[type="file"]').val(''); // 清空文件输入
$('#attributes').append(newAttribute);
});
//处理删除按钮的点击事件
$('#attributes').on('click', '.removeAttribute', function() {
$(this).closest('.form-group').remove();
});
//处理添加属性值的点击事件
$('#attributes').on('click', '.addValue', function() {
var valueInput = `
<div class="form-group row mt-2">
<div class="col-sm-2 offset-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUploadValue">
<label class="btn btn-info btn-sm" for="fileUploadValue" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm removeValue">删除属性值</button>
</div>
</div>
`;
$(this).closest('.form-group').find('.added-values').append(valueInput);
});
//处理删除属性值的点击事件
$('#attributes').on('click', '.removeValue', function() {
$(this).closest('.form-group.row').remove();
});
//提交按钮事件
$('#submitBtn').on('click', function() {
let attributes = [];
$('#attributes .form-group').each(function() {
let attributeName = $(this).find('input[type="text"]').eq(0).val();
let attributeValue = $(this).find('input[type="text"]').eq(1).val();
let attributeImage = $(this).find('input[type="file"]').eq(0).prop('files')[0];
attributes.push({
name: attributeName,
value: attributeValue,
image: attributeImage ? attributeImage.name : null
});
});
console.log(JSON.stringify(attributes));
alert("提交的属性数据已打印到控制台。");
});
});
</script>
<!-- 引入 Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</body>
</html>
三、Bug优化
分析:
这边我们在第一个属性那边再添加一个或几个属性值的时候,然后有需要添加其他属性,就会把上面一整块都添加下来
改进:
把模板写到JavaScript里:
// 属性模板
const attributeTemplate = `
<div class="form-group row">
<div class="col-sm-2">
<input type="text" placeholder="属性名称,例如(尺码,颜色)" class="form-control form-control-sm">
</div>
<div class="col-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUpload">
<label class="btn btn-info btn-sm" for="fileUpload" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-secondary btn-sm addValue">添加属性值</button>
<button type="button" class="btn btn-danger btn-sm removeAttribute">删除属性</button>
</div>
<div class="col-sm-12 mt-2 added-values"></div>
</div>
`;
// 初始显示一组属性
$('#attributes').append(attributeTemplate);
在html里就没有这个,就不会以这个为模板
<div class="container mt-4">
<h4>属性管理</h4>
<div id="attributes"></div>
<button id="addAttribute" type="button" class="btn btn-primary btn-sm mt-2">添加属性</button>
<button id="submitBtn" type="button" class="btn btn-success btn-sm mt-2">提交</button>
</div>
Javascript:
//添加属性组
$('#addAttribute').on('click', function() {
//添加新的属性组
$('#attributes').append(attributeTemplate);
});
//处理删除按钮的点击事件
$('#attributes').on('click', '.removeAttribute', function() {
$(this).closest('.form-group').remove();
});
//处理添加属性值的点击事件
$('#attributes').on('click', '.addValue', function() {
var valueInput = `
<div class="form-group row mt-2">
<div class="col-sm-2 offset-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUploadValue">
<label class="btn btn-info btn-sm" for="fileUploadValue" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm removeValue">删除属性值</button>
</div>
</div>
`;
$(this).closest('.form-group').find('.added-values').append(valueInput);
});
//处理删除属性值的点击事件
$('#attributes').on('click', '.removeValue', function() {
$(this).closest('.form-group.row').remove();
});
//提交按钮事件
$('#submitBtn').on('click', function() {
let attributes = [];
$('#attributes .form-group').each(function() {
let attributeName = $(this).find('input[type="text"]').eq(0).val();
let attributeValue = $(this).find('input[type="text"]').eq(1).val();
let attributeImage = $(this).find('input[type="file"]').eq(0).prop('files')[0];
attributes.push({
name: attributeName,
value: attributeValue,
image: attributeImage ? attributeImage.name : null
});
});
console.log(JSON.stringify(attributes));
alert("提交的属性数据已打印到控制台。");
});
修改后的完整代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<title>动态表单</title>
</head>
<body>
<div class="container mt-4">
<h4>属性管理</h4>
<div id="attributes"></div>
<button id="addAttribute" type="button" class="btn btn-primary btn-sm mt-2">添加属性</button>
<button id="submitBtn" type="button" class="btn btn-success btn-sm mt-2">提交</button>
</div>
<script>
$(document).ready(function() {
// 属性模板
const attributeTemplate = `
<div class="form-group row">
<div class="col-sm-2">
<input type="text" placeholder="属性名称,例如(尺码,颜色)" class="form-control form-control-sm">
</div>
<div class="col-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUpload">
<label class="btn btn-info btn-sm" for="fileUpload" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-secondary btn-sm addValue">添加属性值</button>
<button type="button" class="btn btn-danger btn-sm removeAttribute">删除属性</button>
</div>
<div class="col-sm-12 mt-2 added-values"></div>
</div>
`;
//初始显示一组属性
$('#attributes').append(attributeTemplate);
//添加属性组
$('#addAttribute').on('click', function() {
//添加新的属性组
$('#attributes').append(attributeTemplate);
});
//处理删除按钮的点击事件
$('#attributes').on('click', '.removeAttribute', function() {
$(this).closest('.form-group').remove();
});
//处理添加属性值的点击事件
$('#attributes').on('click', '.addValue', function() {
var valueInput = `
<div class="form-group row mt-2">
<div class="col-sm-2 offset-sm-2">
<input type="text" placeholder="属性值,例如(黑色)" class="form-control form-control-sm">
</div>
<div class="col-sm-1">
<input type="file" accept="image/*" class="form-control-file" style="display: none;" id="fileUploadValue">
<label class="btn btn-info btn-sm" for="fileUploadValue" style="width: 30px; height: 30px; display: flex; justify-content: center; align-items: center; border-radius: 5px;">
<span class="material-icons" style="font-size: 20px;">upload</span>
</label>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-danger btn-sm removeValue">删除属性值</button>
</div>
</div>
`;
$(this).closest('.form-group').find('.added-values').append(valueInput);
});
//处理删除属性值的点击事件
$('#attributes').on('click', '.removeValue', function() {
$(this).closest('.form-group.row').remove();
});
//提交按钮事件
$('#submitBtn').on('click', function() {
let attributes = [];
$('#attributes .form-group').each(function() {
let attributeName = $(this).find('input[type="text"]').eq(0).val();
let attributeValue = $(this).find('input[type="text"]').eq(1).val();
let attributeImage = $(this).find('input[type="file"]').eq(0).prop('files')[0];
attributes.push({
name: attributeName,
value: attributeValue,
image: attributeImage ? attributeImage.name : null
});
});
console.log(JSON.stringify(attributes));
alert("提交的属性数据已打印到控制台。");
});
});
</script>
<!-- 引入 Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</body>
</html>
总结
这就是一个比较完整的动态追加的学习例子,最近也是大四孩子们该写毕设的日期了(虽然我当时写了好几个月,传个值都不会)。
希望通过这个项目,能让你学会了如何使用 jQuery 动态添加和管理表单元素,增强了对 Bootstrap 网格系统的理解。未来可以进一步扩展功能,例如添加表单验证、样式优化等。