动态添加多行的jQuery插件——addRowsPlugin.js

插件特点:

1.做动态添加行更便捷;

2.有常用回调函数使得插件更灵活;

3.支持链式调用。

下面直接上代码:

第一步首先引入jQuery,版本别太老就行,我是用的1.8.2的版本;

第二步引入addRowsPlugin.css,代码如下;

/**
 * jQuery Add Or Del Rows Plugin Css
 * Author: fcl<2438564025@qq.com>
 * Author URL: http://www.uhang.com.cn
 * Version: 1.0.0
 */
.addRowsTemp{
    display: none;
}

第三步引入addRowsPlugin.js,代码如下;

/**
 * jQuery Add Or Del Rows Plugin Js
 * Author: fcl<2438564025@qq.com>
 * Author URL: http://www.uhang.com.cn
 * Version: 1.0.0
 */
;(function($){
    //开启严格模式(消除代码运行的一些不安全之处,保证代码运行的安全;提高编译器效率,增加运行速度;为未来新版本的Javascript做好铺垫)
    "use strict";
    /* 错误日志 */
    function addRowsPlugin_log(elem, tempCount, itemsCount, error) {
        alert("==================错误日志===================\n" +
            "【调用插件对象的各项参数】\n" +
            " · 元素类型:" + elem.get(0).nodeName + "\n" +
            " · 元素ID:" + elem.get(0).id + "\n"+
            " · 元素class:" + elem.get(0).className + "\n" +
            " · 模板个数:" + tempCount + "\n" +
            " · 默认显示行数:" + itemsCount + "\n" +
            "【错误原因】\n" +
            " · " + error);
        console.groupCollapsed("%c调用插件的对象","font-size:20px;color:red;");
        console.log($(this));
        console.groupEnd();
    };
    /* 多行添加插件 */
    $.fn.addRowsPlugin = function(options){
        //默认参数
        var defaults = {
            temp : ".addRowsTemp",  //模板行的class选择器
            items : ".addRowsItems",  //默认显示行的class选择器
            addBtn : ".addBtn",  //添加按钮的选择器
            delBtn : ".delBtn",  //删除按钮的选择器
            minCount : 0,  //最小行数。默认0,至少有1行,剩余的最后一行可删除;设置为1,则至少有一行,剩余的最后一行不可删除
            maxCount : -1,  //最大行数。默认-1,行数无限制
            message: function (operationType, msg) { return false; },  //operationType:操作类型;msg:提示的文字。行数验证函数,默认false不继续执行添加
            AddBefore: function (btn) { return true; },  //btn:点击的添加按钮对象。添加前事件,默认true继续执行添加,如果返回false,则不继续执行添加
            DelBefore: function (btn) { return true; },  //btn:点击的删除按钮对象。删除前事件,默认true继续执行删除,如果返回false,则不继续执行删除
            AddAfter: function (elem) { },  //elem:返回新增行dom对象。添加后事件
            DelAfter: function (elem) { },  //elem:返回剩余行dom对象。删除后事件
            UpdateName: function (elem, index) {  //elem:所有要更新name的行的dom对象;index:更新行的起始索引号。
                elem.each(function (i,n) {
                    var reg = new RegExp('\\[(.+?)\\]',"g");//正则全局匹配[]
                    $.each($(n).find("[name]"), function(j , e) {
                        $(e).attr("name",$(e).attr("name").replace(reg,"["+(index+i)+"]"));
                    });
                });
            }  //更新name函数
        };
        //操作类型
        var operationTypeEnum = {
            Add: "add",//添加
            Del:"del"//删除
        };
        var options = $.extend(defaults,options); //传入的参数覆盖默认参数
        $.each(this, function(i, n) {//对元素遍历绑定执行内容
            var $container = $(n);//缓存调用插件的当前元素this(适应多个调用该插件的情况)
            var $temp = $container.find(options.temp);//模板对象
            //检测插件异常
            if($temp.length!=1){
                addRowsPlugin_log($container, $temp.length, $container.find(options.items).length, "插件未找到或找到多个模板");
                return;
            }else if(!($container.find(options.items).length>=options.minCount)){
                addRowsPlugin_log($container, $temp.length, $container.find(options.items).length, "默认显示行数小于最小行数限制");
                return;
            }
            //删除模板class标记,添加具体行class标记
            $temp.removeClass(options.temp.substring(1, options.temp.length)).addClass(options.items.substring(1, options.items.length));
            var tempHTML = $temp.prop("outerHTML");//模板html字符串
            //删除模板dom
            $temp.remove();

            //添加行事件 (先移除绑定的事件,主要是避免重复绑定点击事件问题)
            $container.off("click",options.addBtn).on("click",options.addBtn, function () {
                //验证行数
                if ($container.find(options.items).length == options.maxCount) {
                    if (!options.message.call(this, operationTypeEnum.Add, "最多只能添加" + options.maxCount + "行!")) {
                        return false;
                    }
                }
                //添加前执行
                if (!options.AddBefore.call(this, $(this))) {
                    return false;
                }
                //当前行
                var nowRow = $(this).closest(options.items);
                //在当前行后面新增一行
                nowRow.after(tempHTML);
                //更新name
                var _thisIndex = $container.find(options.items).index(nowRow)+1;//当前操作行的索引号+1作为更新行的起始索引号
                options.UpdateName.call(this, nowRow.nextAll(options.items), _thisIndex);
                //添加后执行
                options.AddAfter.call(this, nowRow.next(options.items));
            });

            //删除行事件
            $container.off("click",options.delBtn).on("click",options.delBtn, function () {
                //验证行数
                var rowCount = $container.find(options.items).length;
                if (rowCount == options.minCount) {
                    if (!options.message.call(this, operationTypeEnum.Del, "最少要有" + options.minCount + "行!")) {
                        return false;
                    }
                }
                //删除前执行
                if (!options.DelBefore.call(this, $(this))) {
                    return false;
                }
                //当前行
                var nowRow = $(this).closest(options.items);
                //缓存要更新name的行和起始索引号
                var updateRow = nowRow.nextAll(options.items);
                var _thisIndex = $container.find(options.items).index(nowRow);//当前操作行的索引号作为更新行的起始索引号
                //缓存动态行父级容器
                var rowsBox = nowRow.parent();
                //删除当前行
                nowRow.remove();
                //如果删除的是最后一行就新增一行默认行
                if(rowCount == 1){
                    rowsBox.append(tempHTML);
                    updateRow = rowsBox.find(options.items);
                    options.AddAfter.call(this, updateRow);//自动新增的默认行也同步添加后事件
                }
                //更新name
                options.UpdateName.call(this, updateRow, _thisIndex);
                //删除后执行
                options.DelAfter.call(this, $container.find(options.items));
            });
        });
        return $(this);   //把节点对象返回去,为了支持链式调用。
    }
})(jQuery);

第四步就是html部分了,主要是addRowsTemp标识的模板行和addRowsItems标识的具体行两段;

<body>
		<fieldset>
	        <legend>log:</legend>
	        <div>
	            <textarea id="txtMsg" style="width: 100%; height: 100px;"></textarea>
	        </div>
	    </fieldset>

	    <fieldset>
	        <legend>多行添加实例</legend>
            <table class="table" cellpadding="0" cellspacing="0" border="1" style="width: 100%;">
            	<thead align="center">
            		<tr>
	            		<th>学号</th>
	            		<th>姓名</th>
	            		<th>性别</th>
	            		<th>年龄</th>
	            		<th>院系</th>
	            		<th>班级</th>
	            		<th>操作</th>
            		</tr>
            	</thead>
            	<tbody align="center">
            		<!--新增行模板加class标记:addRowsTemp-->
	                <tr height="40px" class="addRowsTemp">
	                    <td>
	                    	<!--模板里的表单控件,name属性值中括号中的下标值可以是任意数字或字符串,但是不能为空-->
	                        <input type="text" name="studentList[任意字符串].id"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[999].name"/>
	                    </td>
	                    <td>
	                        <select name="studentList[0].sex" style="width: 173px;">
	                        	<option value="">请选择</option>
	                        	<option value="男">男</option>
	                        	<option value="女">女</option>
	                        </select>
	                    </td>
	                    <td>
	                        <input type="number" min="0" name="studentList[0].age"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[0].yx"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[0].bj"/>
	                    </td>
	                    <td>
	                    	<!--添加按钮加class标记:addBtn-->
	                        <button class="addBtn">添加</button>
	                        <!--删除按钮加class标记:delBtn-->
	                        <button class="delBtn">删除</button>
	                    </td>
	                </tr>
	                <!--默认显示行加class标记:addRowsItems-->
	                <tr height="40px" class="addRowsItems">
	                    <td>
	                        <input type="text" name="studentList[0].id"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[0].name"/>
	                    </td>
	                    <td>
	                        <select name="studentList[0].sex" style="width: 173px;">
	                        	<option value="">请选择</option>
	                        	<option value="男">男</option>
	                        	<option value="女">女</option>
	                        </select>
	                    </td>
	                    <td>
	                        <input type="number" min="0" name="studentList[0].age"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[0].yx"/>
	                    </td>
	                    <td>
	                        <input type="text" name="studentList[0].bj"/>
	                    </td>
	                    <td>
	                        <!--添加按钮加class标记:addBtn-->
	                        <button class="addBtn">添加</button>
	                        <!--删除按钮加class标记:delBtn-->
	                        <button class="delBtn">删除</button>
	                    </td>
	                </tr>
                </tbody>
            </table>
	    </fieldset>
	</body>

最后一步就是调用插件初始化了

$(document).ready(function(){
				var $msg = $("#txtMsg"), line = 1;
				//初始化插件
				$(".table").addRowsPlugin({
					maxCount:10,
					AddBefore: function (btn) {
						$msg.val($msg.val() + (line++) + "   添加前事件:add" + "\r\n");
                    	$msg.scrollTop($msg[0].scrollHeight);
                    	console.log(btn);
						return true;
					},
					DelBefore: function (btn) {
						$msg.val($msg.val() + (line++) + "   删除前事件:del" + "\r\n");
                    	$msg.scrollTop($msg[0].scrollHeight);
                    	console.log(btn);
						return true;
					},
					message: function (operationType, msg) {
						$msg.val($msg.val() + (line++) + "   超过最小或最大行数提示函数:" + operationType + "  "+ msg + "\r\n");
                    	$msg.scrollTop($msg[0].scrollHeight);
						return false; 
					},
					AddAfter: function (elem) { 
						$msg.val($msg.val() + (line++) + "   添加后事件:add" + "\r\n");
                    	$msg.scrollTop($msg[0].scrollHeight);
                    	console.log(elem);
					},
					DelAfter: function (elem) { 
						$msg.val($msg.val() + (line++) + "   删除后事件:del" + "\r\n");
                    	$msg.scrollTop($msg[0].scrollHeight);
                    	console.log(elem);
					}
				});
			});

如果您发现插件有什么bug或者能够完善的地方可以反馈给我,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值