当前仓库属于暂停状态,部分功能使用受限,详情请查阅 仓库状态说明
44 Star 292 Fork 78

sakuya / LayUi组件:TableSelect
暂停

 / 详情

搜索后选中状态异常的解决方案

待办的
创建于  
2020-01-03 16:16

您好,很感谢您提供TableSelect插件。
我在使用过程中发现了一些小问题,经过优化后成功修复了已知的BUG,并添加了一些有趣的功能
在此贴上修改后的代码,自作主张更新版本号为1.2.0。

layui.define(['table', 'jquery', 'form'], function (exports) {
    "use strict";

    var MOD_NAME = 'tableSelect',
        $ = layui.jquery,
        table = layui.table,
        form = layui.form;
    var tableSelect = function () {
        this.v = '1.2.0';
    };

    /**
    * 初始化表格选择器
    */
    tableSelect.prototype.render = function (opt) {
        var elem = $(opt.elem);
        var tableDone = opt.table.done || function(){};
		
        //默认设置
        opt.searchKey = opt.searchKey || 'keyword';
        opt.searchPlaceholder = opt.searchPlaceholder || '关键词搜索';
        // opt.checkedKey = opt.checkedKey;
        opt.table.page = opt.table.page || true;
        opt.table.height = opt.table.height || 315;

        // v1.2 - 1.新增search支持多条件搜索
        var search = opt.search;
        //.. v1.2 - search支持多条件搜索

        elem.off('click').on('click', function(e) {
            e.stopPropagation();

            if($('div.tableSelect').length >= 1){
                return false;
            }

            var t = elem.offset().top + elem.outerHeight()+"px";
            var l = elem.offset().left +"px";
            var tableName = "tableSelect_table_" + new Date().getTime();
            var tableBox = '<div class="tableSelect layui-anim layui-anim-upbit" style="left:'+l+';top:'+t+';border: 1px solid #d2d2d2;background-color: #fff;box-shadow: 0 2px 4px rgba(0,0,0,.12);padding:10px 10px 0 10px;position: absolute;z-index:66666666;margin: 5px 0;border-radius: 2px;min-width:530px;">';
                tableBox += '<div class="tableSelectBar">';
                tableBox += '<form class="layui-form" action="" style="display:inline-block;">';

            // v1.2 - search支持多条件搜索
            if (search) {
                var arr = [];
                search.forEach(function (item, index) {
                    if (item.type === 'text') {
                        arr.push('<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:2px;border: 1px solid #C9C9C9;" type="text" name="'+item.key+'" placeholder="'+item.placeholder+'" autocomplete="off" class="layui-input">')
                    } else if (item.type === 'select') {
                        arr.push('<select style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:2px;border: 1px solid #C9C9C9;" type="text" name="'+item.key+'">')
                        arr.push(' <option value="">'+ item.placeholder +':全部</option>');
                        if (item.data) {
                            item.data.forEach(function (x, j) {
                                arr.push('<option value="'+ x.key +'">'+ x.value +'</option>');
                            });
                        }
                        arr.push('</select>');
                    }
                });
                tableBox += arr.join('');
            } else {
                tableBox += '<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:-1px;border: 1px solid #C9C9C9;" type="text" name="'+opt.searchKey+'" placeholder="'+opt.searchPlaceholder+'" autocomplete="off" class="layui-input">'
            }
            //.. v1.2 - search支持多条件搜索

                tableBox += '<button class="layui-btn layui-btn-sm layui-btn-primary tableSelect_btn_search" lay-submit lay-filter="tableSelect_btn_search"><i class="layui-icon layui-icon-search"></i></button>';
                tableBox += '</form>';
                tableBox += '<button style="float:right;" class="layui-btn layui-btn-sm tableSelect_btn_select">选择<span></span></button>';
                tableBox += '<button style="float:right;margin-right: 6px;" class="layui-btn layui-btn-primary layui-btn-sm tableSelect_btn_clear">清空<span></span></button>';
                tableBox += '</div>';
                tableBox += '<table id="'+tableName+'" lay-filter="'+tableName+'"></table>';
                tableBox += '</div>';
                tableBox = $(tableBox);
            $('body').append(tableBox);
            
            //数据缓存
            var checkedKeyData = [], pageData = [], firstLoad = true;

            //渲染TABLE
            opt.table.elem = "#"+tableName;
            opt.table.id = tableName;
            opt.table.done = function(res, curr, count){
                defaultChecked(res, curr, count);
                setChecked(res, curr, count);
                tableDone(res, curr, count);
            };
            var tableSelect_table = table.render(opt.table);

            //分页选中保存数组
            table.on('radio('+tableName+')', function(obj){
                if(opt.checkedKey){
                    checkedKeyData = table.checkStatus(tableName).data[opt.checkedKey]
                }
                updateButton(table.checkStatus(tableName).data.length)
            })
			table.on('checkbox('+tableName+')', function(obj){
                if(opt.checkedKey){
                    // 全选
                    if(obj.type === 'all'){
                        if (obj.checked) {
                            pageData.forEach(function (x, i) {
                                checkedKeyData.push(x + '')
                            });
                        } else {
                            pageData.forEach(function (x, i) {
                                checkedKeyData.forEach(function (y, j) {
                                    if(y == x){
                                        checkedKeyData.splice(j,1)
                                    }
                                })

                            });
                        }

                    // 单选
                    }else{
                        if(obj.checked){
                            checkedKeyData.push(obj.data[opt.checkedKey] + '')
                        } else {
                            checkedKeyData.forEach(function (y, j) {
                                if(obj.data[opt.checkedKey] == y){
                                    checkedKeyData.splice(j,1)
                                }
                            });
                        }
                    }

                    checkedKeyData = uniqueObjArray(checkedKeyData);

                    // elem.attr('ts-selected', checkedKeyData.join(','));

                    updateButton(checkedKeyData.length)
                }else{
                    updateButton(table.checkStatus(tableName).data.length)
                }
            });

            //渲染表格后选中
            function setChecked (res, curr, count) {
                var list = res.data;
				for(var i=0;i<list.length;i++){
            		for (var j=0;j<checkedKeyData.length;j++) {
            			if(list[i][opt.checkedKey] == checkedKeyData[j]){
                            list[i].LAY_CHECKED = true;
                            var index= list[i]['LAY_TABLE_INDEX'];
                            var checkbox = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="checkbox"]');
            				    checkbox.prop('checked', true).next().addClass('layui-form-checked');
                            var radio  = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="radio"]');
                                radio.prop('checked', true).next().addClass('layui-form-radioed').find("i").html('&#xe643;');
            			}
            		}
            	}
            	var checkStatus = table.checkStatus(tableName);
				if(checkStatus.isAll){
					$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').prop('checked', true);
					$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').next().addClass('layui-form-checked');
				}
				updateButton(checkedKeyData.length)
            }
            
            //写入默认选中值(puash checkedKeyData)
            function defaultChecked (res, curr, count) {

                if (firstLoad) {
                    var selected = elem.attr('ts-selected');
                    if(opt.checkedKey && selected){
                        var selected = selected.split(",");
                        checkedKeyData = selected;
                    }
                    firstLoad = false;
                }

                pageData = [];
                res.data.forEach(function (x, i) {
                    pageData.push(x[opt.checkedKey])
                });
            }

			//更新选中数量
			function updateButton (n) {
				tableBox.find('.tableSelect_btn_select span').html(n==0?'':'('+n+')')
            }
            
            //数组去重
			function uniqueObjArray(arr, type){
                var newArr = [];
                var tArr = [];
                if(arr.length == 0){
                    return arr;
                }else{
                    if(type){
                        for(var i=0;i<arr.length;i++){
                            if(!tArr[arr[i][type]]){
                                newArr.push(arr[i]);
                                tArr[arr[i][type]] = true;
                            }
                        }
                        return newArr;
                    }else{
                        for(var i=0;i<arr.length;i++){
                            if(!tArr[arr[i]]){
                                newArr.push(arr[i]);
                                tArr[arr[i]] = true;
                            }
                        }
                        return newArr;
                    }
                }
            }

			//FIX位置
			var overHeight = (elem.offset().top + elem.outerHeight() + tableBox.outerHeight() - $(window).scrollTop()) > $(window).height();
			var overWidth = (elem.offset().left + tableBox.outerWidth()) > $(window).width();
			    overHeight && tableBox.css({'top':'auto','bottom':'0px'});
			    overWidth && tableBox.css({'left':'auto','right':'5px'})
			
            //关键词搜索
            form.on('submit(tableSelect_btn_search)', function(data){
                tableSelect_table.reload({
                    where: data.field,
                    page: {
                      curr: 1
                    }
                });
                return false;
            });

            //双击行选中
            table.on('rowDouble('+tableName+')', function(obj) {
                var checkStatus = {data:[obj.data]};
                selectDone(checkStatus);
            });

            //按钮选中
            tableBox.find('.tableSelect_btn_select').on('click', function() {
                selectDone(checkedKeyData);
            });

            // 清空
            tableBox.find('.tableSelect_btn_clear').on('click', function () {
                checkedKeyData = [];
                updateButton(0);
                tableSelect_table.reload();
            });

            //写值回调和关闭
            function selectDone (checkedData){
                elem.attr("ts-selected",checkedData.join(","));
                opt.done(elem, checkedData);
                tableBox.remove();
                checkedKeyData = [];
            }
            
            //点击其他区域关闭
            $(document).mouseup(function(e){
                var userSet_con = $(''+opt.elem+',.tableSelect');
                if(!userSet_con.is(e.target) && userSet_con.has(e.target).length === 0){
                    tableBox.remove();
                    checkedKeyData = [];
                }
            });


        })
    }

    /**
    * 隐藏选择器
    */
    tableSelect.prototype.hide = function (opt) {
        $('.tableSelect').remove();
    }

    //自动完成渲染
    var tableSelect = new tableSelect();

    //FIX 滚动时错位
    if(window.top == window.self){
        $(window).scroll(function () {
            tableSelect.hide();
        });
    }

    exports(MOD_NAME, tableSelect);
})

评论 (5)

wujiawei0926 创建了任务
  1. render()函数添加配置search
search: [
    {type: 'text', key: 'title', placeholder: '标题'},
    {type: 'select', key: 'type_id', placeholder: '分类',
        data: [
            {key: '1', value: '动漫'},
            {key: '2', value: '电影'},
            {key: '3', value: '电视剧'},
        ]
    }
],

目前type仅支持text(文本框)和select(下拉选择框),select需要与data配置结合使用,data为下拉框中显示的数据

  1. done()回调修改为elemdataelem与原来一致,data调整为选中数据的checkedKey数组

哥 可以把选中的值整个返回吗?
不只返回 checkedKey的值

您受累再优化一下。。

layui.define(['table', 'jquery', 'form'], function (exports) {
"use strict";

var MOD_NAME = 'tableSelect',
    //$ = layui.jquery,
    table = layui.table,
    form = layui.form;
var tableSelect = function () {
    this.v = '1.2.0';
};

/**
* 初始化表格选择器
*/
tableSelect.prototype.render = function (opt) {
    var elem = $(opt.elem);
    var tableDone = opt.table.done || function(){};
	
	var url = opt.url;
    //默认设置
    opt.searchKey = opt.searchKey || 'keyword';
    opt.searchPlaceholder = opt.searchPlaceholder || '关键词搜索';
    // opt.checkedKey = opt.checkedKey;
    opt.table.page = opt.table.page || true;
    opt.table.height = opt.table.height || 315;

    // v1.2 - 1.新增search支持多条件搜索
    var search = opt.search;
    //.. v1.2 - search支持多条件搜索

    elem.off('click').on('click', function(e) {
        e.stopPropagation();

        if($('div.tableSelect').length >= 1){
            return false;
        }

        var t = elem.offset().top + elem.outerHeight()+"px";
        var l = elem.offset().left +"px";
        var tableName = "tableSelect_table_" + new Date().getTime();
        var tableBox = '<div class="tableSelect layui-anim layui-anim-upbit" style="left:'+l+';top:'+t+';border: 1px solid #d2d2d2;background-color: #fff;box-shadow: 0 2px 4px rgba(0,0,0,.12);padding:10px 10px 0 10px;position: absolute;z-index:66666666;margin: 5px 0;border-radius: 2px;min-width:530px;">';
            tableBox += '<div class="tableSelectBar">';
            tableBox += '<form class="layui-form" action="" style="display:inline-block;">';

        // v1.2 - search支持多条件搜索
        if (search) {
            var arr = [];
            search.forEach(function (item, index) {
                if (item.type === 'text') {
                    arr.push('<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:2px;border: 1px solid #C9C9C9;" type="text" name="'+item.key+'" placeholder="'+item.placeholder+'" autocomplete="off" class="layui-input">')
                } else if (item.type === 'select') {
                    arr.push('<select style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:2px;border: 1px solid #C9C9C9;" type="text" name="'+item.key+'">')
                    arr.push(' <option value="">'+ item.placeholder +':全部</option>');
                    if (item.data) {
                        item.data.forEach(function (x, j) {
                            arr.push('<option value="'+ x.key +'">'+ x.value +'</option>');
                        });
                    }
                    arr.push('</select>');
                }
            });
            tableBox += arr.join('');
        } else {
            tableBox += '<input style="display:inline-block;width:190px;height:30px;vertical-align:middle;margin-right:-1px;border: 1px solid #C9C9C9;" type="text" name="'+opt.searchKey+'" placeholder="'+opt.searchPlaceholder+'" autocomplete="off" class="layui-input">'
        }
        //.. v1.2 - search支持多条件搜索

            tableBox += '<button class="layui-btn layui-btn-sm layui-btn-primary tableSelect_btn_search" lay-submit lay-filter="tableSelect_btn_search"><i class="layui-icon layui-icon-search"></i></button>';
            tableBox += '</form>';
            tableBox += '<button style="float:right;" class="layui-btn layui-btn-sm tableSelect_btn_select">选择<span></span></button>';
            tableBox += '<button style="float:right;margin-right: 6px;" class="layui-btn layui-btn-primary layui-btn-sm tableSelect_btn_clear">清空<span></span></button>';
            tableBox += '</div>';
            tableBox += '<table id="'+tableName+'" lay-filter="'+tableName+'"></table>';
            tableBox += '</div>';
            tableBox = $(tableBox);
        $('body').append(tableBox);
        
        //	1.2.1 数据缓存
        var checkedData = [] ,pageData = [], firstLoad = true ;
        
        //渲染TABLE
        opt.table.elem = "#"+tableName;
        opt.table.id = tableName;
        opt.table.done = function(res, curr, count){           	
        	defaultChecked(res, curr, count);            	
            setChecked(res, curr, count);
            tableDone(res, curr, count);
        };
        var tableSelect_table = table.render(opt.table);

        //分页选中保存数组
        //单选框
        table.on('radio('+tableName+')', function(obj){
            if(opt.checkedKey){
                //checkedKeyData = table.checkStatus(tableName).data[opt.checkedKey]
            	checkedData = table.checkStatus(tableName).data
            }
            updateButton(table.checkStatus(tableName).data.length)
        })
        //多选框
		table.on('checkbox('+tableName+')', function(obj){
            if(opt.checkedKey){
                // 全选
                if(obj.type === 'all'){
                    if (obj.checked) {
                    	//function(index,item)  index表示当前对象      item代表当前循环的数组下标,
                        pageData.forEach(function (item, index) {
                        	//该push()方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
                            //checkedKeyData.push(x + '')
                        	checkedData.push(item)
                        });
                    } else {
                        pageData.forEach(function (x, i) {
                           // checkedKeyData.forEach(function (y, j) {
                        	checkedData.forEach(function (y, j) {
                                if(y[opt.checkedKey] == x[opt.checkedKey]){
                                	//该splice()方法通过删除或替换现有元素和/或在适当位置添加新元素来更改数组的内容。
                                	//从索引3移除1个元素  :  myFish.splice(3, 1)
                                	checkedData.splice(j,1)
                                }
                            })

                        });
                    }

                // 单选
                }else{
                    if(obj.checked){
                    	var lista = obj.data;
                    	checkedData.push(lista);
                    } else {
                    	checkedData.forEach(function (y, j) {
                            if(obj.data[opt.checkedKey] == y[opt.checkedKey]){
                            	checkedData.splice(j,1)
                            }
                        });
                    }
                }
                checkedData = uniqueObjArray(checkedData);
                updateButton(checkedData.length)
            }else{
                updateButton(table.checkStatus(tableName).data.length)
            }
        });

        //渲染表格后选中
        function setChecked (res, curr, count) {
            var list = res.data;
			for(var i=0;i<list.length;i++){
        		for (var j=0;j<checkedData.length;j++) {
        			if(list[i][opt.checkedKey] == checkedData[j][opt.checkedKey]){
                        list[i].LAY_CHECKED = true;
                        var index= list[i]['LAY_TABLE_INDEX'];
                        var checkbox = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="checkbox"]');
        				    checkbox.prop('checked', true).next().addClass('layui-form-checked');
                        var radio  = $('#'+tableName+'').next().find('tr[data-index=' + index + '] input[type="radio"]');
                            radio.prop('checked', true).next().addClass('layui-form-radioed').find("i").html('&#xe643;');
        			}
        		}
        	}
        	var checkStatus = table.checkStatus(tableName);
			if(checkStatus.isAll){
				$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').prop('checked', true);
				$('#'+tableName+'').next().find('.layui-table-header th[data-field="0"] input[type="checkbox"]').next().addClass('layui-form-checked');
			}
			updateButton(checkedData.length)
        }
        
        //写入默认选中值(puash checkedKeyData)
        function defaultChecked (res, curr, count) {   
            if (firstLoad) {
                var selectedlist = elem.attr('ts-selected').split(",");
                var valuelist = elem.val().split(",");               
                if(opt.checkedKey && selectedlist && opt.showKey && valuelist){
                    var checkedKeyOfListKey = opt.checkedKey;
                    var showKeyOfListKey = opt.showKey;
                	selectedlist.forEach(function (y, j){
                        var setlist = {};
                		setlist[checkedKeyOfListKey] = y;
                		setlist[showKeyOfListKey] = valuelist[j];
                		checkedData.push(setlist);
                	});
                }
                firstLoad = false;    
            }
            pageData = [];
            res.data.forEach(function (x, i) {
                pageData.push(x[opt.checkedKey])
            });
        }

		//更新选中数量
		function updateButton (n) {
			tableBox.find('.tableSelect_btn_select span').html(n==0?'':'('+n+')')
        }
        
        //数组去重
		function uniqueObjArray(arr, type){
            var newArr = [];
            var tArr = [];
            if(Array.isArray(arr) && arr.length == 0){
                return arr;
            }else{
                if(type){
                    for(var i=0;i<arr.length;i++){
                        if(!tArr[arr[i][type][opt.checkedKey]]){
                            newArr.push(arr[i]);
                            tArr[arr[i][type]] = true;
                        }
                    }
                    return newArr;
                }else{
                    for(var i=0;i<arr.length;i++){
                        if(!tArr[arr[i][opt.checkedKey]]){
                            newArr.push(arr[i]);
                            tArr[arr[i][opt.checkedKey]] = true;
                        }
                    }
                   return newArr;
                }
            }
        }

		//FIX位置
		var overHeight = (elem.offset().top + elem.outerHeight() + tableBox.outerHeight() - $(window).scrollTop()) > $(window).height();
		var overWidth = (elem.offset().left + tableBox.outerWidth()) > $(window).width();
		    overHeight && tableBox.css({'top':'auto','bottom':'0px'});
		    overWidth && tableBox.css({'left':'auto','right':'5px'})
		
        //关键词搜索
        form.on('submit(tableSelect_btn_search)', function(data){
            tableSelect_table.reload({
                where: data.field,
                page: {
                  curr: 1
                }
            });
            return false;
        });

        //双击行选中
        table.on('rowDouble('+tableName+')', function(obj) {         	
        	for (var key in obj.data) {
        	    //console.log(obj.data[key])
        		if(typeof(obj.data[key])!='string' ){
        			obj.data[key] = obj.data[key]+"";
        		}
        	}
            selectDone(checkedData.concat(obj.data));
        });
        //按钮选中
        tableBox.find('.tableSelect_btn_select').on('click', function() {
            selectDone(checkedData);
        });

        // 清空
        tableBox.find('.tableSelect_btn_clear').on('click', function () {
        	checkedData = [];
            updateButton(0);
            tableSelect_table.reload();
        });

        //写值回调和关闭
        function selectDone (checkedData){
        	var returnString ="";
        	if(!(checkedData.length==0)){
        		returnString = checkedData[0][opt.checkedKey]+",";
            	for(var i=1;i<checkedData.length-1;i++){
            		returnString = returnString+" " + checkedData[i][opt.checkedKey] + ","; 	
            	}
            	returnString = returnString +" "+ checkedData[checkedData.length-1][opt.checkedKey]                 
        	}
            elem.attr('ts-selected',returnString);
            opt.done(elem, checkedData);
            tableBox.remove();
            checkedData = [];
        }           
        //点击其他区域关闭
        $(document).mouseup(function(e){
            var userSet_con = $(''+opt.elem+',.tableSelect');
            if(!userSet_con.is(e.target) && userSet_con.has(e.target).length === 0){
                tableBox.remove();
                checkedData = [];
            }
        });
    })
}
/**
* 隐藏选择器
*/
tableSelect.prototype.hide = function (opt) {
    $('.tableSelect').remove();
}

//自动完成渲染
var tableSelect = new tableSelect();

//FIX 滚动时错位
if(window.top == window.self){
    $(window).scroll(function () {
        tableSelect.hide();
    });
}

exports(MOD_NAME, tableSelect);

})

我修改了下 传回的数组为所需要的元素 然后修复了双击行选中的bug

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(2)
1157021 wujiawei0926 1578943322
JavaScript
1
https://gitee.com/lolicode/layui_component_tableselect.git
git@gitee.com:lolicode/layui_component_tableselect.git
lolicode
layui_component_tableselect
LayUi组件:TableSelect

搜索帮助