首页 前端知识 Jquery动态表单系列:表单动态追加

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

2024-09-29 22:09:14 前端知识 前端哥 623 746 我要收藏

系列文章介绍

        本文是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 网格系统的理解。未来可以进一步扩展功能,例如添加表单验证、样式优化等。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/18762.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!