Bläddra i källkod

table列表下拉框js文件

user5 4 år sedan
förälder
incheckning
b718e5839a
1 ändrade filer med 466 tillägg och 0 borttagningar
  1. 466 0
      src/main/webapp/static/kindeditor/plugins/tableEdit/tableEdit.js

+ 466 - 0
src/main/webapp/static/kindeditor/plugins/tableEdit/tableEdit.js

@@ -0,0 +1,466 @@
+layui.define(["laydate","laytpl","table","layer"],function(exports) {
+    "use strict";
+    var moduleName = 'tableEdit',_layui = layui,laytpl = _layui.laytpl
+        ,$ = _layui.$,laydate = _layui.laydate,table = _layui.table,layer = _layui.layer
+        ,selectTpl = [ //单选下拉框模板
+            '<div class="layui-tableEdit-div" style="{{d.style}}">'
+                ,'<ul class="layui-tableEdit-ul">'
+                    ,'{{# if(d.data){ }}'
+                        ,'{{# d.data.forEach(function(item){ }}'
+                            ,'{{# var selectedClass = d.callbackFn(item) }}'
+                            ,'<li class="{{ selectedClass }}" data-name="{{ item.name }}" data-value="{{ item.value }}">'
+                                ,'<div class="layui-unselect layui-form-checkbox" lay-skin="primary"><span>{{ item.value }}</span></div>'
+                            ,'</li>'
+                        ,'{{# }); }}'
+                        ,'{{# } else { }}'
+                            ,'<li>无数据</li>'
+                    ,'{{# } }}'
+                ,'</ul>'
+            , '</div>'
+        ].join('')
+        ,selectMoreTpl = [ //多选下拉框模板
+            '<div class="layui-tableEdit-div" style="{{d.style}}">'
+                ,'<div class="layui-tableEdit-tpl">'
+                    ,'<ul>'
+                    ,'{{# if(d.data){ }}'
+                        ,'{{# d.data.forEach(function(item){ }}'
+                            ,'{{# var selectedClass = d.callbackFn(item) }}'
+                            ,'<li class="{{ selectedClass }}" data-name="{{ item.name }}" data-value="{{ item.value }}">'
+                                ,'<div class="layui-unselect layui-form-checkbox" lay-skin="primary"><span>{{ item.value }}</span><i class="layui-icon layui-icon-ok"></i></div>'
+                            ,'</li>'
+                        ,'{{# }); }}'
+                    ,'{{# } else { }}'
+                        ,'<li>无数据</li>'
+                    ,'{{# } }}'
+                    ,'</ul>'
+                ,'</div>'
+                ,'<div style="line-height: 36px;">'
+                    ,'<div style="float: left">'
+                        ,'<button type="button" event-type="close" class="layui-btn layui-btn-sm layui-btn-primary">关闭</button>'
+                    ,'</div>'
+                    ,'<div style="text-align: right">'
+                        ,'<button event-type="confirm" type="button" class="layui-btn layui-btn-sm layui-btn-primary">确定</button>'
+                    ,'</div>'
+                ,'</div>'
+            ,'</div>'
+        ].join('');
+    //组件用到的css样式
+    var thisCss = [];
+    thisCss.push('.layui-tableEdit-div{position:absolute;background-color:#fff;font-size:14px;border:1px solid #d2d2d2;z-index:19910908445;max-height: 252px;}');
+    thisCss.push('.layui-tableEdit-tpl{max-height:216px;overflow-y:auto;}');
+    thisCss.push('.layui-tableEdit-div li{line-height:36px;padding-left:5px;}');
+    thisCss.push('.layui-tableEdit-div li:hover{background-color:#f2f2f2;}');
+    thisCss.push('.layui-tableEdit-selected{background-color:#5FB878;}');
+    thisCss.push('.layui-tableEdit-checked i{background-color:#60b979!important;}');
+    thisCss.push('.layui-tableEdit-ul div{padding-left:0px!important;}');
+    thisCss.push('.layui-tableEdit-input{text-align:center;position:absolute;left:0;bottom:0;width:100%;height:38px;z-index: 19910908;}');
+    thisCss.push('.layui-tableEdit-add{position: absolute;right: 3px;top: 21px;margin-top: -15px;z-index: 199109084;}')
+    thisCss.push('.layui-tableEdit-sub{position: absolute;left: 3px;top: 21px;margin-top: -15px;z-index: 199109084;}')
+    var thisStyle = document.createElement('style');
+    thisStyle.innerHTML = thisCss.join('\n'),document.getElementsByTagName('head')[0].appendChild(thisStyle);
+
+    var configs = {
+        callbacks:{}
+        ,
+        verify: {
+            required: [
+                /[\S]+/
+                ,'必填项不能为空'
+            ]
+            ,phone: [
+                /^1[34578]\d{9}$/
+                ,'请输入正确的手机号'
+            ]
+            ,email: [
+                /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/
+                ,'邮箱格式不正确'
+            ]
+            ,url: [
+                /(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/
+                ,'链接格式不正确'
+            ]
+            ,number:[
+                /(^[-+]?\d+$)|(^[-+]?\d+\.\d+$)/
+                ,'只能填写数字'
+            ]
+            ,date: [
+                /^(\d{4})[-\/](\d{1}|0\d{1}|1[0-2])([-\/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/
+                ,'日期格式不正确'
+            ]
+            ,identity: [
+                /(^\d{15}$)|(^\d{17}(x|X|\d)$)/
+                ,'请输入正确的身份证号'
+            ]
+        }
+    };
+
+    var Class = function () { //单列模式  也就是只能new一个对象。
+        var instance;
+        Class = function Class() {
+            return instance;
+        };
+        Class.prototype = this; //保留原型属性
+        instance = new Class();
+        instance.constructor = Class; //重置构造函数指针
+        return instance
+    }; //构造器
+    var singleInstance = new Class();
+    var inFunc = function () {singleInstance.leaveStat = false;},outFunc = function () {singleInstance.leaveStat = true;};
+    document.onclick = function () {if(singleInstance.leaveStat)singleInstance.deleteAll();};
+
+    //日期选择框
+    Class.prototype.date = function(options){
+        var othis = this;
+        othis.callback = options.callback,othis.element = options.element,othis.dateType = options.dateType;
+        othis.dateType = othis.isEmpty(othis.dateType) ? "datetime":othis.dateType;
+        var that = options.element;
+        if ($(that).find('input').length>0)return;
+        othis.deleteAll(),othis.leaveStat = false;
+        var input = $('<input class="layui-input layui-tableEdit-input" type="text">');
+        (39 - that.offsetHeight > 3) && input.css('height','30px');
+        (that.offsetHeight - 39 > 3) && input.css('height','50px');
+        $(that).append(input),input.focus();
+        //日期时间选择器 (show: true 表示直接显示)
+        laydate.render({elem: input[0],type: othis.dateType,show: true,done:function (value, date) {
+            othis.deleteAll();
+            if(othis.callback)othis.callback.call(that,value);
+        }});
+        $('div.layui-laydate').hover(inFunc,outFunc),$(that).hover(inFunc,outFunc);
+        _layui.stope();
+    };
+
+    //输入框
+    Class.prototype.input = function(options){
+        var othis = this;
+        othis.callback = options.callback,othis.element = options.element;
+        othis.oldValue = options.oldValue;
+        othis.oldValue = othis.oldValue ? othis.oldValue : '';
+        var that = options.element;
+        if ($(that).find('input').length>0)return;
+        othis.deleteAll(),othis.leaveStat = false;
+        var input = $('<input class="layui-input layui-tableEdit-input" style="z-index: 99999999999"  type="text">');
+        (39 - that.offsetHeight > 3) && input.css('height','30px');
+        (that.offsetHeight - 39 > 3) && input.css('height','50px');
+        input.val(othis.oldValue);
+        $(that).append(input),input.focus();
+        input.click(function (e) {
+            _layui.stope(e);
+        });
+        input.bind('change', function(e){othis.callback.call(othis.element,this.value)});
+        $(that).hover(inFunc,outFunc);
+        _layui.stope();
+    };
+
+    //带加号和减号的输入框(只支持输入数字)
+    Class.prototype.signedInput = function(options){
+        var othis = this;
+        othis.callback = options.callback,othis.element = options.element;
+        othis.oldValue = options.oldValue;
+        othis.oldValue = othis.oldValue ? othis.oldValue : '';
+        var that = options.element;
+        if ($(that).find('input').length>0)return;
+        othis.deleteAll(),othis.leaveStat = false;
+        var thisWidth = that.offsetWidth-49;
+        var input = $('<input class="layui-input layui-tableEdit-input" style="left: 24px;width: '+thisWidth+'px" type="text">');//
+        var leftBtn = $('<button type="button" class="layui-btn layui-btn-sm layui-tableEdit-sub"><i class="layui-icon layui-icon-subtraction" style="margin-top:-14px!important;position: absolute;left:2px!important"></i></button>');
+        var rightBtn = $('<button type="button" class="layui-btn layui-btn-sm layui-tableEdit-add"><i class="layui-icon layui-icon-addition" style="margin-top:-14px!important;position: absolute;right:-1px!important"></i></button>');
+        if(39 - that.offsetHeight > 3){
+            input.css('height','30px');leftBtn.css('top','16px');rightBtn.css('top','16px');
+        }
+        if(that.offsetHeight - 39 > 3){
+            input.css('height','50px');leftBtn.css('top','25px');rightBtn.css('top','25px');
+        }
+        input.val(othis.oldValue);
+        $(that).append(leftBtn);leftBtn.find('i').html('');
+        $(that).append(input),input.focus();$(that).append(rightBtn);rightBtn.find('i').html('');
+        input.click(function (e) {
+            _layui.stope(e);
+        });
+        input.bind('change', function(e){othis.callback.call(othis.element,this.value)});
+        $(that).hover(inFunc,outFunc);
+        _layui.stope();
+        $(that).find('button.layui-tableEdit-sub,button.layui-tableEdit-add').bind('click',function () {
+            var input = $(that).find('input.layui-tableEdit-input');
+            var val = input.val();
+            if(!val || val.length<=0)val=0;
+            val = parseInt(val);
+            if($(this).hasClass('layui-tableEdit-add')){
+                ++val;input.val(val);
+                othis.callback.call(othis.element,val)
+            }else{
+                --val;input.val(val);
+                othis.callback.call(othis.element,val)
+            }
+        })
+    };
+
+    //判断是否为空函数
+    Class.prototype.isEmpty = function(dataStr){return typeof dataStr === 'undefined' || dataStr === null || dataStr.length <= 0;};
+
+    //生成下拉框函数入口
+    Class.prototype.register = function(options){
+        var othis = this;
+        othis.enabled = options.enabled,othis.callback = options.callback;
+        othis.data = options.data,othis.element = options.element;
+        othis.selectedData = options.selectedData;
+        var that = othis.element;
+        if($(that).find('input.layui-tableEdit-input')[0]) return;
+        othis.deleteAll(),othis.leaveStat = false;
+        var input = $('<input class="layui-input layui-tableEdit-input" placeholder="请选择">')
+            ,tableEdit = $('<div class="layui-tableEdit"></div>')
+            ,tableBody = $(that).parents('div.layui-table-body')
+            ,tablePage = $(that).parents('div.layui-table-box').eq(0).next();
+        (39 - that.offsetHeight > 3) && input.css('height','30px');
+        (that.offsetHeight - 39 > 3) && input.css('height','50px');
+        tableEdit.append(input),$(that).append(tableEdit),input.focus();
+        var thisY = input[0].getBoundingClientRect().top //输入框y坐标
+            ,thisHeight = ((39 - that.offsetHeight > 3) ? 30 : input[0].offsetHeight) //输入框高度
+            ,thisHeight = ((that.offsetHeight - 39 > 3) ? 50 :thisHeight)
+            ,thisWidth = input[0].offsetWidth //输入框宽度
+            ,elemY = that.getBoundingClientRect().top //输入框y坐标
+            ,tableBodyY = tableBody[0].getBoundingClientRect().top
+            ,pageY = tablePage[0].getBoundingClientRect().top
+            ,tableBodyHeight = tableBody.height() //表格高度
+            ,isType = thisY-tableBodyY > 0.8*tableBodyHeight
+            ,type = isType ? 'top: auto;bottom: '+(thisHeight+2)+'px;' : 'bottom: auto;top: '+(thisHeight+2)+'px;';
+        if(elemY<tableBodyY)tableBody[0].scrollTop = that.offsetTop; //调整滚动条位置
+        var style = type+'width: '+thisWidth+'px;left: 0px;'+(othis.enabled ? '':'overflow-y: auto;');
+        var getClassFn = function(item){
+            if(othis.isEmpty(othis.selectedData) || othis.isEmpty(item.name))return "";
+            var selectedClass;
+            if(typeof othis.selectedData === 'string' || Object.prototype.toString.call(othis.selectedData) === '[object Number]'){
+                selectedClass = (item.name+"" === othis.selectedData+"") || (item.value+"" === othis.selectedData+"") ? "layui-tableEdit-selected"+(othis.enabled ? " layui-tableEdit-checked":'') : "";
+            }
+            if(typeof othis.selectedData === 'object'){
+                selectedClass = (item.name+"" === othis.selectedData.name+"") ? "layui-tableEdit-selected"+(othis.enabled ? " layui-tableEdit-checked":'') : "";
+            }
+            if(Array.isArray(othis.selectedData)){
+                for(var i=0;i<othis.selectedData.length;i++){
+                    selectedClass = (item.name+"" === othis.selectedData[i].name+"") ? "layui-tableEdit-selected layui-tableEdit-checked" : "";
+                    if(!othis.isEmpty(selectedClass)) break;
+                }
+            }
+            return selectedClass;
+        };
+        tableEdit.append(laytpl(othis.enabled ? selectMoreTpl : selectTpl).render({data: othis.data,style: style,callbackFn:getClassFn}));
+        var $tableEdit = $('div.layui-tableEdit-div')[0];
+        (thisY+$tableEdit.offsetHeight+thisHeight > pageY) && !isType && (tableBody[0].scrollTop = that.offsetTop);//调整滚动条位置
+        othis.events();
+    };
+
+    //删除所有下拉框和时间选择框
+    Class.prototype.deleteAll = function(){
+        $('div.layui-tableEdit-div,div.layui-tableEdit,div.layui-laydate,input.layui-tableEdit-input,button.layui-tableEdit-sub,button.layui-tableEdit-add').remove();
+        delete this.leaveStat;//清除(离开状态属性)
+    };
+
+    //注册事件
+    Class.prototype.events = function(){
+        var othis = this;
+        var searchFunc = function(val){ //关键字搜索
+            $('div.layui-tableEdit-div li').each(function () {
+                othis.isEmpty(val) || $(this).data('value').indexOf(val) > -1 ? $(this).show() : $(this).hide();
+            });
+        },liClickFunc = function(){ //给li元素注册点击事件
+            var liArr = $('div.layui-tableEdit-div li');
+            liArr.unbind('click'),liArr.bind('click',function (e) {
+                _layui.stope(e);
+                if(othis.enabled){//多选
+                    $(this).hasClass("layui-tableEdit-checked") ? ($(this).removeClass("layui-tableEdit-checked"),
+                          $(this).removeClass("layui-tableEdit-selected"))
+                        : $(this).addClass("layui-tableEdit-checked")
+                }else {//单选
+                    othis.deleteAll();
+                    if(othis.callback)othis.callback.call(othis.element,{name:$(this).data("name"),value:$(this).data("value")});
+                }
+            });
+        },btnClickFunc = function (){ //给button按钮注册点击事件
+            $("div.layui-tableEdit-div button").bind('click',function () {
+                var eventType = $(this).attr("event-type"), btn = this,dataList = new Array();
+                if(eventType === 'close') singleInstance.deleteAll(); //“关闭”按钮
+                if(eventType === 'confirm') { //“确定”按钮
+                    $('div.layui-tableEdit-div li').each(function (e) {
+                        if(!$(this).hasClass("layui-tableEdit-checked"))return;
+                        dataList.push({name:$(this).data("name"),value:$(this).data("value")});
+                    });
+                    othis.deleteAll();
+                    if(othis.callback)othis.callback.call(othis.element,dataList);
+                }
+            });
+        };
+        //事件注册
+        $(othis.element).find('input.layui-tableEdit-input').bind('input propertychange', function(){searchFunc(this.value)});
+        othis.enabled ? (liClickFunc(),btnClickFunc()) : liClickFunc();
+        $(othis.element).hover(inFunc,outFunc);
+    };
+
+    var AopEvent = function(cols){this.config = {colsConfig:{}};this.parseCols(cols)};//aop构造器
+    /**
+     * 解析出tableEdit组件所需要的配置信息
+     * @param cols
+     */
+    AopEvent.prototype.parseCols = function(cols){
+        var that = this;
+        cols.forEach(function (ite) {
+            ite.forEach(function (item) {
+                if(!item.config)return;
+                that.config.colsConfig[item.field] = item.config;
+            });
+        });
+    };
+    /**
+     * aop代理event
+     * @param event 事件名称
+     * @param callback 回调函数
+     */
+    AopEvent.prototype.on = function(event,callback){
+        var othis = this;othis.config.event = event,othis.config.callback = callback;
+        table.on(othis.config.event,function (obj) {
+            var zthis = this,field = $(zthis).data('field'),config = othis.config.colsConfig[field];
+            if(!config){
+                othis.config.callback.call(zthis,obj);return;
+            }
+            obj.field = field;
+            var callbackFn = function (res) {
+                if(config.verify && !othis.verify(res,config.verify,this))return; //验证为空
+                obj.value = Array.isArray(res) ? (res.length>0 ? res : [{name:'',value:''}]) : res;
+                othis.config.callback.call(zthis,obj);
+                if(!singleInstance.isEmpty(config.cascadeSelectField)){
+                    var csElement = $(this.parentNode).find("td[data-field='"+config.cascadeSelectField+"']");
+                    $(csElement).attr("cascadeSelect-data",JSON.stringify({data:res,field:field}));
+                }
+            };
+            var csd = $(this).attr("cascadeSelect-data");//联动数据
+            if(singleInstance.isEmpty(csd)){ //非联动事件
+                if(config.type === 'select'){
+                    singleInstance.register({data:config.data,element:zthis,enabled:config.enabled,selectedData:obj.data[field],callback:callbackFn});
+                }else if(config.type === 'date'){
+                    singleInstance.date({dateType:config.dateType,element:zthis,callback:callbackFn});
+                }else if(config.type === 'input'){
+                    singleInstance.input({element:zthis,oldValue:obj.data[field],callback:callbackFn});
+                }else if(config.type === 'signedInput'){
+                    singleInstance.signedInput({element:zthis,oldValue:obj.data[field],callback:callbackFn});
+                }else othis.config.callback.call(zthis,obj);
+            } else {//联动事件
+                if(config.type === 'date') return;
+                //获取当前单元格的table表格的lay-filter属性值
+                var filter = $(zthis).parents('div.layui-table-view').eq(0).prev().attr('lay-filter')
+                    ,rs = active.callbackFn.call(zthis,'clickBefore('+filter+')',JSON.parse(csd));
+                    //异步操作,由使用者调用。
+                    //判断条件为rs为空时。
+                    if(singleInstance.isEmpty(rs)){
+                        active.on("async("+filter+")",function (result) {
+                            singleInstance.register({data:result.data,element:zthis,enabled:result.enabled,selectedData:obj.data[field],callback:callbackFn});
+                        })
+                    }else {
+                        singleInstance.register({data:rs.data,element:zthis,enabled:rs.enabled,selectedData:obj.data[field],callback:callbackFn});
+                    }
+            }
+
+        });
+    };
+
+    /**
+     * 验证数据是否符合要求
+     * @param data 被验证数据
+     * @param verify 正则参数
+     * @param td 当前单元格
+     * @returns {boolean} true验证通过 false验证未通过
+     */
+    AopEvent.prototype.verify = function (data,verify,td) {
+        var verifyObj = configs.verify[verify.type];
+        var verifyMsg = verify.msg;
+        verifyMsg = verifyMsg ? verifyMsg : (verifyObj ? verifyObj[1] : '必填项不能为空');
+        if(singleInstance.isEmpty(data)){
+            layer.tips(verifyMsg, td,{tipsMore:true});
+            return false;
+        }
+        if(Array.isArray(data) && data.length <= 0){
+            layer.tips(verifyMsg, td,{tipsMore:true});
+            return false;
+        }
+        if((typeof data === 'object' && singleInstance.isEmpty(data.name))
+            || data.name === 'undefined'){
+            layer.tips(verifyMsg, td,{tipsMore:true});
+            return false;
+        }
+        if(!verifyObj && !verify.regx){
+            return true;
+        }
+        if(verify.regx){ //自定义正则判断
+            if(typeof verify.regx === "function"){//为函数时
+                if(verify.regx(data))return true;
+                layer.tips(verifyMsg, td,{tipsMore:true});
+                return false;
+            }
+            if(typeof verify.regx === "string"){ //为字符串正则时
+                var regx = new RegExp(verify.regx);
+                if(regx.test(data))return true;
+                layer.tips(verifyMsg, td,{tipsMore:true});
+                return false;
+            }
+            if(verify.regx.test(data))return true; //为正则时
+            layer.tips(verifyMsg, td,{tipsMore:true});
+            return false;
+        }
+        if(!verifyObj[0].test(data)){
+            layer.tips(verifyMsg, td,{tipsMore:true});
+            return false;
+        }
+        return true;
+    };
+
+    /**
+     * 提交数据的验证
+     * @param options {elem:'#test',data:[],verifyKey:'id'}
+     * elem: 表格id,带井号  data: 验证数据,数组类型。
+     * verifyKey: data中的元素的唯一值字段,且必须在表格中有此字段的单元格。
+     * @returns {*}
+     */
+    AopEvent.prototype.submitValidate = function (options) {
+        var that = this,failedTds = [];
+        if(!options || singleInstance.isEmpty(options.verifyKey)
+            || singleInstance.isEmpty(options.data)
+            || singleInstance.isEmpty(options.elem))return failedTds;
+        var body = $(options.elem).next().find('div.layui-table-box div.layui-table-body tr');
+        options.data.forEach(function (item) {
+            for(var field in item){
+                var config = that.config.colsConfig[field];
+                if(!config || !config.verify)continue;
+                var verify = config.verify;
+                var tds = body.find('td[data-field="'+options.verifyKey+'"]');
+                var thisTd;
+                tds.each(function () {
+                    var text = $(this).find('div.layui-table-cell').text();
+                    if(text+'' === item[options.verifyKey]+''){
+                        thisTd = $(this);
+                    }
+                });
+                if(!thisTd)continue;
+                var td = thisTd.parent().children('td[data-field="'+field+'"]');
+                if(!that.verify(item[field],verify,td))failedTds.push(td[0]);
+            }
+        });
+        return failedTds;
+    };
+
+    var active = {
+        aopObj:function(cols){return new AopEvent(cols);},
+        on:function (event,callback) {
+            var filter = event.match(/\((.*)\)$/),eventName = (filter ? (event.replace(filter[0],'')+'_'+ filter[1]) : event);
+            configs.callbacks[moduleName+'_'+eventName]=callback;
+        },
+        callbackFn:function (event,params) {
+            var filter = event.match(/\((.*)\)$/),eventName = (filter ? (event.replace(filter[0],'')+'_'+ filter[1]) : event);
+            var key = moduleName+'_'+eventName,func = configs.callbacks[key];
+            if(!func) return;
+            return func.call(this,params);
+        }
+    };
+
+    active.on("tableEdit(getEntity)",function () {
+        return singleInstance;
+    });
+
+    exports(moduleName, active);
+});