layui.config({
    base: './form-design/modules/'
}).extend({
    input: 'components/input',
    numberInput: 'components/numberInput',
    password: 'components/password',
    grid: 'components/grid',
    textarea: 'components/textarea',
    select: 'components/select',
    radio: 'components/radio',
    checkbox: 'components/checkbox',
    laySwitch: 'components/laySwitch',
    laySlider: 'components/laySlider',
    date: 'components/date',
    layRate: 'components/layRate',
    layCarousel: 'components/layCarousel',
    uploadImage: 'components/uploadImage',
    uploadFile: 'components/uploadFile',
    uploadVideo: 'components/uploadVideo',
    uploadAudio: 'components/uploadAudio',
    laySign: 'components/laySign',
    docno: 'components/docno',
}).define(["layer", "laytpl", "element", "form", "slider", "laydate", "rate", "colorpicker", "layedit", "carousel", "upload", "formField", "iconPicker", "cron", "labelGeneration",
    'consts',
    'input', 'numberInput', 'password', 'grid', 'textarea',
    'select', 'radio', 'checkbox', 'laySwitch', 'laySlider', 'date', 'layRate', 'layCarousel',
    'uploadImage', 'uploadFile', 'uploadVideo', 'uploadAudio',
    'laySign', 'docno'
], function (exports) {
    var $ = layui.jquery,
        layer = layui.layer,
        slider = layui.slider,
        laydate = layui.laydate,
        rate = layui.rate,
        carousel = layui.carousel,
        form = layui.form,
        layedit = layui.layedit,
        formField = layui.formField,
        hint = layui.hint,
        input = layui.input,
        numberInput = layui.numberInput,
        password = layui.password,
        grid = layui.grid,
        textarea = layui.textarea,
        select = layui.select,
        radio = layui.radio,
        checkbox = layui.checkbox,
        laySwitch = layui.laySwitch,
        laySlider = layui.laySlider,
        date = layui.date,
        layRate = layui.layRate,
        layCarousel = layui.layCarousel,
        uploadImage = layui.uploadImage,
        uploadFile = layui.uploadFile,
        uploadVideo = layui.uploadVideo,
        uploadAudio = layui.uploadAudio,
        laySign = layui.laySign,
        docno = layui.docno,
        consts = layui.consts,
        lang = consts.lang,

        //模块名称常量
        MOD_NAME = 'formDesigner',
        TP_MAIN = [
            '<div class="layui-layout layui-layout-admin">',
            '       <div class="layui-side">',
            '           <div class="layui-side-scroll" style="width: 260px;">',
            '               <!-- 左侧导航区域（可配合layui已有的垂直导航） -->',
            '               <div class="layui-tab layui-tab-brief" lay-filter="components-list">',
            '                   <ul class="layui-tab-title">',
            '                       <li class="layui-this">组件</li>',
            '                   </ul>',
            '                   <div class="layui-tab-content">',
            '                       <div class="layui-tab-item layui-show">',
            '                           <div class="components-list" id="components-form-list">',
            '                       </div>',
            '                   </div>',
            '                   <div class="layui-tab-item components-list" id="components-form-list">开发中...</div>',
            '               </div>',
            '           </div>',
            '       </div>',
            '   </div>',
            '   <div class="layui-body" style="left: 265px;">',
            '       <!-- 内容主体区域 -->',
            '       <form class="layui-form layui-form-pane" style="height:98%;">',
            '           <div class="layui-form" id="formDesignerForm" lay-filter="formDesignerForm">',
            '               <div class="layui-row layui-empty">',
            '从左侧拖拽控件到此设计区域来添加字段',
            '                </div>',
            '           </div>',
            '           <button type="button" class="layui-btn" style="display: none" lay-submit lay-filter="*">立即提交</button>',
            '       </form>',
            '   </div>',
            '   <div class="layui-side-right">',
            '       <div class="layui-side-scroll" style="width: 350px;">',
            '           <!-- 属性导航 -->',
            '           <form class="layui-form  layui-form-pane">',
            '               <div class="layui-tab layui-tab-brief" lay-filter="form-attr">',
            '                   <ul class="layui-tab-title">',
            '                       <li class="layui-this">字段设置</li>',
            '                       <li>表单设置</li>',
            '                   </ul>',
            '                   <div class="layui-tab-content">',
            '                       <div class="layui-tab-item layui-show" id="columnProperty">',
            '                       </div>',
            '                       <div class="layui-tab-item" id="formProperty">',
            '                           <!--表单名称-->',
            '                           <div class="layui-form-item">',
            '                               <label class="layui-form-label">表单名称 *</label>',
            '                               <div class="layui-input-block">',
            '                                   <input type="text" id="formName" name="formName" lay-verify="required" placeholder="请输入表单名称" class="layui-input">',
            '                               </div>',
            '                           </div>',
            '                           <div class="layui-form-item">',
            '                               <label class="layui-form-label">表单描述 *</label>',
            '                               <div class="layui-input-block">',
            '                                   <input type="text" id="formSummary" name="formSummary" lay-verify="required" placeholder="请输入表单描述" class="layui-input">',
            '                               </div>',
            '                           </div>',
            '                           <div class="layui-form-item">',
            '                               <label class="layui-form-label">表单类型</label>',
            '                               <div class="layui-input-block">',
            '                                   <select id="formType" name="formType" lay-verify="required">',
            '                                       <option value="default">默认</option>',
            '                                       <option value="oa">OA表单</option>',
            '                                   </select>',
            '                               </div>',
            '                               <div class="layui-form-mid layui-word-aux">提示：OA表单数据参与OA流程；默认表单中APP的页面校验用户token，可对接开放接口，不校验token，但需要传userId；</div>',
            '                           </div>',
            '                           <div class="layui-form-item">',
            '                               <label class="layui-form-label">OA标题模板</label>',
            '                               <div class="layui-input-block">',
            '                                   <input type="text" id="mainTitleTpl" name="mainTitleTpl" placeholder="请输入主标题模板" class="layui-input">',
            '                               </div>',
            '                               <div class="layui-form-mid layui-word-aux">提示：列表中显示的标题（<b>MAIN_TITLE</b> 字段，组合为空则没有该字段），由表单可在列表中显示的指定字段组合而成，组合方法为至少一个 <b>${唯一标识}</b> 按顺序排列即可。如：${name1}${name2}，那么最终在列表数据中的标题便会赋值为 name1的值 + name2的值。</div>',
            '                           </div>',
            '                           <div class="layui-btn-group">',
            '                               <button id="save" type="button" class="layui-btn">保存</button>',
            '                           </div>',
            '                           <!--//end-->',
            '                       </div>',
            '                   </div>',
            '               </div>',
            '           </form>',
            '       </div>',
            '   </div>',
            '</div>'
        ].join(''),

        //外部接口
        formDesigner = {
            index: layui.formDesigner ? (layui.formDesigner.index + 10000) : 0,
            //设置全局项
            set: function (options) {
                var that = this;
                that.config = $.extend({}, that.config, options);
                return that;
            },
            //事件监听
            on: function (events, callback) {
                return layui.onevent.call(this, MOD_NAME, events, callback);
            }
        },
        /**
         * 操作当前实例elem
         * id 表示当前实例的索引 默认就是内部的 index，如果id存在值 那么就从已经存在的获取
         */
        thisIns = function () {
            var that = this,
                options = that.config;
            return {
                reload: function (options) {
                    that.reload.call(that, options);
                },
                getOptions: function () {
                    return options || null;
                },
                getData: function () {
                    return options.data || null;
                },
            }
        },
        getThisInsConfig = function (id) {
            var config = thisIns.config[id];
            if (!config) {
                hint.error('在表实例中找不到ID选项');
            }
            return config || null;
        },
        Class = function (options) {
            var that = this;
            that.index = ++formDesigner.index; //增加实例，index 也是要增加JSON.stringify(options.data, null, 4)
            that.config = $.extend({}, that.config, formDesigner.config, options);
            that.render();
        };
    /* 此方法最后一道 commom.js 中 */
    Class.prototype.findJsonItem = function (json, id) {
        var that = this,
            options = that.config;
        for (var i = 0; i < json.length; i++) {
            if (json[i].id === id) {
                return json[i];
            } else {
                if (json[i].tag === 'grid') {
                    for (var j = 0; j < json[i].columns.length; j++) {
                        if (json[i].columns[j].list.length > 0) {
                            var _item = that.findJsonItem(json[i].columns[j].list, id);
                            if (_item) {
                                return _item;
                            }
                        }
                    }
                }
            }
        }
    }
    /* 删除json中的文件并返回上一个节点*/
    Class.prototype.deleteJsonItem = function (json, id) {
        var that = this,
            options = that.config;
        for (var i = 0; i < json.length; i++) {
            if (json[i].id === id) {
                json.splice(i, 1);
                if (i > 0) {
                    return json[i - 1];
                }
                break;
            } else {
                if (json[i].tag === 'grid') {
                    for (var j = 0; j < json[i].columns.length; j++) {
                        if (json[i].columns[j].list.length > 0) {
                            that.deleteJsonItem(json[i].columns[j].list, id);
                        }
                    }
                }
            }
        }
        return undefined;
    };
    Class.prototype.copyJsonAfterItem = function (json, id) {
        var that = this,
            options = that.config;
        for (var i = 0; i < json.length; i++) {
            if (json[i].id === id) {
                var _newjson = JSON.parse(JSON.stringify(json[i]));
                _newjson.id = that.autoId(_newjson.tag);
                json.splice(i + 1, 0, _newjson);
                return json[i];
            } else {
                if (json[i].tag === 'grid') {
                    for (var j = 0; j < json[i].columns.length; j++) {
                        if (json[i].columns[j].list.length > 0) {
                            var _item = that.copyJsonAfterItem(json[i].columns[j].list, id);
                            if (_item) {
                                return _item;
                            }
                        }
                    }
                }
            }
        }
        return undefined;
    };
    /**
     * data 表示设计区数据
     * dataSource 表示数据源即一个控件的数据来源
     *
     */
    Class.prototype.config = {
        version: "1.0",
        formName: "",
        Author: "WenG",
        formId: "id",
        mainTitleTpl: '',
        formType: 'default',
        generateId: 0,
        field: [],
        data: [],
        dataSource: {},
        selectItem: undefined,
    };
    /* 自动生成ID 当前页面自动排序*/
    Class.prototype.autoId = function (tag) {
        var that = this,
            options = that.config;
        options.generateId = options.generateId + 1;
        return tag + '_' + options.generateId;
    }
    /* 组件定义 */
    Class.prototype.components = {
        input: input,
        numberInput: numberInput,
        password: password,
        textarea: textarea,

        select: select,
        radio: radio,
        checkbox: checkbox,
        switch: laySwitch,
        slider: laySlider,
        date: date,
        rate: layRate,
        carousel: layCarousel,

        uploadImage: uploadImage,
        uploadFile: uploadFile,
        uploadVideo: uploadVideo,
        uploadAudio: uploadAudio,

        grid: grid,

        laySign: laySign,

        docno: docno,
    };
    /* 如果是grid布局控件 就显示不一样的样式 */
    Class.prototype.addClick = function (evt) {
        var that = this, options = that.config;
        $("#formDesignerForm .layui-form-item").on('click', function (e) {
            //当 div 为嵌套关系的时候 阻止事件冒泡
            e.preventDefault();
            e.stopPropagation();
            // console.log("您点击了 formDesignerForm .layui-form-item");
            var index = parseInt($(this)[0].dataset.index);
            var _id = $(this)[0].dataset.id;
            options.selectItem = that.findJsonItem(options.data, _id);
            var tag = $(this)[0].dataset.tag;
            //显示当前的属性
            that.components[tag].property(options.selectItem);
            if (options.selectItem.tag === "select" || options.selectItem.tag === "checkbox" || options.selectItem.tag === "radio") {
                var sortable = Sortable.create(document.getElementById(options.selectItem.tag), {
                    group: {
                        name: 'propertygroup',
                    },
                    ghostClass: "ghost",
                    handle: '.select-option-drag',
                    dataIdAttr: 'data-index',
                    animation: 150,
                    onEnd: function (evt) {
                        if (options.selectItem === undefined) {
                            return;
                        }
                        var indexArray = sortable.toArray();
                        var newJson = [];
                        for (var i = 0; i < indexArray.length; i++) {
                            newJson.push(options.selectItem.options[indexArray[i]]);
                        }
                        options.selectItem.options = newJson;
                        that.renderForm();
                    }
                });
            }
            that.bindPropertyEvent();
            //移除其他元素的 siblings() 方法返回被选元素的所有同级元素
            // $(this).siblings('div').removeClass('active');
            //移除 #formDesignerForm .layui-form-item 下所有的 active
            $('#formDesignerForm .layui-form-item').removeClass('active');
            //给当前元素增加class
            $(this).addClass('active');
            var _draghtml1 = '<div class="widget-view-action"  id="widget-view-action"><i class="layui-icon layui-icon-file"></i><i class="layui-icon layui-icon-delete"></i></div><div class="widget-view-drag" id="widget-view-drag"><i class="layui-icon layui-icon-screen-full"></i></div>';
            var len = $(this).children().length;
            if (len <= 12) {
                //先删除元素
                $("#formDesignerForm .layui-form-item .widget-view-action").remove();
                $("#formDesignerForm .layui-form-item .widget-view-drag").remove();
                // console.log("显示子节点");
                // console.log($(this).children());
                if ($('#widget-view-action')) { //已存在
                    $('#widget-view-action').remove();
                }
                $(this).children(len - 1).after(_draghtml1);
            }
            /* 向 拷贝 删除 按钮添加 click 动作 */
            that.addCopyDeleteClick();
            //重新渲染
            form.render();
            if (options.data.length != 0) {
                for (var i = 0; i < options.data.length; i++) {
                    if (options.data[i].tag === 'grid') {
                        for (var j = 0; j < options.data[i].columns.length; j++) {
                            for (var k = 0; k < options.data[i].columns[j].list.length; k++) {
                                if (options.data[i].columns[j].list[k].tag === 'select') {
                                    $('#' + options.data[i].columns[j].list[k].id + ' .layui-input-block div.layui-unselect.layui-form-select').css({
                                        width: '{0}'.format(options.data[i].columns[j].list[k].width)
                                    });
                                }
                            }
                        }
                    } else {
                        if (options.data[i].tag === 'select') {
                            $('#' + options.data[i].id + ' .layui-input-block div.layui-unselect.layui-form-select').css({
                                width: '{0}'.format(options.data[i].width)
                            });
                        }
                    }
                }
            }
        });
    };
    /* 给字段属性绑定事件 实现双向绑定？*/
    Class.prototype.bindPropertyEvent = function (_json) {
        var that = this,
            options = that.config;
        if (options.data === undefined) {
            return;
        }
        if (typeof (options.data) === 'string') {
            options.data = JSON.parse(options.data);
        }
        var _property = $('#columnProperty');
        var _columns = _property.find('input,textarea,select,checkbox');
        var _json = options.selectItem;
        //没有可以选择的
        if (_json === undefined) {
            return;
        }
        laydate.render({
            elem: '#dataMaxValue' + _json.tag + _json.id,
            format: 'yyyy-MM-dd',
            btns: ['now', 'confirm'],
            value: _json.dataMaxValue,
            done: function (value, date, endDate) {
                _json.dataMaxValue = value;
                that.components[_json.tag].update(_json);
            }
        });
        laydate.render({
            elem: '#dataMinValue' + _json.tag + _json.id,
            format: 'yyyy-MM-dd',
            btns: ['now', 'confirm'],
            value: _json.dataMinValue,
            done: function (value, date, endDate) {
                _json.dataMinValue = value;
                that.components[_json.tag].update(_json);
            }
        });
        laydate.render({
            elem: '#dateDefaultValue' + _json.tag + _json.id,
            type: _json.datetype,
            format: _json.dateformat,
            value: _json.dateDefaultValue,
            done: function (value, date, endDate) {
                _json.dateDefaultValue = value;
                that.components[_json.tag].update(_json);
            }
        });
        laydate.render({
            elem: '#dateRangeDefaultValue' + _json.tag + _json.id,
            type: _json.datetype,
            format: _json.dateformat,
            value: _json.dateRangeDefaultValue,
            range: "-",
            done: function (value, date, endDate) {
                _json.dateRangeDefaultValue = value;
                that.components[_json.tag].update(_json);
            }
        });
        if (_json.width !== undefined) {
            //定义初始值
            slider.render({
                elem: '#width',
                value: _json.width.replace("%", ""), //初始值
                min: 20,
                max: 100,
                step: 1,
                input: true,
                change: function (value) {
                    _json.width = value + "%";
                    that.components[_json.tag].update(_json);
                }
            });
        }
        if (_json.labelWidth !== undefined) {
            //定义初始值
            slider.render({
                elem: '#labelWidth',
                value: _json.labelWidth, //初始值
                min: 80,
                max: 300,
                step: 1,
                input: true,
                change: function (value) {
                    _json.labelWidth = value;
                    that.components[_json.tag].update(_json);
                }
            });
        }
        form.on('checkbox', function (data) {
            //data.elem.closest('.layui-form-item')
            if (_json.tag === 'checkbox') {
                var _index = parseInt($("#" + _json.id + "Box .layui-input-block div.layui-form-checkbox").index(data.othis[0]));
                if ($(data.othis[0]).parent().parent().parent().attr("id") === 'checkbox') {
                    _index = parseInt($(data.othis[0]).parent().parent().attr("data-index"));
                }
                for (var i = 0; i < _json.options.length; i++) {
                    if (i === _index) {
                        _json.options[i].checked = data.elem.checked;
                        break;
                    }
                }
                that.components[_json.tag].update(_json);
            }
        });
        form.on('radio', function (data) {
            //data.elem.closest('.layui-form-item')
            if (_json.tag === 'radio') {
                var _index = parseInt($("#" + _json.id + "Box .layui-input-block div.layui-form-radio").index(data.othis[0]));
                if ($(data.othis[0]).parent().parent().parent().attr("id") === 'radio') {
                    _index = parseInt($(data.othis[0]).parent().parent().attr("data-index"));
                }
                for (var i = 0; i < _json.options.length; i++) {
                    if (i === _index) {
                        _json.options[i].checked = true;
                        continue;
                    }
                    _json.options[i].checked = false;
                }
                that.components[_json.tag].update(_json);
            } else if (_json.tag === 'select') {
                var _index = parseInt(data.elem.closest('.layui-form-item').dataset.index);
                for (var i = 0; i < _json.options.length; i++) {
                    if (i === _index) {
                        _json.options[i].checked = true;
                        continue;
                    }
                    _json.options[i].checked = false;
                }
                that.components[_json.tag].update(_json);
            }
        });
        form.on('select', function (data) {
            var _key = data.elem.name;
            var _value = parseInt(data.value);
            var _json = options.selectItem;
            if (_key === 'columns') {
                var columnCount = _json[_key].length;
                var nullJson = {
                    span: 12,
                    list: []
                };
                if (_value > columnCount) {
                    for (var i = columnCount + 1; i <= _value; i++) {
                        _json[_key].splice(i, 0, nullJson);
                    }
                } else {
                    _json[_key].splice(_value, columnCount);
                }
                that.renderForm();
            } else if (_key === 'dateformat') {
                if (_json.tag === 'date') {
                    var _html = '<div id="{0}" class="layui-input icon-date widget-date" style="line-height: 40px;"></div>'.format('dateDefaultValue' + _json.tag + _json.id);
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').empty();
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').append(_html);
                    _json.dateformat = data.value;
                    var dateClass = laydate.render({
                        elem: '#dateDefaultValue' + _json.tag + _json.id,
                        type: _json.datetype,
                        format: _json.dateformat,
                        value: new Date(),
                        done: function (value, date, endDate) {
                            _json.dateDefaultValue = value;
                            that.components[_json.tag].update(_json);
                        }
                    });
                    _json.dateDefaultValue = dateClass.config.elem[0].innerText;
                    that.components[_json.tag].update(_json);
                }
                if (_json.tag === 'dateRange') {
                    var _html = '<div id="{0}" class="layui-input icon-date widget-date"></div>'.format('dateDefaultValue' + _json.tag + _json.id);
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').empty();
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').append(_html);
                    _json.dateformat = data.value;
                    var _v = layui.util.toDateString(new Date(), _json.dateformat) + " - " + layui.util.toDateString(new Date(), _json.dateformat);
                    laydate.render({
                        elem: '#dateRangeDefaultValue' + _json.tag + _json.id,
                        type: _json.datetype,
                        format: _json.dateformat,
                        value: _v,
                        range: "-",
                        done: function (value, date, endDate) {
                            _json.dateRangeDefaultValue = value;
                            that.components[_json.tag].update(_json);
                        }
                    });
                    _json.dateRangeDefaultValue = _v;
                    that.components[_json.tag].update(_json);
                }
            } else if (_key === 'datetype') {
                if (_json.tag === 'date') {
                    var _html = '<div id="{0}" class="layui-input icon-date widget-date" style="line-height: 40px;"></div>'.format('dateDefaultValue' + _json.tag + _json.id);
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').empty();
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').append(_html);
                    _json.datetype = data.value;
                    var dateClass = laydate.render({
                        elem: '#dateDefaultValue' + _json.tag + _json.id,
                        type: _json.datetype,
                        format: _json.dateformat,
                        value: new Date(),
                        done: function (value, date, endDate) {
                            _json.dateDefaultValue = value;
                            that.components[_json.tag].update(_json);
                        }
                    });
                    _json.dateDefaultValue = dateClass.config.elem[0].innerText;
                    that.components[_json.tag].update(_json);
                }
                if (_json.tag === 'dateRange') {
                    var _html = '<div id="{0}" class="layui-input icon-date widget-date"></div>'.format('dateDefaultValue' + _json.tag + _json.id);
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').empty();
                    $('#dateDefaultValue' + _json.id + ' .layui-input-block').append(_html);
                    _json.datetype = data.value;
                    laydate.render({
                        elem: '#dateRangeDefaultValue' + _json.tag + _json.id,
                        type: _json.datetype,
                        format: _json.dateformat,
                        value: _json.dateRangeDefaultValue,
                        range: "-",
                        done: function (value, date, endDate) {
                            _json.dateRangeDefaultValue = value;
                            that.components[_json.tag].update(_json);
                        }
                    });
                    that.components[_json.tag].update(_json);
                }
            } else if (_key === 'required') {
                _json.expression = data.value;
                that.components[_json.tag].update(_json);
            } else if (_key === 'expression') {
                _json.expression = data.value;
                that.components[_json.tag].update(_json);
            } else if (_key === 'anim' || _key === 'arrow') {
                _json[data.elem.name] = data.value;
                that.components[_json.tag].update(_json);
            } else if (_key === 'buttonType') {
                _json.buttonType = data.value;
                that.components[_json.tag].update(_json);
            } else if (_key === 'buttonSize') {
                _json.buttonSize = data.value;
                that.components[_json.tag].update(_json);
            }
        });
        form.on('switch', function (data) {
            var _key = data.elem.name;
            var _value = data.elem.checked ? true : false;
            if (_key === 'readonly' || _key == 'disabled' || _key === 'required' || _key === 'listShow' || _key === 'half' || _key === 'text' || _key === 'switchValue' || _key === 'isInput' || _key == 'iconPickerSearch' || _key === 'iconPickerPage' || _key === 'isEnter' || _key === 'isLabel') {
                _json[_key] = _value;
                that.components[_json.tag].update(_json); //局部更新
            }
        });
        //options 的添加事件
        if (_json.hasOwnProperty('options')) {
            $('#select-option-add').on('click', function () {
                //添加html
                _json.options.splice(_json.options.length + 1, 0, {
                    text: 'option',
                    value: 'value',
                    checked: false
                });
                var _htmloption = '';
                _htmloption += '<div class="layui-form-item option select-options" data-index="{0}">'.format(_json.options.length - 1);
                _htmloption += '  <div class="layui-inline" style="width: 30px; margin-right: 0px;">';
                if (_json.tag === 'checkbox') {
                    _htmloption += '   <input type="checkbox" name="{0}" lay-skin="primary" title="">'.format(_json.tag);
                } else {
                    _htmloption += '   <input type="radio" name="{0}" >'.format(_json.tag);
                }
                _htmloption += '  </div>';
                _htmloption += '  <div class="layui-inline" style="margin-right: 0px;width:110px;">';
                _htmloption += '   <input type="text" name="{0}-text"  autocomplete="off" value="{1}" class="layui-input">'.format(_json.tag, 'option');
                _htmloption += '  </div>';
                _htmloption += '  <div class="layui-inline" style="margin-right: 0px;width:110px;">';
                _htmloption += '   <input type="text" name="{0}-value"  autocomplete="off" value="{1}" class="layui-input">'.format(_json.tag, 'value');
                _htmloption += '  </div>';
                _htmloption += '  <div class="layui-inline" style="margin-right: 0px;">';
                _htmloption += '   <i class="layui-icon layui-icon-slider select-option-drag" style="color:blue;font-size:20px;"></i>';
                _htmloption += '   <i class="layui-icon layui-icon-delete select-option-delete" style="color:red;font-size:20px;"></i>';
                _htmloption += '  </div>';
                _htmloption += '</div>';
                $('#columnProperty .select-options').last().after(_htmloption);
                _html = '';
                if (_json.tag === 'checkbox') {
                    //同步到设计视图checkbox
                    _html += '<input type="checkbox" name="{0}" title="{1}" >'.format(_json.tag, 'option');
                    $('#' + _json.id + 'Box .layui-input-block').append(_html);
                } else if (_json.tag === 'radio') {
                    //同步到设计视图radio
                    _html += '<input type="radio" name="{0}" title="{1}" >'.format(_json.tag, 'option');
                    $('#' + _json.id + 'Box .layui-input-block').append(_html);
                } else if (_json.tag === 'carousel') {}

                if (_json.tag === 'checkbox') {
                    form.render('checkbox');
                } else if (_json.tag === 'radio') {
                    form.render('radio');
                } else if (_json.tag == 'carousel') {
                    that.components[_json.tag].update(_json);
                    form.render('radio');
                    carousel.render({
                        elem: '#' + item.tag + item.id,
                        width: item.width, //设置容器宽度
                        arrow: item.arrow, //始终显示箭头
                        //anim: 'updown' //切换动画方式
                    });
                } else if (_json.tag == 'select') {
                    form.render('select');
                    form.render('radio');
                }
            });
            //委托监听先关闭在增加 click
            $(document).off('click', '#columnProperty .select-option-delete').on('click', '#columnProperty .select-option-delete', function (e) {
                e.preventDefault();
                e.stopPropagation();
                //从数据源 options.data 中删除节点
                if (_json.options.length <= 1) {
                    layer.msg('已达到最低选项，不能继续删除');
                    return;
                }
                var _index = $(this).closest('.layui-form-item')[0].dataset.index;
                if (_index !== undefined) {
                    _json.options.splice(_index, 1); //删除此节点
                }
                var checkedDefual = true;
                for (var i = 0; i < _json.options.length; i++) {
                    if (_json.options[i].checked) {
                        vv = false
                    }
                }
                if (checkedDefual) {
                    _json.options[0].checked = true;
                }
                //从html中删除节点 改成全部重绘
                // $(this).closest('.layui-form-item').remove()
                $('#' + _json.tag).empty();
                //删除所有的选项
                //选项
                var _html = '';
                for (var i = 0; i < _json.options.length; i++) {
                    _html += '<div class="layui-form-item option select-options" data-index="{0}">'.format(i);
                    _html += '  <div class="layui-inline" style="width: 30px; margin-right: 0px;">';
                    if (_json.tag === 'checkbox') {
                        if (_json.options[i].checked) {
                            _html += '   <input type="checkbox" name="{0}" lay-skin="primary" title="" checked>'.format(_json.tag);
                        } else {
                            _html += '   <input type="checkbox" name="{0}" lay-skin="primary" title="">'.format(_json.tag);
                        }
                    } else {
                        if (_json.options[i].checked) {
                            _html += '   <input type="radio" name="{0}" checked>'.format(_json.tag);
                        } else {
                            _html += '   <input type="radio" name="{0}">'.format(_json.tag);
                        }
                    }
                    _html += '  </div>';
                    _html += '  <div class="layui-inline" style="margin-right: 0px;width:110px;">';
                    _html += '   <input type="text" name="{0}-text"  autocomplete="off" value="{1}" class="layui-input">'.format(_json.tag, _json.options[i].text);
                    _html += '  </div>';
                    _html += '  <div class="layui-inline" style="margin-right: 0px;width:110px;">';
                    _html += '   <input type="text" name="{0}-value"  autocomplete="off" value="{1}" class="layui-input">'.format(_json.tag, _json.options[i].value);
                    _html += '  </div>';
                    _html += '  <div class="layui-inline" style="margin-right: 0px;">';
                    _html += '   <i class="layui-icon layui-icon-slider select-option-drag" style="color:blue;font-size:20px;"></i>';
                    _html += '   <i class="layui-icon layui-icon-delete select-option-delete" style="color:red;font-size:20px;"></i>';
                    _html += '  </div>';
                    _html += '</div>';
                }
                $('#' + _json.tag).append(_html);
                //更新设计区节点
                that.components[_json.tag].update(_json);
                if (_json.tag === 'checkbox') {
                    form.render('checkbox');
                } else if (_json.tag === 'radio') {
                    form.render('radio');
                } else if (_json.tag == 'select') {
                    form.render('select');
                    form.render('radio');
                }
                //向 .option .layui-inline 添加drag事件并且必须设在 select-option-drag 中才能拖动
            });
        }
        // 文号
        if(_json.hasOwnProperty('docNoOptions')) {
            $('.select-doc-no-btn').on('click', function() {
                var id = this.dataset.id;
                var boxId = '#'+ id +'OptionsBox';
                top.dialog.open({
                    // 打开页面，指定选择框类型
                    url: 'route/doc-no/select/list?selectType=checkbox',
                    title: '选择文号选项',
                    width: '800px',
                    height: '400px',
                    onClose: function() {
                        $(boxId).empty();
                        // 获取选择后的列表
                        var newSelectedArray = top.dialog.dialogData.newSelectedArray;
                        if(newSelectedArray && newSelectedArray.length != 0) {
                            // 处理选择结果
                            var _htmloption = '';
                            var docNoOptions = [];
                            for(var i = 0, item; item = newSelectedArray[i++];) {
                                docNoOptions.push({
                                    text: item.title,
                                    value: item.docNoId,
                                    template: item.template,
                                    type: item.type,
                                    checked: i == 1 ? true : false
                                });
                                _htmloption += '<div class="layui-form-item option select-options" data-index="{0}">'.format(i - 1);
                                _htmloption += '  <div class="layui-inline" style="margin-right: 0px;width:314px;">';
                                _htmloption += '   <input type="text" name="{0}-text"  autocomplete="off" value="{1}" class="layui-input" readonly>'.format(_json.tag, item.title + item.template);
                                _htmloption += '  </div>';
                                _htmloption += '</div>';
                            }
                            $(boxId).append(_htmloption);
                            form.render('radio');
                            _json.docNoOptions = docNoOptions;
                            that.components[_json.tag].update(_json);
                        }
                    }
                });
            })
        }
        $(document).off('click', '.select-options input[type=checkbox]').on('click', '.select-options input[type=checkbox]', function (e) {
            // console.log(e);
            //判断是否选中
            //找到 id=key 下的 option值
            var _options = [];
            //遍历options 的值
            $('#columnProperty .select-options').each(function () {
                _options.push({
                    text: $(this).find('input[name=select-text]').val(),
                    value: $(this).find('input[name=select-value]').val()
                });
                // console.log($(this));
            });
            //_json.options 节点值替换为 _options 值
            _json.options = JSON.parse(JSON.stringify(_options));
        });
        //属性模块的 input keyup
        $(document).off('keyup', '#columnProperty .layui-input').on('keyup', '#columnProperty .layui-input', function () {
            if ($(this).attr("name") !== undefined) {
                //去改变值
                //改变json的值
                var _key = $(this).attr("name");
                var _value = $(this).val();
                var _json = options.selectItem;
                if (_key === 'id') {
                    return;
                }
                if (_key === 'label' || _key === 'width' || _key === 'interval' || _key === 'iconPickerLimit' || _key === 'iconPickerCellWidth' || _key === 'buttonVlaue') {
                    _json[_key] = _value;
                    that.components[_json.tag].update(_json); //局部更新
                }
                if (_key === 'uploadUrl' || _key === 'cronUrl') {
                    _json[_key] = _value;
                }
                if (_key === 'placeholder') {
                    _json[_key] = _value;
                    $('#' + _json.id).find('.layui-input').attr('placeholder', _value);
                }
                if (_key === 'height') {
                    _json[_key] = _value;
                    if (_json.tag === 'editor') {
                        that.components[_json.tag].update(_json); //局部更新
                    }
                    if (_json.tag === 'carousel') {
                        _json[_key] = _value;
                        that.components[_json.tag].update(_json); //局部更新
                    }
                }
                if (_key === 'defaultValue') {
                    _json[_key] = _value;
                    if (_json.tag === 'slider') {
                        var resultNumber = that.replaceNumber(_value);
                        _json[_key] = resultNumber;
                        $(this).val(resultNumber);
                        slider.render({
                            elem: '#' + _json.tag + _json.id,
                            value: _json.defaultValue, //初始值
                            min: _json.minValue,
                            max: _json.maxValue,
                            step: _json.stepValue,
                            disabled: _json.disabled
                        });
                    } else if (_json.tag === 'rate') {
                        rate.render({
                            elem: '#' + _json.tag + _json.id,
                            value: _json.defaultValue,
                            text: _json.text,
                            length: _json.rateLength,
                            half: _json.half,
                            readonly: _json.readonly
                        });
                    } else if (_json.tag == 'textarea') {
                        $('#' + _json.id).find('.layui-textarea').text(_value);
                    } else if (_json.tag == 'colorpicker') {
                        that.components[_json.tag].update(_json); //局部更新
                    } else if (_json.tag == 'iconPicker') {
                        that.components[_json.tag].update(_json); //局部更新
                    } else if (_json.tag == 'numberInput') {
                        var resultNumber = that.replaceNumber(_value);
                        _json[_key] = resultNumber;
                        $(this).val(resultNumber);
                        that.components[_json.tag].update(_json); //局部更新
                    } else {
                        $('#' + _json.id).find('.layui-input').val(_value);
                    }
                }
                if (_key === "minValue" || _key === "maxValue") {
                    var resultNumber = that.replaceNumber(_value);
                    _json[_key] = resultNumber;
                    $(this).val(resultNumber);
                    if (_json.tag === 'slider') {
                        slider.render({
                            elem: '#' + _json.tag + _json.id,
                            value: _json.defaultValue, //初始值
                            min: _json.minValue,
                            max: _json.maxValue,
                            step: _json.stepValue,
                            disabled: _json.disabled
                        });
                    } else if (_json.tag == 'numberInput') {
                        that.components[_json.tag].update(_json); //局部更新
                    }
                }
                if (_key === 'stepValue') {
                    _json[_key] = _value;
                    if (_json.tag == 'numberInput') {
                        that.components[_json.tag].update(_json); //局部更新
                    }
                }
                if (_key === 'rateLength') {
                    _json[_key] = _value;
                    if (_json.tag === 'rate') {
                        rate.render({
                            elem: '#' + _json.tag + _json.id,
                            value: _json.defaultValue,
                            text: _json.text,
                            length: _json.rateLength,
                            half: _json.half,
                            readonly: _json.readonly
                        });
                    }
                }
                if (_key === 'document') {
                    _json[_key] = _value;
                }
                if (_key === 'readonly') {
                    _json[_key] = _value;
                    $('#' + _json.id).find('.layui-input').attr('readonly', _value);
                }
                if (_key === 'listShow') {
                    _json[_key] = _value;
                }
                if (_key === 'select-text' || _key === 'select-value' || _key === 'radio-text' || _key === 'radio-value' || _key === 'checkbox-text' || _key === 'checkbox-value') {
                    //找到 id=key 下的 option值
                    var _index = parseInt($(this).parent().parent().attr("data-index"));
                    if (_key === 'select-text' || _key === 'radio-text' || _key === 'checkbox-text') {
                        _json.options[_index].text = $(this).val();
                    } else {
                        _json.options[_index].value = $(this).val();
                    }
                    that.components[_json.tag].update(_json); //局部更新
                }
                if (_key === 'carousel-text' || _key === 'carousel-value') {
                    //找到 id=key 下的 option值
                    var _options = [];
                    //遍历options 的值
                    $('#columnProperty .select-options').each(function () {
                        _options.push({
                            text: $(this).find('input[name=carousel-text]').val(),
                            value: $(this).find('input[name=carousel-value]').val()
                        });
                        // console.log($(this));
                    });
                    //_json.options 节点值替换为 _options 值
                    _json.options = JSON.parse(JSON.stringify(_options));
                    that.components[_json.tag].update(_json); //局部更新
                }
            }
        });
        // 系统关键字
        var SYSTEM_KEY_ARRAY = ['id', 'uid', 'gmt_create', 'creator', 'gmt_modified', 'modifier', 'is_delete', 'MAIN_TITLE', 'attachments', 'attachmentBtn', 'showAttachmentBtn', 'goBackBtn', 'printBtn', 'forcedEndBtn', 'ccs', 'ccBtn', 'transferBtn'];
        // 更新 option json
        $(document).off('blur', '#columnProperty .layui-input').on('blur', '#columnProperty .layui-input', function () {
            if ($(this).attr("name") !== undefined) {
                //改变json的值
                var _key = $(this).attr("name");
                var _value = $(this).val();
                var _json = options.selectItem;
                var _oldid = _json.id;
                if (_key === 'id' && _value !== _oldid) {
                    for(var i = 0, systemKey; systemKey = SYSTEM_KEY_ARRAY[i++];) {
                        if(_value === systemKey) {
                            layer.msg(systemKey +'为关键字');
                            _json[_key] = _oldid;
                            that.renderForm();
                            return;
                        }
                    }
                    //检测id是否存在重复
                    var _checkid = that.findJsonItem(options.data, _value);
                    if (_checkid === undefined) {
                        _json[_key] = _value;
                        that.renderForm();
                    } else {
                        layer.msg('ID已经存在');
                        _json[_key] = _oldid;
                        that.renderForm();
                    }
                }
            }
        });
        //预览
    }
    //递归赋值
    Class.prototype.replaceNumber = function (value) {
        value = value.replace(/[^\d]/g, '');
        if ('' != value) {
            value = parseInt(value);
        }
        return value;
    }
    /* 加入copy选项删除 */
    Class.prototype.addCopyDeleteClick = function () {
        var that = this,
            options = that.config;
        if (options.data === undefined) {
            return;
        }
        if (typeof (options.data) === 'string') {
            options.data = JSON.parse(options.data);
        }
        //复制当前节点
        $('#formDesignerForm  .layui-form-item .widget-view-action .layui-icon-file').on('click', function (e) {
            e.stopPropagation();
            //在json中插入
            if (options.data === undefined) {
                return;
            }
            if (typeof (options.data) === 'string') {
                options.data = JSON.parse(options.data);
            }
            var _id = document.elementFromPoint(e.pageX, e.pageY).parentElement.parentElement.dataset.id;
            if (_id !== undefined) {
                options.selectItem = that.copyJsonAfterItem(options.data, _id);
            }
            that.renderForm();
        });
        $('#formDesignerForm  .layui-form-item .layui-icon-delete').on('click', function (e) {
            e.stopPropagation();
            //获取当前组件的组件id
            var _id = document.elementFromPoint(e.pageX, e.pageY).parentElement.parentElement.dataset.id;
            if (_id !== undefined) {
                options.selectItem = that.deleteJsonItem(options.data, _id);
            }
            //document.elementFromPoint(e.pageX,e.pageY).parentElement.parentElement.parentElement.dataset 获取父grid的信息
            // 删除刷新表单与属性
            that.renderForm();
            // console.log('click layui-icon layui-icon-delete');
        });
    };
    /* 触发 grid 的 sortablejs 事件*/
    Class.prototype.bindGridSortEvent = function (json) {
        var that = this;
        var options = that.config;
        var objs = $('#' + json.id + 'Box .widget-col-list');
        //遍历他下面的节点
        for (var i = 0; i < objs.length; i++) {
            var el = objs[i];
            var ops = {
                group: {
                    name: 'formgroup'
                },
                handle: '.widget-view-drag',
                ghostClass: "ghost",
                animation: 150,
                onAdd: function (evt) {
                    var parentItem = JSON.parse(JSON.stringify(that.findJsonItem(options.data, evt.item.parentElement.parentElement.dataset.id)));
                    var index = evt.newIndex;
                    var colIndex = evt.item.parentElement.dataset.index;
                    if (evt.item.dataset.id != undefined) {
                        //表示从其他地方移动过来
                        var _fromItem = JSON.parse(JSON.stringify(that.findJsonItem(options.data, evt.item.dataset.id)));
                        var _oldid = _fromItem.id;
                        _fromItem.id = that.autoId(_fromItem.tag);
                        _fromItem.index = index;
                        parentItem.columns[colIndex].list.splice(index + 1, 0, _fromItem);
                        that.findAndCopyJson(options.data, parentItem, evt.item.parentElement.parentElement.dataset.id);
                        that.deleteJsonItem(options.data, _oldid);
                    } else {
                        /* 向指定目标放入数据 splice */
                        var tag = evt.item.dataset.tag;
                        _id = that.autoId(tag);
                        var _newitem = that.components[tag].jsonData(_id, evt.newIndex);
                        _newitem.index = index;
                        parentItem.columns[colIndex].list.splice(index + 1, 0, _newitem);
                        that.findAndCopyJson(options.data, parentItem, evt.item.parentElement.parentElement.dataset.id);
                        options.selectItem = _newitem;
                    }
                    that.renderForm();
                },
                //拖动结束
                onEnd: function (evt) {
                    //console.log(evt);
                }
            };
            var gridSortable = Sortable.create(el, ops);
        }
    };
    //递归赋值
    Class.prototype.findAndCopyJson = function (json, parentItem, id) {
        var that = this;
        for (var i = 0; i < json.length; i++) {
            if (json[i].id === id) {
                json[i] = parentItem;
            } else {
                if (json[i].tag === 'grid') {
                    for (var j = 0; j < json[i].columns.length; j++) {
                        if (json[i].columns[j].list.length > 0) {
                            that.findAndCopyJson(json[i].columns[j].list, parentItem, id);
                        }
                    }
                }
            }
        }
    }
    //渲染视图
    Class.prototype.render = function () {
        var that = this;
        var options = that.config;
        options.elem = $(options.elem);
        options.id = options.id || options.elem.attr('id') || that.index;

        //cache 模式
        /* 输入型组件 开始*/
        var _listhtml = ""
        _listhtml += '<div class="components-title">{0} </div>'.format(formField.c1.name);
        _listhtml += '<div class="components-draggable" id="c1">';
        $.each(formField.c1.list, function (index, item) {
            _listhtml += '<div class="components-item" data-tag="{0}"><div class="components-body"><i class="icon iconfont icon-input"></i>{1}</div></div>'.format(item, lang[item]);
        });
        _listhtml += '</div>';
        _listhtml += '<div class="components-title">{0} </div>'.format(formField.c2.name);
        _listhtml += '<div class="components-draggable" id="c2">';
        /* 选择型组件 开始*/
        $.each(formField.c2.list, function (index, item) {
            _listhtml += '<div class="components-item" data-tag="{0}"><div class="components-body"><i class="icon iconfont icon-input"></i>{1}</div></div>'.format(item, lang[item]);
        });
        _listhtml += '</div>';
        _listhtml += '<div class="components-title">{0} </div>'.format(formField.c3.name);
        _listhtml += '<div class="components-draggable" id="c3">';
        /* 布局型组件 开始*/
        $.each(formField.c3.list, function (index, item) {
            _listhtml += '<div class="components-item" data-tag="{0}"><div class="components-body"><i class="icon iconfont icon-input"></i>{1}</div></div>'.format(item, lang[item]);
        });
        _listhtml += '</div>';
        _listhtml += '<div class="components-title">{0} </div>'.format(formField.c4.name);
        _listhtml += '<div class="components-draggable" id="c4">';
        /* 选择型组件 开始*/
        $.each(formField.c4.list, function (index, item) {
            _listhtml += '<div class="components-item" data-tag="{0}"><div class="components-body"><i class="icon iconfont icon-input"></i>{1}</div></div>'.format(item, lang[item]);
        });
        _listhtml += '</div>';
        _listhtml += '<div class="components-title">{0} </div>'.format(formField.c5.name);
        _listhtml += '<div class="components-draggable" id="c5">';
        /* 选择型组件 开始*/
        $.each(formField.c5.list, function (index, item) {
            _listhtml += '<div class="components-item" data-tag="{0}"><div class="components-body"><i class="icon iconfont icon-input"></i>{1}</div></div>'.format(item, lang[item]);
        });
        _listhtml += '</div>';
        options.elem.html(TP_MAIN);
        $('#components-form-list').append(_listhtml);
        //排序事件注册
        var sortable1 = Sortable.create(document.getElementById("c1"), {
            group: {
                name: 'formgroup',
                pull: 'clone', //克隆本区域元素到其他区域
                put: false, //禁止本区域实现拖动或拖入
            },
            // ghostClass: "ghost",
            sort: false,
            animation: 150,
            onEnd: function (evt) {
                // console.log('onEnd.foo:', [evt.item, evt.from]);
                // console.log(evt.oldIndex);
                // console.log(evt.newIndex);
                var itemEl = evt.item;
                // console.log(itemEl);
            }
        });
        var sortable2 = Sortable.create(document.getElementById("c2"), {
            group: {
                name: 'formgroup',
                pull: 'clone',
                put: false, //禁止本区域实现拖动或拖入
            },
            sort: false,
            animation: 150
        });
        var sortable3 = Sortable.create(document.getElementById("c3"), {
            group: {
                name: 'formgroup',
                pull: 'clone',
                put: false, //禁止本区域实现拖动或拖入
            },
            sort: false,
            animation: 150
        });
        var sortable4 = Sortable.create(document.getElementById("c4"), {
            group: {
                name: 'formgroup',
                pull: 'clone',
                put: false, //禁止本区域实现拖动或拖入
            },
            sort: false,
            animation: 150
        });
        var sortable5 = Sortable.create(document.getElementById("c5"), {
            group: {
                name: 'formgroup',
                pull: 'clone',
                put: false, //禁止本区域实现拖动或拖入
            },
            sort: false,
            animation: 150
        });
        // 表单设计
        var formItemSort = Sortable.create(document.getElementById("formDesignerForm"), {
            group: {
                name: 'formgroup'
            },
            handle: '.widget-view-drag',
            ghostClass: "ghost",
            animation: 200,
            /**
             * 不同元素之间的拷贝
             * 如果是从组件区域则是创建一个新的节点
             * 如果是从设计区则是移动一个节点
             *  */
            onAdd: function (evt) {
                var columncount = evt.item.dataset.columncount;
                if (columncount === undefined) {
                    columncount = 2;
                }
                // 没有表单JSON数据
                if (options.data === undefined) {
                    return;
                }
                if (typeof (options.data) === 'string') {
                    options.data = JSON.parse(options.data);
                }
                //注意这里的一个bug，newIndex 第一次拖动也是1 第二次拖动也是1
                if (options.data.length === 0) {
                    evt.newIndex = 0;
                }
                if (evt.item.dataset.id !== undefined) {
                    /*根据id的新算法 复制一份副本 删除json中的节点 再插入节点*/
                    var _item = that.findJsonItem(options.data, evt.item.dataset.id);
                    options.selectItem = _item;
                    that.deleteJsonItem(options.data, evt.item.dataset.id);
                    options.data.splice(evt.newIndex + 1, 0, _item);
                } else {
                    var _id = that.autoId(evt.item.dataset.tag);
                    /* 向现有的表单数据中增加新的数组元素 splice */
                    var _newitem = that.components[evt.item.dataset.tag].jsonData(_id, evt.newIndex, columncount);
                    //如果是 grid 呢，需要知道几列
                    options.selectItem = _newitem;
                    options.data.splice(evt.newIndex, 0, _newitem); //options.data.splice(evt.newIndex + 1, 0, _newitem);
                    /* 如果evt.item.dataset.id 有值表示从已经存在的布局中获取了元素，这个时候要在数据源中删除这个元素*/
                }
                //局部更新 只要更新 designer 设计区部分
                that.renderForm();
            },
            onEnd: function (evt) {
                var newIndex = evt.newIndex;
                var oldIndex = evt.oldIndex;
                //只有当to的目标容器是 formDesignerForm 才出发次逻辑
                if (evt.to.id === 'formDesignerForm') {
                    that.moveItem(evt.oldIndex, evt.newIndex);
                }
            }
        });
        //移动视图
        Class.prototype.moveItem = function (oldIndex, newIndex) {
            var that = this,
                options = that.config;
            var newData = options.data[newIndex];
            var oldData = options.data[oldIndex];
            options.data[newIndex] = oldData;
            options.data[oldIndex] = newData;
        }

        /**
         * 获取字段dom
         * @param dataList
         * @param dom
         */
        function getFieldDom(dataList, dom) {
            $.each(dataList, function (index, item) {
                var elem = $(that.components[item.tag].render(item, false));
                dom.append(elem);
                if (item.tag === 'grid') {
                    getGridDom(item.columns, elem);
                }
            });
        }

        /**
         * 获取网格的HTML
         * @param listData
         * @param dom
         */
        function getGridDom(listData, dom) {
            $.each(listData, function (index, item) {
                var colElem = dom.find('.column' + index);
                if (item.list.length > 0) {
                    getFieldDom(item.list, colElem);
                }
            });
        }

        /**
         * 查询字段列表
         * @param fieldData
         */
        function listField(fieldData) {
            var fieldArray = [];
            $.each(fieldData, function (index, item) {
                var elem = $(that.components[item.tag].render(item, false));
                fieldArray.push({
                    data: item,
                    elem: elem
                });
                if (item.tag === 'grid') {
                    getGridDom(item.columns, elem);
                }
            });
            return fieldArray;
        }

        // 提交
        $('#save').on('click', function () {
            var fieldData = options.data;
            if (fieldData.length == 0) {
                top.dialog.msg('请添加组件');
                return;
            }
            var formName = $('#formName').val();
            if (!formName) {
                top.dialog.msg('请输入表单名称');
                return;
            }
            var formSummary = $('#formSummary').val();
            if (!formSummary) {
                top.dialog.msg('请输入表单描述');
                return;
            }
            var formType = $('#formType').val();
            if(!formType) {
                top.dialog.msg('请选择表单类型');
                return;
            }
            var mainTitleTpl = $('#mainTitleTpl').val();
            var fieldHtmlArray = listField(fieldData);
            var fields = [];
            $.each(fieldHtmlArray, function (index, item) {
                fields.push({
                    data: item.data,
                    html: item.elem.prop('outerHTML')
                })
            });
            top.dialog.confirm(top.dataMessage.commit, function (index) {
                top.dialog.close(index);
                var loadLayerIndex;
                top.restAjax.post(top.restAjax.path('api/form-design/save', []), {
                    formCode: options.formCode,
                    formName: formName,
                    formSummary: formSummary,
                    formType: formType,
                    mainTitleTpl: mainTitleTpl,
                    data: fieldData,
                    fields: fields,
                }, null, function (code, data) {
                    var layerIndex = top.dialog.msg(top.dataMessage.commitSuccess, {
                        time: 0,
                        btn: [top.dataMessage.button.yes, top.dataMessage.button.no],
                        shade: 0.3,
                        yes: function (index) {
                            top.dialog.close(index);
                            window.location.reload();
                        },
                        btn2: function () {
                            parent.layer.close(parent.layer.getFrameIndex(window.name));
                        }
                    });
                }, function (code, data) {
                    top.dialog.msg(data.msg);
                }, function () {
                    loadLayerIndex = top.dialog.msg(top.dataMessage.committing, {icon: 16, time: 0, shade: 0.3});
                }, function () {
                    top.dialog.close(loadLayerIndex);
                });
            });
        });
        that.renderForm();
    };

    /* 递归渲染组件 */
    Class.prototype.renderComponents = function (jsondata, elem) {
        var that = this,
            options = that.config;
        $.each(jsondata, function (index, item) {
            item.index = index; //设置index 仅仅为了传递给render对象，如果存在下级子节点那么 子节点的也要变动
            if (options.selectItem === undefined) {
                elem.append(that.components[item.tag].render(item, false));
            } else {
                if (options.selectItem.id === item.id) {
                    elem.append(that.components[item.tag].render(item, true));
                    //显示当前的属性
                    that.components[item.tag].property(item);
                    that.bindPropertyEvent(item);
                } else {
                    elem.append(that.components[item.tag].render(item, false));
                }
            }
            if (item.tag === 'grid') {
                that.bindGridSortEvent(item);
                $.each(item.columns, function (index2, item2) {
                    //获取当前的 DOM 对象
                    if (item2.list.length > 0) {
                        var elem2 = $('#' + item.id + '_column_' + index2);
                        that.renderComponents(item2.list, elem2);
                    }
                });
            } else if (item.tag === 'slider') {
                laySlider.componentRender(item);
            } else if (item.tag === 'numberInput') {
                numberInput.componentRender(item);
            } else if (item.tag === 'date') {
                date.componentRender(item);
            } else if (item.tag === 'laySign') {
                laySign.componentRender(item);
            } else if (item.tag === 'rate') {
                layRate.componentRender(item);
            } else if (item.tag === 'carousel') {
                layCarousel.componentRender(item);
            } else if (item.tag === 'uploadImage') {
                uploadImage.componentRender(item);
            } else if (item.tag === 'uploadFile') {
                uploadFile.componentRender(item);
            } else if (item.tag === 'uploadVideo') {
                uploadVideo.componentRender(item);
            } else if (item.tag === 'uploadAudio') {
                uploadAudio.componentRender(item);
            }
        });
    };

    /* 重新渲染设计区*/
    Class.prototype.renderForm = function () {
        var that = this,
            options = that.config;
        var elem = $('#formDesignerForm');
        // 清空表单
        elem.empty();
        // 清空属性配置
        $('#columnProperty').empty();
        that.renderComponents(options.data, elem);

        //选中的节点只有一个
        if (options.selectItem !== undefined) {
            var _draghtml1 = '<div class="widget-view-action"  id="widget-view-action"><i class="layui-icon layui-icon-file"></i><i class="layui-icon layui-icon-delete"></i></div><div class="widget-view-drag" id="widget-view-drag"><i class="layui-icon layui-icon-screen-full"></i></div>';
            var len = $('#' + options.selectItem.id +'Box').children().length;
            if ($('#widget-view-action')) { //已存在
                $('#widget-view-action').remove();
            }
            $('#' + options.selectItem.id +'Box').children(len - 1).after(_draghtml1);
            $('#formDesignerForm .layui-form-item').removeClass('active');
            //给当前元素增加class
            $('#' + options.selectItem.id +'Box').addClass('active');
            //设置当前选择项目的拷贝删除的事件
            //显示当前的属性
            that.components[options.selectItem.tag].property(options.selectItem);
            if (options.selectItem.tag === "select" || options.selectItem.tag === "checkbox" || options.selectItem.tag === "radio" || options.selectItem.tag === "carousel") {
                var sortable = Sortable.create(document.getElementById(options.selectItem.tag), {
                    group: {
                        name: 'propertygroup',
                    },
                    ghostClass: "ghost",
                    handle: '.select-option-drag',
                    dataIdAttr: 'data-index',
                    animation: 150,
                    onEnd: function (evt) {
                        if (options.selectItem === undefined) {
                            return;
                        }
                        var indexArray = sortable.toArray();
                        var newJson = [];
                        for (var i = 0; i < indexArray.length; i++) {
                            newJson.push(options.selectItem.options[indexArray[i]]);
                        }
                        options.selectItem.options = newJson;
                        //that.renderForm();
                        that.components[options.selectItem.tag].update(options.selectItem);
                    }
                });
            }
            that.bindPropertyEvent(options.selectItem);
        }
        that.addClick();
        /* 向 拷贝 删除 按钮添加 click 动作 */
        that.addCopyDeleteClick();
        if (options.data.length != 0) {
            for (var i = 0; i < options.data.length; i++) {
                if (options.data[i].tag === 'grid') {
                    for (var j = 0; j < options.data[i].columns.length; j++) {
                        for (var k = 0; k < options.data[i].columns[j].list.length; k++) {
                            if (options.data[i].columns[j].list[k].tag === 'select') {
                                $('#' + options.data[i].columns[j].list[k].id + 'Box .layui-input-block div.layui-unselect.layui-form-select').css({
                                    width: '{0}'.format(options.data[i].columns[j].list[k].width)
                                });
                            }
                        }
                    }
                } else {
                    if (options.data[i].tag === 'select') {
                        $('#' + options.data[i].id + 'Box .layui-input-block div.layui-unselect.layui-form-select').css({
                            width: '{0}'.format(options.data[i].width)
                        });
                    }
                }
            }
        }
        // 表单属性
        $('#formName').val(options.formName);
        $('#formSummary').val(options.formSummary);
        $('#formType').val(options.formType);
        $('#mainTitleTpl').val(options.mainTitleTpl);
        form.render();
    };
    Class.prototype.reload = function (id, options) {
        var that = this;
        options = options || {}; //如果是空的话，就赋值 {} 
        that.render();
    }
    //核心入口 初始化一个 regionSelect 类
    formDesigner.render = function (options) {
        var ins = new Class(options);
        return thisIns.call(ins);
    };
    exports('formDesigner', formDesigner);
});