Jquery+layui的动态表单构建

页面代码


<meta charset="utf-8">
<style>
.upload_img_list {
    margin: 10px 0 0 0
}

.upload_img_list dd {
    position: relative;
    margin: 0 10px 10px 0;
    float: left;
    width: 92px;
}

.upload_img_list .operate {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1
}

.upload_img_list .operate i {
    cursor: pointer;
    background: #2F4056;
    padding: 2px;
    line-height: 15px;
    text-align: center;
    color: #fff;
    margin-left: 1px;
    float: left;
    filter: alpha(opacity = 80);
    -moz-opacity: .8;
    -khtml-opacity: .8;
    opacity: .8;
}

.upload_img_list dd .img {
    width: 92px;
    height: 92px;
}
</style>
<script src="/static/js/commonjs.js"></script>
    rel="stylesheet" type="text/css">
<div id="app" style="width: 980px">
    <form class="layui-form" action="" lay-filter="form">
        <div id="form"></div>
        <div class="layui-form-item">
            <div class="layui-input-block">
                <button class="layui-btn" lay-submit="" lay-filter="save">保存</button>
                <button type="button" οnclick="doclose()"
                    class="layui-btn layui-btn-primary">关闭</button>
            </div>
        </div>
    </form>
</div>
<script src="/static/js/form_create.js"></script>
<script>
    var model_name = "fd_estate";
    //排除项
    var exclude_table_col = [ "create_time", "update_time", "deleted",
            "create_by", "update_by" ];
    var pics = {};
    var must = []; //必填项
    var islimit = false;
    $(function() {
        layui
                .use(
                        [ 'form', 'upload', 'laydate' ],
                        function() {

                            var form = layui.form;
                            var upload = layui.upload;
                            var laydate = layui.laydate;

                           //数据源请求接口

                       $.get("http://127.0.0.1:8080/model/test",
                                            {
                                                model : model_name
                                            },
                                            function(data) {
                                                console.info(data)
                                                if (data.code == 0) {
                                                    var metadata = data.data.metadata;
                                                    console.log(metadata)
                                                    var cols = []

                                                    var fieldset = fd_title(data.data.title);
                                                    $("#app").prepend(fieldset);

                                                    for (var i = 0; i < metadata.length; i++) {
                                                        cols = cols
                                                                .concat(metadata[i].section.children)

                                                        var group = fd_group(metadata[i].section.label);
                                                        $("#form")
                                                                .append(group);

                                                        for (var cj = 0; cj < metadata[i].section.children.length; cj++) {

                                                            var child = metadata[i].section.children[cj];

                                                            if (child.inputType.vadidate.required) {
                                                                var item={
                                                                        key:child.column,
                                                                        value:child.label,
                                                                        type:child.inputType.type
                                                                };
                                                                
                                                                must.push(item);
                                                                console.log("必填项数组===",must)
                                                            }
                                                            if (exclude_table_col.indexOf(child.column) > -1) {
                                                                console.log("必填项数组===",child.column)
                                                                continue;
                                                            }

                                                            if (child.inputType.type == inputType.FD_TEXT) {
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var input = fd_input(child);
                                                                $("#form").children().last().append(input);

                                                            } else if (child.inputType.type == inputType.FD_AREATEXT) {
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var textarea = fd_textarea(child);
                                                                $("#form").children().last().append(textarea);

                                                            } else if (child.inputType.type == inputType.FD_DATE) {
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var time = fd_date(child);
                                                                $("#form").children().last().append(time);
                                                                fd_date_init(laydate,child);
                                                            } else if (child.inputType.type == inputType.FD_PIC) {
                                                                pics[child.column] = [];
                                                                
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var pic_view = fd_addpic(child);
                                                                $("#form").children().last().append(pic_view);
                                                                initpic(child,upload);

                                                            } else if (child.inputType.type == inputType.FD_NUMBER) {
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var number_txt = fd_number(child);
                                                                $("#form").children().last().append(number_txt);
                                                            } else if (child.inputType.type == inputType.FD_SELECT) {
                                                                var item=fd_item();
                                                                $("#form").append(item);
                                                                var select_txt = fd_select(child);
                                                                $("#form").children().last().append(select_txt);
                                                                form.render('select');
                                                            }
                                                        } }}  });

                            //监听提交
                            form.on('submit(save)', function(data) {
                                data.field.file = pics;
                                //校验必填项
                                for(var i=0;i<must.length;i++){
                                    if(must[i].type==inputType.FD_PIC){
                                        layer.msg("请填写"+data.field.file[must[i].key].length);
                                        if(data.field.file[must[i].key].length<=0){
                                            layer.msg("请上传"+must[i].value);
                                            return false;
                                        }
                                    }else{
                                        if(data.field[must[i].key]==''){
                                            layer.msg("请填写"+must[i].value);
                                            return false;
                                        }
                                    }
                                }
                                $.post("http://127.0.0.1:8080/model/test", {
                                    data : {
                                        model : model_name,
                                        data_json : data.field
                                    },
                                }, function(res) {
                                    alert("数据");
                                });
                                layer.msg(JSON.stringify(data.field));
                                return false;

                            });
                        });

    });

    function doclose() {
        alert("关闭窗口")
        parent.vm.iframeclose();
        var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引         
        parent.layer.close(index); //再执行关闭 
    }
</script>

每个标签的封装js


function fd_item(){
    var item_str="<div class='layui-form-item'></div>";
    return item_str;
}

function fd_input(child) {
    var required=child.inputType.vadidate.required;
    if (required) {
        required = "required";
    } else {
        required = "";
    }
    var input = "<label class='layui-form-label'>"
            + child.label
            + "</label><div class='layui-input-block'><input type='text'"
            + " id='" + child.column + "' " + "name='" + child.column + "' " + required
            + " placeholder='" + child.label
            + "' autocomplete='off' class='layui-input'></div>";
    return input;
}

function fd_number(child) {
    var required=child.inputType.vadidate.required;
    if (required) {
        required = "required";
    } else {
        required = "";
    }
    var input = "<label class='layui-form-label'>"
            + child.label
            + "</label><div class='layui-input-block'><input type='number' name='"
            + child.column + "'" + required + " placeholder='" + child.label
            + "' autocomplete='off' class='layui-input'></div>";
    return input;
}

function fd_title(title) {
    var return_txt = "<div class='layui-elem-quote' style='margin-top: 20px;font-size: 20px;'><p>"
            + title + "</p></div>";
    return return_txt;
}

function fd_textarea(child) {
    var max=child.inputType.vadidate.max;
    if(max=="-1"||max==-1){
        max="";
    }else{
        max="maxlength='"+max+"'";
    }
    var return_txt = "<label class='layui-form-label'>"
            + child.label
            + "</label><div class='layui-input-block'><textarea type='text' id='"
            + child.column
            + "' name='"
            + child.column+"'"+max
            + " autocomplete='off' placeholder='"
            + child.label + "' class='layui-textarea'></textarea></div>";
    return return_txt;
}

function fd_group(title) {
    var return_txt = "<fieldset class='layui-elem-field layui-field-title' style='margin-top: 20px; width: 300px;font-size: 16px;'><legend style='font-size: 16px;'>"
            + title + "</legend></fieldset>";

    return return_txt;
}

/*
 * title:标题,例如:门责图片 limitpicnum:图片上传数量限制
 * 
 */
function fd_addpic(child) {
    
    var id=child.column;
    var title=child.label;
    var limitpicnum=child.inputType.vadidate.max;
    
    var choose_txt = "<button type='button' class='layui-btn' id='" + id
            + "'>请选择图片</button>";
    if (islimit == true) {
        choose_txt = "";
    }
    var picsString = "<div class='upload_img_list' style='display: flex; flex-wrap: nowrap' id='"+id+"_view'></div>";

    var return_txt = "<label class='layui-form-label'>"
            + title
            + "</label><div class='layui-input-block'><div class='layui-upload'>"
            + choose_txt
            + "<div class='layui-upload-list' style='display: flex; flex-wrap: nowrap'>"
            + picsString
            + "</div></div></div><div class='layui-input-block'><span style='color: red;'>图片限制上传"
            + limitpicnum + "张</span></div>";
    return return_txt;
}

function fd_showpic(limitpicnum, id) {
    
    var temp = "";
    if (pics[id] == null || pics[id] == undefined || pics[id] == NaN
            || pics[id] == '') {
        pics[id] = [];
    }
    for (var i = 0; i < pics[id].length; i++) {

        temp = temp
                + "<dd id='"
                + i
                + "'><div class='operate'><i  class='layui-icon layui-icon-delete' style='color: #fff;' οnclick='piccancel("
                + i
                + ",&quot;"
                + pics[id].join(",")
                + "&quot;,"
                + limitpicnum
                + ",&quot;"
                + id
                + "&quot;)'></i></div><img class='img' src='http://192.168.1.42:7112"
                + pics[id][i] + "' id='"+id+"_view'></dd>"
    }
    
    return temp;
}
function initpic(child, upload) {
    var id=child.column;
    var limitpicnum=child.inputType.vadidate.max;
    
    
    var multipleUpload = upload.render({
        elem : '#' + id, // 绑定元素
        url : 'http://192.168.1.42:7112/common/upload/zipimg', // 上传接口
        exts : 'png|jpg|jpeg',
        accept : 'images',
        acceptMime : 'image/jpg, image/png,image/jpeg',
        multiple : true, // 允许多文件上传
        number : limitpicnum, // 允许上传文件数,0不限,当不限制图片上传数量时,请注意数据库字段允许的最大长度
        before : function(obj) {
        },
        done : function(res, index, upload) {
            // 如果上传失败
            if (res.code > 0) {
                return layer.msg(index, '上传失败');
            } else {
                if (pics[id].length >= limitpicnum) {
                    islimit = true;
                } else {
                    
                    pics[id].push(res.url);
                    $('#' + id+'_view').empty();
                    
                    $('#' + id+'_view').append(fd_showpic(limitpicnum, id));
                    if (pics[id].length == limitpicnum) {
                        islimit = true;
                    }
                }
            }
            // 上传成功
        },
        error : function() {

        },
        allDone : function(obj) { // 当文件全部被提交后,才触发

        }
    });

}

function piccancel(index, pic_list, limitpicnum, id) { // 删除图片
    console.log("删除===",pics[id])
    pic_list = pic_list.split(",");
    pic_list.splice(index, 1); // 操作图片数组
    pics[id] = pic_list;
    
    if (pics[id].length < limitpicnum) { // 判断此时图片数量是否达到限制,未达到则显示上传按钮
        islimit = false;
    }
    $('#' + id+'_view').empty();
    $('#' + id+'_view').append(fd_showpic(limitpicnum, id));
}

function fd_txt(title, name, placeholder, required) {
    if (required) {
        required = "required";
    } else {
        required = "";
    }
    var input = "<label class='layui-form-label'>"
            + title
            + "</label><div class='layui-input-block'><input type='text' name='"
            + name + "'" + required + "placeholder='" + placeholder
            + "' autocomplete='off' class='layui-input'></div>";
    return input;
}


function fd_date(child) {
    var required=child.inputType.vadidate.required;
    if (required) {
        required = "required";
    } else {
        required = "";
    }
    var input = "<label class='layui-form-label'>"
            + child.label
            + "</label><div class='layui-input-block'><input type='txt' id='fd_"
            + child.column + "'name='" + child.column + "'" + required + " placeholder='"
            + child.label
            + "' autocomplete='off' class='layui-input'></div>";
    return input;
}

function fd_date_init(laydate,child) {
    var format=child.inputType.format;
    var type = "date";
    if (format == "yyyy" || format == "YYYY") {
        type = "year";
    } else if (format == "yyyy-mm" || format == "YYYY-MM"
            || format == "YYYY-mm" || format == "yyyy-MM") {
        type = "month";
    }
    laydate.render({
        elem : '#fd_' + child.column,
        type : type,
        done : function(value) {

        }
    });
}

function fd_select(child) {
    var list=child.inputType.option.options;
    var temp = "";
    for (var i = 0; i < list.length; i++) {
        temp = temp + "<option value='" + list[i].label + "'>" + list[i].value
                + "</option>"
    }
    var select_str = "<label class='layui-form-label'>"
            + child.label
            + "</label><div class='layui-input-block'><select lay-search='' name='"
            + child.column
            + "' lay-filter='"
            + child.column
            + "'>"
            + temp
            + "</select></div>";

    return select_str;

}

公共js


var inputType = { 
        FD_TEXT : "fd_text",//限制 是否必填
        FD_AREATEXT    :"fd_areatext",//限制文字的长度
        FD_PIC    :"fd_pic",
        FD_DATE    :"fd_date",//限制 是否必填
        FD_NUMBER    :"fd_number",//输入类型为数字  限制  是否必填
        FD_SELECT:"fd_select"
};


​数据格式


{
    table:"", // 生成的表名
    name:"", // 表单元数据 查询name 唯一
    title:"", // 中文业务名
    parent_table:{
        isChildren:true/flase, // 是否有关联
        table:"", // 关联表
        column:"", // 关联字段
        value:"" // 查询值
    }, // 关联表名
    metadata:[
        {
           section:{
            label:"", // 块级 label显示 例:基本信息
            children:[
                {
                    column:"", // 表单项name 提交时的字段名
                    label:"", // 表单项的提示label
                    inputType:{
                        type:"", 
                        // number数字 rich富文本 text文本 date时间控件
                        // password密码框 textarea多行文本
                        // select下拉框 image图片上传 file文件上传
                        // 二级联动,根据不同项目初期定稿 例:
                        // 街镇联动 streetAndRoad 
                        // 后端读到街镇联动,自动加入 street_id road_id 字段 
                        // 前端读到街镇联动,自动加入 街镇联动的下拉框,接口定稿
                        format:"",
                        // date搭配字段 时间格式的限制
                        // YYYY-MM/YYYY-MM-dd/YYYY-MM-dd HH:II:SS
                        option:{ 
                        // select搭配字段
                            type:"", 
                            // static静态 link外链 foreign表格关联
                            table:"", 
                            // 表格关联搭配字段 关联表
                            label:"", 
                            // 表格关联搭配字段 option的value 通常id
                            value:"",  // 表格关联搭配字段 option显示的字段
                            url:"", // 外链搭配字段 接口地址
                            options:[ // option显示数组
                            {label:"",value:""}
                            ]
                        },
                        vadidate:{ // 字段验证限制
                            required:true/false, // 必填
                            max:"", 
                            // 最大输入数 string长度 number大小 上传数
                            min:"", // 最小输入数
                        }
                    }
                }
            ]
           } 
        },
        {
            section:{...}
        }
    ]
}

​​​​​构建效果

Jquery+layui的动态表单构建