Jquery动态表单系列:表单动态追加

系列文章介绍

        本文是Jquery动态表单系列文章,有一些常见的表单知识以前都没有去深究,现在回过头来需要用到得去学习,原理都是Jquery对dom的操作,这里不选用原生Js采用Jquery简洁明了方便大家阅读,也不去用vue可以直接用组件。


本文是表单的动态追加


前言

上班一年了,有一些以前觉得很厉害的功能觉得很麻烦学不会的功能,现在也能做了,写下来给刚学习的学弟学妹们做参考。

之前都没怎么能搜得到这些东西,也就觉得这个功能很高级。


一、组件来源

        博主上班的地方是做跨境有自己的后台,做商品管理的时候有需要用到多规格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 网格系统的理解。未来可以进一步扩展功能,例如添加表单验证、样式优化等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小于晏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值