Exemple #1
0
view.getRenderer = function (tpl) {
    var target = this.getTarget(tpl) || tpl;
    var renderer = etplEngine.getRenderer(target);
    if (!renderer) {
        renderer = etplEngine.compile(tpl);
    }

    return renderer;
};
Exemple #2
0
    /**
     * 编译模版
     *
     * @public
     * @param {View} view 视图对象
     * @param {string|Array.<string>} str 模版
     */
    function compileTemplate(view, str) {
        if (Array.isArray(str)) {
            str = str.join('');
        }

        var config = extend({}, view.templateConfig || {});
        var filters = {};
        if (config.filters) {
            filters = config.filters;
            delete config.filters;
        }

        // 新建模版引擎
        var tplEngine = new etpl.Engine(config);
        Object.keys(filters).forEach(function (key) {
            tplEngine.addFilter(key, filters[key]);
        });

        // 保存默认render
        var defaultRender = tplEngine.compile(str);

        // 如果没有默认render就是模版编译失败了
        if (!defaultRender) {
            throw new Error('compile template fail');
        }

        // 保存原始的render
        var orgRender = tplEngine.render;

        view.template = tplEngine;
        // 重载render以支持无target的情况
        view.template.render = function (name, data) {
            // 扩展通用模版数据
            data = extend({}, view.templateData, data);

            var res = '';
            // 如果只有一个参数 或者target为null
            // 则使用默认render
            if (arguments.length < 2 || !name) {
                res = defaultRender(name || data);
            }
            else {
                res = orgRender.call(this, name, data);
            }

            return res;
        };
    }
Exemple #3
0
    /**
     * 渲染 esui.Select 组件并绑定 change 事件
     *
     * @param {Object} componentsConf 组件的配置,就是 json 中的配置
     * @param {er.View} view 当前 View 实例
     */
    function renderElem(componentsConf, view) {

        formSubmitData.submitName = componentsConf.submitName || '';

        var containerId = componentsConf.containerId;
        var containerDom = $('#' + containerId);

        var etplEngine = new etpl.Engine();
        etplEngine.compile(tpl);

        var componentList = componentsConf.list;
        var etplRenderOpts = {
            componentList: componentList,
            submitName: formSubmitData.submitName
        };

        containerDom.html(
            etplEngine.render('selectAddr', etplRenderOpts)
        );

        esui.init(
            containerDom[0],
            {
                viewContext: view.viewContext
            }
        );

        // data 只有在修改表单的时候才会有
        var editData = componentsConf.data;

        for (var i = 0, len = componentList.length; i < len; i++) {
            var component = componentList[i];
            view.get('prov' + formSubmitData.submitName + component.index).updateDatasource(povince.getAll());
            // 默认选中北京,如果是修改,那么回填之前的值
            view.get('prov' + formSubmitData.submitName + component.index).setValue(
                (editData && editData[i]) ? editData[i].prov : 0
            );
            view.get('prov' + formSubmitData.submitName + component.index).on(
                'change',
                lib.bind(
                    changeProv,
                    {
                        view: view,
                        index: component.index,
                        formSubmitData: formSubmitData
                    }
                )
            );

            view.get('city' + formSubmitData.submitName + component.index).updateDatasource(
                city.getCityByProvince(view.get('prov' + formSubmitData.submitName + component.index).getValue())
            );
            view.get('city' + formSubmitData.submitName + component.index).setValue(
                (editData && editData[i]) ? editData[i].city : 0
            );
            view.get('city' + formSubmitData.submitName + component.index).on(
                'change',
                lib.bind(
                    changeCity,
                    {
                        view: view,
                        index: component.index,
                        formSubmitData: formSubmitData
                    }
                )
            );

            view.get('addr' + formSubmitData.submitName + component.index).setValue(
                (editData && editData[i]) ? editData[i].addr : ''
            );
            view.get('addr' + formSubmitData.submitName + component.index).on(
                'change',
                lib.bind(
                    changeAddr,
                    {
                        view: view,
                        index: component.index,
                        formSubmitData: formSubmitData
                    }
                )
            );

            formSubmitData.dataList.push({
                prov: view.get('prov' + formSubmitData.submitName + component.index).getValue(),
                city: view.get('city' + formSubmitData.submitName + component.index).getValue(),
                addr: view.get('addr' + formSubmitData.submitName + component.index).getValue() || ''
            });
        }

        // 初始化的时候也需要 fire
        // 因为可能编辑 form 的时候,不改动这个组件的值
        exports.fire(
            formSubmitData.submitName + 'formSubmitDataChange',
            {
                curFormData: formSubmitData,
                componentCallback: submitDataFilter
            }
        );

        return formSubmitData;
    }
Exemple #4
0
function createBlogPages(env) {
    var etplEngin = new etpl.Engine();
    etplEngin.compile(fs.readFileSync(path.join(__dirname, 'site/template.tpl.html')).toString());

    etplEngin.addFilter('md', function (mdCode) {
        return marked(mdCode)
            .replace(/url\(\.\/imgs\//g, 'url(../../imgs/')
            .replace(/src="\.\/imgs\//g, 'src="../../imgs/');
    });

    var config = JSON.parse(fs.readFileSync('./site/' + env + '.conf'));

    var mdFiles = fs.readdirSync(path.join(__dirname, 'blogs'));
    mdFiles = mdFiles.filter(function (fileName) {
        return /\.md$/.test(fileName);
    }).map(function (fileName) {
        var fullPath = path.join(__dirname, 'blogs', fileName);
        var content = fs.readFileSync(fullPath).toString();
        var time = getBlogTime(content);
        return {
            fileName: fileName,
            path: fullPath,
            content: content,
            time: time,
            timeText: moment(time).format('YYYY-MM-DD HH:mm:ss'),
            brief: getBlogBrief(content),
            title: fileName.slice(0, -3)
        };
    });

    var blogs = mdFiles.sort(function (a, b) {
        return b.time.getTime() - a.time.getTime();
    });

    blogs.forEach(function (blog) {
        fs.writeFileSync(
            path.join(__dirname, '/site/blogs', blog.fileName.slice(0, -3) + '.html'),
            etplEngin.getRenderer('blogPage')(getData({blog: blog}))
        );
    });

    fs.writeFileSync(
        path.join(__dirname, 'site/index.html'),
        etplEngin.getRenderer('indexPage')(getData({blogs: blogs}))
    );
    fs.writeFileSync(
        path.join(__dirname, '/README.md'),
        etplEngin.getRenderer('readmeTitleList')(getData({blogs: blogs}))
    );

    function getData(local) {
        return u.extend({}, config, local);
    }

    function getBlogBrief(mdStr) {
        var briefMatch = mdStr.match(/<!--\s*config.brief:(.+)-->/);
        if (briefMatch && briefMatch.length >= 2) {
            return briefMatch[1].replace(/^\s|\s$/g, '');
        }
        return '';
    }

    // 拿到 blog 发布时间
    function getBlogTime(mdStr) {
        var timeMatch = mdStr.match(/<!--\s*config.time:\s*([0-9\-:\s]+)\s*-->/);
        if (timeMatch && timeMatch.length >= 2) {
            return new Date(timeMatch[1]);
        }
        return new Date();
    }
}
define(function (require) {

    var dynamicAddFormTpl = require('er/tpl!./dynamicForm.tpl.html');

    var $ = require('jquery');
    var _ = require('underscore');
    var util = require('er/util');
    var etpl = require('etpl');
    var esui = require('esui');
    var Deferred = require('er/Deferred');
    var FormView = require('./FormView');
    var dynamicUtil = require('./dynamicUtil');

    var LANG_PKG = require('../lang').getLangPkg();

    var etplEngine = new etpl.Engine();
    etplEngine.compile(dynamicAddFormTpl);

    /**
     * 动态 Form View 基类
     *
     * @extends FormView
     * @constructor
     */
    function DynamicFormView() {
        FormView.apply(this, arguments);
    }

    DynamicFormView.prototype.template = 'dynamicForm';

    /**
     * form 提交成功后的回调函数
     */
    DynamicFormView.prototype.successFunc = function () {};

    /**
     * form 提交成功后的回调函数
     * 常规的错误处理函数已经在 ejson 中封装,会弹出错误信息
     * 这里的 errorFunc 是为了做一些自定义的错误处理
     */
    DynamicFormView.prototype.errorFunc = function () {};

    /**
     * 容器渲染完毕后做一些准备工作
     * 例如控制元素可见性及绑定事件等DOM操作
     *
     * @override
     */
    DynamicFormView.prototype.enterDocument = function () {
        var me = this;
        var model = me.model;

        var formItemConfigs = model.get('formItemConfigs');

        if (_.isArray(formItemConfigs)) {
            buildUIProperties(
                formItemConfigs, model
            ).then(
                function (ret) {
                    // 触发 submit 事件的参数
                    var submitEvtArgs = {
                        componentData: {}
                    };

                    var properties = ret.properties;
                    // DynamicFormView.prototype.uiProperties = properties;
                    me.uiProperties = properties; // 要挂载在 me 上,这样子类才能生效

                    // 设置 uiEvents 要在执行父类的 enterDocument 之前
                    me.uiEvents = _.extend(
                        {},
                        me.uiEvents,
                        {
                            'form:submit': function (e) {
                                submitEvtArgs = _.extend(
                                    submitEvtArgs,
                                    {
                                        form: me.getFormInstance(),
                                        ideaInfo: model.get('ideaInfo') // 修改才有的
                                    }
                                );
                                me.fire('submit', submitEvtArgs);
                            }
                        }
                    );

                    FormView.prototype.enterDocument.apply(me, arguments);

                    initTip(me, properties);

                    // 对 components 做处理
                    var components = properties.components;
                    if (components.length) {
                        dealComponents(components, submitEvtArgs, me);
                    }

                    var dynamicItems = properties.dynamicItems;
                    if (dynamicItems) {
                        dealDynamicItems(dynamicItems, me);
                    }
                }
            );
        }
    };

    /**
     * 动态添加表单项的处理
     *
     * @param {Object} dynamicItems 要添加的表单项的配置
     * @param {View} view 当前的 View 对象
     */
    function dealDynamicItems(dynamicItems, view) {
        $('.add-items').each(
            function (i, v) {
                v = $(v);
                var refIdentify = v.data('refIdentify');
                var maxCount = dynamicItems[refIdentify].maxCount;
                var candidateAddItemsConfig = dynamicItems[refIdentify].list;

                var alreadyAddItemsConfig = dynamicItems[refIdentify].alreadyAddItemsConfig;
                var len;
                if (alreadyAddItemsConfig && (len = alreadyAddItemsConfig.length)) {
                    v.attr('data-already-addcount', len);

                    for (var j = 0, l = alreadyAddItemsConfig.length; j < l; j++) {

                        var addItemContainer = $('<div class="add-items-container"></div>');
                        var html = '';
                        html += etplEngine.render('dynamicForm', {
                            formItemConfigs: alreadyAddItemsConfig[j],
                            i18n: {
                                'QXZ': LANG_PKG.QXZ,
                                'ZDXZ': LANG_PKG.ZDXZ,
                                'Ge': LANG_PKG.Ge,
                                'BT': LANG_PKG.BT
                            }
                        });

                        addItemContainer.attr('data-index', alreadyAddItemsConfig[j].index).html(html);

                        v.parents('.form-row').append(addItemContainer);

                        esui.init(
                            addItemContainer[0],
                            {
                                viewContext: view.viewContext
                            }
                        );
                    }
                }

                var alreadyAddcount = v.attr('data-already-addcount') || 0;
                alreadyAddcount = parseInt(alreadyAddcount, 10);
                if (alreadyAddcount >= maxCount) {
                    v.attr('disabled', 'disabled');
                }
                var maxCountArr = [];
                for (var q = 1; q <= maxCount; q++) {
                    maxCountArr.push(q);
                }
                v.on(
                    'click',
                    {
                        view: view,
                        itemsConfig: candidateAddItemsConfig,
                        maxCount: maxCount,
                        maxCountArr: maxCountArr,
                        alreadyAddItemsConfig: alreadyAddItemsConfig,
                        dynamicItems: dynamicItems,
                        refIdentify: refIdentify
                    },
                    addItemFunc
                );
                // if (alreadyAddcount < maxCount) {
                //     var maxCountArr = [];
                //     for (var q = 1; q <= maxCount; q++) {
                //         maxCountArr.push(q);
                //     }
                //     v.on(
                //         'click',
                //         {
                //             view: view,
                //             itemsConfig: candidateAddItemsConfig,
                //             maxCount: maxCount,
                //             maxCountArr: maxCountArr,
                //             alreadyAddItemsConfig: alreadyAddItemsConfig,
                //             dynamicItems: dynamicItems,
                //             refIdentify: refIdentify
                //         },
                //         addItemFunc
                //     );
                // }
                // else {
                //     v.attr('disabled', 'disabled');
                // }

                $('.form-data-body').delegate(
                    '.del-items',
                    'click',
                    {
                        addNode: v,
                        view: view,
                        maxCount: maxCount,
                        refIdentify: refIdentify
                    },
                    delItemFunc
                );
            }
        );
    }

    /**
     * 删除之前动态添加的 formItem
     *
     * @param {jQuery.Element} e jQuery 事件对象
     */
    function delItemFunc(e) {
        e.stopPropagation();
        e.preventDefault();

        var target = $(e.currentTarget);

        var data = e.data;
        var refIdentify = data.refIdentify;

        if (refIdentify == target.attr('data-ref-identify')) {
            $(target.parents('.add-items-container')).remove();
            e.data.view.get(target.attr('data-del-identify')).dispose();
            // 这个删除按钮对应的添加按钮
            var addNode = data.addNode;
            var alreadyAddcount = +addNode.attr('data-already-addcount');

            alreadyAddcount--;
            addNode.attr('data-already-addcount', alreadyAddcount);

            if (alreadyAddcount >= e.data.maxCount) {
                addNode.attr('disabled', 'disabled');
            }
            else {
                addNode.removeAttr('disabled');
            }
        }
    }

    /**
     * 动态添加 formItem
     *
     * @param {jQuery.Element} e jQuery 事件对象
     */
    function addItemFunc(e) {
        e.stopPropagation();
        e.preventDefault();

        var target = $(e.currentTarget);

        // 当前添加按钮所在的这一行的 form-row 节点
        var curFormRowNode = target.parents('.form-row');

        var alreadyAddNode = curFormRowNode.find('.add-items-container');
        var alreadyIndexArr = [];
        alreadyAddNode.each(
            function (i, v) {
                v = $(v);
                alreadyIndexArr.push(+v.attr('data-index'));
            }
        );

        var maxCountArr = e.data.maxCountArr;
        var differenceArr = _.difference(maxCountArr, alreadyIndexArr).sort();

        var alreadyAddcount = +target.attr('data-already-addcount') || 0;
        alreadyAddcount++;

        var flag = 0;
        if (!_.contains(differenceArr, alreadyAddcount)) {
            flag = alreadyAddcount;
            alreadyAddcount = differenceArr[0];
        }

        // 要添加的表单项的配置
        var itemsConfig = $.extend(true, [], e.data.itemsConfig);
        for (var i = 0, l = itemsConfig.length; i < l; i++) {
            itemsConfig[i].id += alreadyAddcount;
            itemsConfig[i].title += alreadyAddcount;
            itemsConfig[i].properties.value = '';
        }

        // 设置删除按钮,只需要在添加出来的一组元素的第一个设置
        // 如果添加的多行元素,在每一行添加的元素后面加上删除按钮是不合理的
        itemsConfig[0].properties.delItems = e.data.refIdentify;

        itemsConfig[0].properties.delIdentify = itemsConfig[0].id;

        var addItemContainer = $('<div class="add-items-container"></div>');
        var html = '';
        html += etplEngine.render('dynamicForm', {
            formItemConfigs: itemsConfig,
            i18n: {
                'QXZ': LANG_PKG.QXZ,
                'ZDXZ': LANG_PKG.ZDXZ,
                'Ge': LANG_PKG.Ge,
                'BT': LANG_PKG.BT
            }
        });

        addItemContainer.attr('data-index', alreadyAddcount).html(html);

        curFormRowNode.append(addItemContainer);

        esui.init(
            addItemContainer[0],
            {
                viewContext: e.data.view.viewContext
            }
        );
        // debugger
        target.attr('data-already-addcount', flag ? flag : alreadyAddcount);

        var maxCount = e.data.maxCount;

        if (+target.attr('data-already-addcount') >= maxCount) {
            target.attr('disabled', 'disabled');
        }
    }

    /**
     * 对 components 的处理
     *
     * @param {Array} components component 集合
     * @param {Object} submitEvtArgs form 提交时的参数,需要在 component 的值改变后修改参数中的值
     * @param {View} view 当前 View 对象
     */
    function dealComponents(components, submitEvtArgs, view) {
        Deferred.all(
            (function () {
                return _.map(
                    components,
                    function (component, index) {
                        return dynamicUtil.loadConfig(
                            './component/' + component.type + '/main',
                            component
                        );
                    }
                );
            })()
        ).then(
            function (d) {
                var args = Array.prototype.slice.call(arguments);
                var componentDataTmp = {};
                var componentCallbackTmp = {};
                /* jshint loopfunc:true */
                for (var i = 0, len = args.length; i < len; i++) {
                    args[i].modExport.on(
                        args[i].component.submitName + 'formSubmitDataChange',
                        function (changedData) {
                            // debugger
                            componentDataTmp[changedData.curFormData.submitName] =
                                changedData.curFormData;
                            componentCallbackTmp[changedData.curFormData.submitName] =
                                changedData.componentCallback;
                            submitEvtArgs = _.extend(
                                submitEvtArgs,
                                {
                                    componentData: componentDataTmp,
                                    componentCallback: componentCallbackTmp
                                }
                            );
                        }
                    );
                    args[i].modExport.init(args[i].component, view);
                }
            }
        );
    }

    /**
     * 设置 formItem 的 tip
     *
     * @param {View} view 当前的 View 对象
     * @param {Object} properties 每一个 formItem 的配置属性对象
     */
    function initTip(view, properties) {
        // 设置 ideaName 的 tip,ideaName 不属于动态 form,它是一个固定的 formItem
        view.initTip(
            LANG_PKG.YZXWG,
            view.get('ideaName')
        );

        // 遍历 properties
        // 初始化 formItem 的 tip
        // 如果是修改的话,那么设置 Uploader 的值
        _.forEach(
            properties,
            function (property, key) {
                if (property.tip) {
                    view.initTip(
                        property.tip,
                        view.get(key)
                    );
                }

                // 说明是 Uploader
                if (property.uploaderVal) {
                    view.get(key).setRawValue(property.uploaderVal);
                }
            }
        );
    }

    /**
     * 根据 formItemConfigs 配置获取 properties ,便于之后渲染 esui 控件
     *
     * @param {Array.<Object>} formItemConfigs formItem 配置
     * @param {Model} model 当前的 Model 对象
     *
     * @return {Promise}
     */
    function buildUIProperties(formItemConfigs, model) {
        var formType = model.get('formType');
        var defer = new Deferred();
        var len = formItemConfigs.length;
        var ret = {};
        ret.components = [];
        ret.dynamicItems = {};
        _.forEach(
            formItemConfigs,
            function (formItemConfig, index) {
                if (formItemConfig.type === 'TextBoxs') {
                    for (var i = 0, itemsLen = formItemConfig.items.length; i < itemsLen; i++) {
                        var fc = formItemConfig.items[i];
                        var p = fc.properties;

                        if (p) {
                            ret[fc.id] = p;

                            // 把 Uploader 类型的 formItem 的值直接放入到 p 中,
                            // 便于不用循环就可以回填 Uploader 的值
                            if (formType === 'edit'
                                && fc.type === 'Uploader'
                            ) {
                                var uploaderData = model.get(fc.id);

                                // 如果 uploaderData 不存在,说明这个 Uploader 组件不是必填项
                                if (uploaderData) {
                                    ret[fc.id].uploaderVal = {
                                        width: uploaderData.width || 50,
                                        height: uploaderData.height || 50,
                                        previewUrl: decodeURIComponent(uploaderData)
                                    };
                                }
                            }

                            var subItems = p.subItems;
                            // 存在 subItems,即当前这个 fc.id 的 formItem 后面有添加按钮
                            // 添加按钮添加的元素配置就是 subItems.list 里的配置
                            // 把 subItems 直接挂在 properties.dynamicItems 上,便于之后操作
                            if (subItems) {
                                ret.dynamicItems[fc.id] = subItems;

                                // console.log(model.get('alreadyAddItemsConfigNew'));
                                // console.log(model.get('alreadyAddItemsConfig'));
                                // console.log(fc.id);

                                // var alreadyAddItemsConfig = model.get('alreadyAddItemsConfig');
                                // if (alreadyAddItemsConfig) {
                                //     ret.dynamicItems[fc.id].alreadyAddItemsConfig = alreadyAddItemsConfig;
                                // }

                                var alreadyAddItemsConfigNew = model.get('alreadyAddItemsConfigNew');
                                if (alreadyAddItemsConfigNew) {
                                    for (var i = 0, l = alreadyAddItemsConfigNew.length; i < l; i++) {
                                        if (fc.id == alreadyAddItemsConfigNew[i].refId) {
                                            var curAlreadyAddItemsConfig = alreadyAddItemsConfigNew[i].alreadyAddItemsConfig;
                                            if (curAlreadyAddItemsConfig && curAlreadyAddItemsConfig.length) {
                                                ret.dynamicItems[fc.id].alreadyAddItemsConfig = curAlreadyAddItemsConfig;
                                            }
                                        }
                                    }
                                    // ret.dynamicItems[fc.id].alreadyAddItemsConfig = alreadyAddItemsConfig;
                                }
                            }
                        }

                        var components = fc.components;

                        if (components) {
                            if (!_.isArray(components)) {
                                ret.components.push(components);
                            }
                            else {
                                Array.prototype.push.apply(ret.components, components);
                            }
                        }
                    }
                }
                else {
                    var properties = formItemConfig.properties;

                    if (properties) {
                        ret[formItemConfig.id] = properties;

                        // 把 Uploader 类型的 formItem 的值直接放入到 properties 中,
                        // 便于不用循环就可以回填 Uploader 的值
                        if (formType === 'edit'
                            && formItemConfig.type === 'Uploader'
                        ) {
                            var uploaderData = model.get(formItemConfig.id);

                            // 如果 uploaderData 不存在,说明这个 Uploader 组件不是必填项
                            if (uploaderData) {
                                ret[formItemConfig.id].uploaderVal = {
                                    width: uploaderData.width || 50,
                                    height: uploaderData.height || 50,
                                    previewUrl: decodeURIComponent(uploaderData)
                                };
                            }
                        }

                        var subItems = properties.subItems;
                        // 存在 subItems,即当前这个 formItemConfig.id 的 formItem 后面有添加按钮
                        // 添加按钮添加的元素配置就是 subItems.list 里的配置
                        // 把 subItems 直接挂在 properties.dynamicItems 上,便于之后操作
                        if (subItems) {
                            ret.dynamicItems[formItemConfig.id] = subItems;

                            // console.log(model.get('alreadyAddItemsConfigNew'));
                            // console.log(model.get('alreadyAddItemsConfig'));
                            // console.log(formItemConfig.id);

                            // var alreadyAddItemsConfig = model.get('alreadyAddItemsConfig');
                            // if (alreadyAddItemsConfig) {
                            //     ret.dynamicItems[formItemConfig.id].alreadyAddItemsConfig = alreadyAddItemsConfig;
                            // }

                            var alreadyAddItemsConfigNew = model.get('alreadyAddItemsConfigNew');
                            if (alreadyAddItemsConfigNew) {
                                for (var i = 0, l = alreadyAddItemsConfigNew.length; i < l; i++) {
                                    if (formItemConfig.id == alreadyAddItemsConfigNew[i].refId) {
                                        var curAlreadyAddItemsConfig = alreadyAddItemsConfigNew[i].alreadyAddItemsConfig;
                                        if (curAlreadyAddItemsConfig && curAlreadyAddItemsConfig.length) {
                                            ret.dynamicItems[formItemConfig.id].alreadyAddItemsConfig = curAlreadyAddItemsConfig;
                                        }
                                    }
                                }
                                // ret.dynamicItems[formItemConfig.id].alreadyAddItemsConfig = alreadyAddItemsConfig;
                            }
                        }
                    }

                    var components = formItemConfig.components;

                    if (components) {
                        if (!_.isArray(components)) {
                            ret.components.push(components);
                        }
                        else {
                            Array.prototype.push.apply(ret.components, components);
                        }
                    }
                }

                if (index === len - 1) {
                    defer.resolve({
                        properties: ret
                    });
                }
            }
        );
        return defer.promise;
    }

    util.inherits(DynamicFormView, FormView);

    return DynamicFormView;
});
    /**
     * 动态添加 formItem
     *
     * @param {jQuery.Element} e jQuery 事件对象
     */
    function addItemFunc(e) {
        e.stopPropagation();
        e.preventDefault();

        var target = $(e.currentTarget);

        // 当前添加按钮所在的这一行的 form-row 节点
        var curFormRowNode = target.parents('.form-row');

        var alreadyAddNode = curFormRowNode.find('.add-items-container');
        var alreadyIndexArr = [];
        alreadyAddNode.each(
            function (i, v) {
                v = $(v);
                alreadyIndexArr.push(+v.attr('data-index'));
            }
        );

        var maxCountArr = e.data.maxCountArr;
        var differenceArr = _.difference(maxCountArr, alreadyIndexArr).sort();

        var alreadyAddcount = +target.attr('data-already-addcount') || 0;
        alreadyAddcount++;

        var flag = 0;
        if (!_.contains(differenceArr, alreadyAddcount)) {
            flag = alreadyAddcount;
            alreadyAddcount = differenceArr[0];
        }

        // 要添加的表单项的配置
        var itemsConfig = $.extend(true, [], e.data.itemsConfig);
        for (var i = 0, l = itemsConfig.length; i < l; i++) {
            itemsConfig[i].id += alreadyAddcount;
            itemsConfig[i].title += alreadyAddcount;
            itemsConfig[i].properties.value = '';
        }

        // 设置删除按钮,只需要在添加出来的一组元素的第一个设置
        // 如果添加的多行元素,在每一行添加的元素后面加上删除按钮是不合理的
        itemsConfig[0].properties.delItems = e.data.refIdentify;

        itemsConfig[0].properties.delIdentify = itemsConfig[0].id;

        var addItemContainer = $('<div class="add-items-container"></div>');
        var html = '';
        html += etplEngine.render('dynamicForm', {
            formItemConfigs: itemsConfig,
            i18n: {
                'QXZ': LANG_PKG.QXZ,
                'ZDXZ': LANG_PKG.ZDXZ,
                'Ge': LANG_PKG.Ge,
                'BT': LANG_PKG.BT
            }
        });

        addItemContainer.attr('data-index', alreadyAddcount).html(html);

        curFormRowNode.append(addItemContainer);

        esui.init(
            addItemContainer[0],
            {
                viewContext: e.data.view.viewContext
            }
        );
        // debugger
        target.attr('data-already-addcount', flag ? flag : alreadyAddcount);

        var maxCount = e.data.maxCount;

        if (+target.attr('data-already-addcount') >= maxCount) {
            target.attr('disabled', 'disabled');
        }
    }
            function (i, v) {
                v = $(v);
                var refIdentify = v.data('refIdentify');
                var maxCount = dynamicItems[refIdentify].maxCount;
                var candidateAddItemsConfig = dynamicItems[refIdentify].list;

                var alreadyAddItemsConfig = dynamicItems[refIdentify].alreadyAddItemsConfig;
                var len;
                if (alreadyAddItemsConfig && (len = alreadyAddItemsConfig.length)) {
                    v.attr('data-already-addcount', len);

                    for (var j = 0, l = alreadyAddItemsConfig.length; j < l; j++) {

                        var addItemContainer = $('<div class="add-items-container"></div>');
                        var html = '';
                        html += etplEngine.render('dynamicForm', {
                            formItemConfigs: alreadyAddItemsConfig[j],
                            i18n: {
                                'QXZ': LANG_PKG.QXZ,
                                'ZDXZ': LANG_PKG.ZDXZ,
                                'Ge': LANG_PKG.Ge,
                                'BT': LANG_PKG.BT
                            }
                        });

                        addItemContainer.attr('data-index', alreadyAddItemsConfig[j].index).html(html);

                        v.parents('.form-row').append(addItemContainer);

                        esui.init(
                            addItemContainer[0],
                            {
                                viewContext: view.viewContext
                            }
                        );
                    }
                }

                var alreadyAddcount = v.attr('data-already-addcount') || 0;
                alreadyAddcount = parseInt(alreadyAddcount, 10);
                if (alreadyAddcount >= maxCount) {
                    v.attr('disabled', 'disabled');
                }
                var maxCountArr = [];
                for (var q = 1; q <= maxCount; q++) {
                    maxCountArr.push(q);
                }
                v.on(
                    'click',
                    {
                        view: view,
                        itemsConfig: candidateAddItemsConfig,
                        maxCount: maxCount,
                        maxCountArr: maxCountArr,
                        alreadyAddItemsConfig: alreadyAddItemsConfig,
                        dynamicItems: dynamicItems,
                        refIdentify: refIdentify
                    },
                    addItemFunc
                );
                // if (alreadyAddcount < maxCount) {
                //     var maxCountArr = [];
                //     for (var q = 1; q <= maxCount; q++) {
                //         maxCountArr.push(q);
                //     }
                //     v.on(
                //         'click',
                //         {
                //             view: view,
                //             itemsConfig: candidateAddItemsConfig,
                //             maxCount: maxCount,
                //             maxCountArr: maxCountArr,
                //             alreadyAddItemsConfig: alreadyAddItemsConfig,
                //             dynamicItems: dynamicItems,
                //             refIdentify: refIdentify
                //         },
                //         addItemFunc
                //     );
                // }
                // else {
                //     v.attr('disabled', 'disabled');
                // }

                $('.form-data-body').delegate(
                    '.del-items',
                    'click',
                    {
                        addNode: v,
                        view: view,
                        maxCount: maxCount,
                        refIdentify: refIdentify
                    },
                    delItemFunc
                );
            }
Exemple #8
0
define(function (require) {

    var etpl = require('etpl');
    var smallImgWidth = 106; // 缩略图宽度

    var tpl = ''
        + '<div class="${expandPrefix}-action">'
        +   '<a href="" class="${expandPrefix}-original" target="_blank" title="查看原图"><i></i>查看原图</a>'
        +   '<a href="#" onclick="return false;" class="${expandPrefix}-rotate-right" title="向右旋转"><i></i>向右旋转</a>'
        + '</div>'
        + '<div class="${expandPrefix}-main-img">'
        +   '<img src="" />'
        + '</div>'
        + '<div class="${expandPrefix}-small-img-container">'
        +   '<% if: ${sUrls.length} %>'
        +     '<div class="${expandPrefix}-switch-left ${expandPrefix}-switch"><i data-switch="left"></i></div>'
        +   '<% /if %>'
        +   '<% if: ${sUrls.length} %>'
        +     '<div class="${expandPrefix}-switch-right ${expandPrefix}-switch"><i data-switch="right"></i></div>'
        +   '<% /if %>'
        +   '<% var: smallImgUlWidth = ${sUrls.length} * ${smallImgWidth} %>'
        +   '<% var: smallImgWrapWidth = ${smallImgNum} * ${smallImgWidth} %>'
        +   '<div class="${expandPrefix}-small-img-wrap <% if: !${sUrls.length} %>hidden<%/if%>" '
        +   'style="width:${smallImgWrapWidth}px" data-a="${smallImgUlWidth} - ${smallImgWrapWidth}">'
        +       '<ul class="${expandPrefix}-small-img" style="width:${smallImgUlWidth}px">'
        +             '<% for: ${sUrls} as ${sUrl}, ${i} %>'
        +             '<li>'
        +                 '<a href="" data-index="${i}"><img src="${sUrl}" /></a>'
        +             '</li>'
        +             '<% /for %>'
        +       '</ul>'
        +   '</div>'

        + '</div>';

    var etplEngine = new etpl.Engine({
        commandOpen: '<%',
        commandClose: '%>'
    });

    // 共用一个render即可
    var render = etplEngine.compile(tpl);

    /**
     * 是否支持css3的transition
     *
     * @private
     * @return {boolean} 支持状态
     */
    var supportTransition = (function () {
        var s = document.createElement('p').style;
        var r = 'transition' in s
            || 'WebkitTransition' in s
            || 'MozTransition' in s
            || 'msTransition' in s
            || 'OTransition' in s;
        s = null;
        return r;
    })();

    /**
     * 旋转
     *
     * @private
     * @param {(string | HTMLElement)} target 目标元素
     * @param {number} deg 角度
     */
    function rotate(target, deg) {
        if (supportTransition) {
            var degStr = 'rotate(' + deg + 'deg)';
            $(target).css({
                '-webkit-transform': degStr,
                '-mos-transform': degStr,
                '-o-transform': degStr,
                'transform': degStr
            });
        }
        else {
            var ieRotate = ~~((deg / 90) % 4 + 4) % 4;
            $(target).css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + ieRotate +')');
        }
    }

    /**
     * 图片展开放大
     *
     * @constructor
     * @exports
     * @param {Object} options 配置项
     */
    function ImgAmplify(options) {
        $.extend(this, options);
        $(this.source).unbind('click').bind('click', this.getExpandImgHandler());
    }

    /**
     * ImgAmplify新增prototype属性
     *
     * @type {Object}
     */
    var proto = {
        /**
         * 获取展开图片的处理函数
         *
         * @private
         * @return {Function}
         */
        getExpandImgHandler: function () {
            var me = this;
            return function (e) {
                // console.log(111);
                e.preventDefault();
                var target = e.target;
                var targetTagName = target.tagName.toLowerCase();
                // modify by liulangyu
                // if (targetTagName !== 'a' && targetTagName !== 'img' && targetTagName !== 'div') {
                if (targetTagName !== 'a' && targetTagName !== 'img') {
                    return;
                }

                target = $(target).parents('a').eq(0)[0];

                // 若第一次展开,则插入节点,绑定事件
                if (!me.expanded) {
                    me.expandInit(); // 插入节点
                    me.bindEvent(); // 渲染事件
                    me.index = -1;
                }

                var index = me.originImgLinks.index(target);
                me.expand(index); // 打开缩略图
            };
        },

        /**
         * 展开图片初始化操作
         *
         * @private
         */
        expandInit: function () {
            // 生成图片展开节点
            var src = $(this.source);
            src.after('<div class="' + this.expandPrefix + '-container" style="display:none;"></div>');
            this.expandEle = src.next()[0];

            // 生成一个临时img节点
            var tempImg = $('<img>', {style: 'position:absolute; left: -10000px; top:0;'})[0];
            // FIXME no need to append
            // document.body.appendChild(tempImg);
            this.tempImg = tempImg;

            // 抽取缩略图和大图url数据
            var src = $(this.source);
            var originImgLinks = src.find('a');
            var sUrls = []; // 缩略图列表
            var bUrls = []; // 原图列表
            var fileInfos = {};

            $.each(originImgLinks, function (index, imgLink) {
                var img = $(imgLink).find('img')[0];
                sUrls.push($(img).attr('src'));
                bUrls.push($(imgLink).attr('href') || $(img).attr('src'));
                fileInfos[index] = fileInfos[index] || {};
                fileInfos[index].rotate = parseInt($(imgLink).attr('data-rotate') || 0, 10);
            });
            this.originImgLinks = originImgLinks;
            this.sUrls = sUrls;
            this.bUrls = bUrls;
            this.fileInfos = fileInfos;
            this.smallImgNum = this.smallImgNum || 6;

            // 插入图片展开DOM
            var data = {
                'sUrls': this.sUrls,
                'expandPrefix': this.expandPrefix,
                'smallImgWidth': smallImgWidth,
                'smallImgNum': this.smallImgNum
            };

            // modify 如果只有一张,不显示缩略图
            if (this.sUrls.length <= 1) {
                data.sUrls = [];
            }
            // var render = etpl.compile(tpl);
            var html = render(data);
            this.expandEle.innerHTML = html;
            this.expandImgWrapper = $(this.expandEle).find('.' + this.expandPrefix + '-main-img')[0];
            this.expandImg = $(this.expandImgWrapper).find('img')[0];
            this.expandOriginal = $(this.expandEle).find('.' + this.expandPrefix + '-original')[0];
            this.expandSwitch = $(this.expandEle).find('.' + this.expandPrefix + '-switch i');
            this.expanded = true;

        },

        /**
         * 绑定事件
         *
         * @private
         */
        bindEvent: function () {
            $(this.tempImg).bind('load', this.getImgLoadedHandler());

            // 为展开后的缩略图绑定事件
            $(this.expandEle).find('.' + this.expandPrefix + '-small-img a').bind(
                'click', this.getSImgClickHandler()
            );

            // 为展开后的缩略图的左右绑定事件
            $(this.expandSwitch).bind('click', this.getSwitchClickHandler());

            // 为展开图片区域绑定mousemove事件
            $(this.expandImgWrapper).bind('mousemove', this.getExpandWrapperMvHandler());

            // 为展开图片区域绑定click事件
            $(this.expandImgWrapper).bind('click', this.getExpandWrapperClickHandler());
            // action
            $(this.expandEle).find('.' + this.expandPrefix + '-action').bind('click', this.getActionClickHandler());
        },

        /**
         * 获取临时图片加载成功后的事件处理函数
         *
         * @private
         * @return {Function}
         */
        getImgLoadedHandler: function () {
            var me = this;
            return function () {
                $(me.expandImgWrapper).removeClass('loading');

                if (me.imgLoading) {
                    me.show();
                    $($(me.source).find('img')[me.index]).css({
                        'opacity': 1,
                        'filter': 'alpha(opacity=100)'
                    });
                }

                me.resizeImg();
                var bUrl = me.bUrls[me.index];
                me.expandImg.src = bUrl;

                $(me.expandOriginal).attr('href', bUrl);

                // 初始化角度
                var deg = me.fileInfos[me.index].rotate;
                if (deg) {
                    me.rotateImage(deg, true);
                }

                if (!me.imgLoading) {
                    $(me.expandImg).animate({
                        opacity: '1'
                    }, 500);
                }

                if (me.imgLoading) {
                    me.imgLoading = false;
                }

                me.scrollPos(me.expandEle);
            };
        },

        /**
         * 根据临时图片的尺寸调整展开图片大小,限制宽度,保持宽高比
         *
         * @private
         */
        resizeImg: function () {
            var tempImg = this.tempImg;
            var originWidth = tempImg.width;
            var wrapperWidth = this.expandImgWrapper.offsetWidth;

            this.fileInfos[this.index] = this.fileInfos[this.index] || {};
            this.fileInfos[this.index].width = originWidth;
            this.fileInfos[this.index].height = tempImg.height;

            // 原图宽度小于wrapper宽度
            if (originWidth < wrapperWidth) {
                $(this.expandImg).css('width', originWidth + 'px');
            }
            else {
                $(this.expandImg).css('width', wrapperWidth + 'px');
            }
        },

        /**
         * 获取展开后缩略图部分点击事件处理函数
         *
         * @private
         * @return {Function}
         */
        getSImgClickHandler: function () {
            var me = this;

            return function (e) {
                e.preventDefault();
                var index = parseInt($(this).attr('data-index'), 10);
                me.turnTo(index);
            };
        },

        /**
         * 获取展开后缩略图左右箭头点击事件处理函数
         *
         * @private
         * @return {Function}
         */
        getSwitchClickHandler: function () {
            var me = this;

            return function (e) {
                e.preventDefault();

                var isFirstImg = (me.index === 0);
                var isLastImg = (me.index === me.sUrls.length - 1);
                var target = $(e.target);

                if (target.attr('data-switch') === 'left' && !isFirstImg) {
                    me.turnTo(me.index - 1);
                }
                else if (target.attr('data-switch') === 'right' && !isLastImg) {
                    me.turnTo(me.index + 1);
                }
            };
        },

        /**
         * 更新缩略图列表
         *
         * @private
         */
        updataThumbList: function () {

            var thumbList = $(this.expandEle).find('.' + this.expandPrefix + '-small-img');
            var thumbLen = this.sUrls.length;

            if (thumbLen > this.smallImgNum) { // 溢出
                if (this.index < 2) {
                    thumbList.css({
                        left: 0
                    });
                }
                else if (this.index < thumbLen - this.smallImgNum + 3) {
                    thumbList.animate(
                        {
                            left: -smallImgWidth * this.index + smallImgWidth * 2
                        },
                        300
                    );
                }
                else {
                    thumbList.animate(
                        {
                            left: -smallImgWidth * (thumbLen - this.smallImgNum)
                        },
                        300
                    );
                }
            }

            // 更新switch
            $(this.expandSwitch).removeClass('disable');
            if (this.index === 0) {
                $(this.expandSwitch).filter('[data-switch=left]').addClass('disable');
            }
            else if (this.index === this.sUrls.length - 1) {
                $(this.expandSwitch).filter('[data-switch=right]').addClass('disable');
            }
        },

        /**
         * 转到指定索引的某张图片
         *
         * @param {number} index 目标图片的索引
         */
        turnTo: function (index) {
            var prevIndex = this.index;
            if (prevIndex === index) {
                return;
            }

            if (index < 0 || index > this.bUrls.length - 1) {
                this.hide();
                return;
            }

            if (!this.imgLoading) {
                $(this.expandImg).css({
                    'opacity': 0,
                    'filter': 'alpha(opacity=0)'
                });

                $(this.expandImgWrapper).addClass('loading');
            }

            this.index = index;

            // 重置
            this.resetStyles();

            // 重置图片大小
            this.resizeImg();

            if (this.tempImg.src === this.bUrls[index]) {
                if (!this.imgLoading) {
                    $(this.expandImg).css({
                        opacity: '1'
                    });
                }
                $(this.expandImgWrapper).removeClass('loading');
            }

            this.tempImg.src = this.bUrls[index];

            var sLinkList = $(this.expandEle).find('.' + this.expandPrefix + '-small-img a');
            $(sLinkList[prevIndex]).parent().removeClass('current');
            $(sLinkList[index]).parent().addClass('current');

            // 更新缩略图列表
            this.updataThumbList();
        },

        /**
         * 获取图片展开区域mouseover事件处理函数
         *
         * @private
         * @return {Function}
         */
        getExpandWrapperMvHandler: function () {
            var me = this;

            return function (e) {
                // original
                // if (
                //     $(e.target)
                //         .add($(e.target).parents('.' + me.expandPrefix + '-original'))
                //         .hasClass(me.expandPrefix + '-original')
                // ) {
                //     return;
                // }

                var offsetGap = e.pageX - $(this).offset().left;
                var wrapperWidth = $(this).width();
                var wrapper = $(me.expandImgWrapper);

                // 若鼠标在图片左边1/3区域,并且当前不为第一张图片,则可向前翻页
                if (offsetGap < wrapperWidth / 3 && me.index > 0) {
                    wrapper.removeClass('next');
                    wrapper.addClass('prev');
                }
                // 若鼠标在图片右边1/3区域,且当前不为最后一张图片,则可向后翻页
                else if (offsetGap > wrapperWidth * 2 / 3 && me.index < me.sUrls.length - 1) {
                    wrapper.removeClass('prev');
                    wrapper.addClass('next');
                }
                // 其他情况为缩小指针
                else {
                    wrapper.removeClass('prev');
                    wrapper.removeClass('next');
                }
            };
        },

        /**
         * 获取图片展开区域click事件处理函数
         *
         * @private
         * @return {Function}
         */
        getExpandWrapperClickHandler: function () {
            var me = this;

            return function (e) {
                if ($(this).hasClass('prev')) {
                    me.turnTo(me.index - 1);
                }
                else if ($(this).hasClass('next')) {
                    me.turnTo(me.index + 1);
                }
                else {
                    me.hide();
                }
            };
        },

        /**
         * action区域点击
         */
        getActionClickHandler: function () {
            var self = this;

            return function (e) {
                if (
                    $(e.target)
                        .add($(e.target).parents('.' + self.expandPrefix + '-rotate-right'))
                        .hasClass(self.expandPrefix + '-rotate-right')
                ) {
                    self.rotateImage();
                }
            };
        },

        /**
         * 旋转
         *
         * @private
         * @param {number=} deg 需要顺时针旋转角度
         * @param {boolean=} isNoAnimation 是否不需要动画
         */
        rotateImage: function(deg, isNoAnimation) {
            deg = deg || (parseInt(this.currentRotate || 0, 10) + 90);
            this.currentRotate = deg;
            var target = $(this.expandImg);
            rotate(target, deg);

            if (!isNoAnimation) {
                $(this.expandImg).addClass('rotate');
            }

            // resize,简单处理,只处理90°倍数的问题,其它的可以通过getBoundClientRect
            var wrapperWidth = this.expandImgWrapper.offsetWidth;

            var isHorizontal = deg % 180 === 0;
            var info = this.fileInfos[this.index];

            var afterWidth = info[isHorizontal ? 'width' : 'height'];
            var afterHeight = info[isHorizontal ? 'height' : 'width'];

            // 原图宽度小于wrapper宽度
            if (afterWidth < wrapperWidth) {
                target.css({
                    width: info.width,
                    height: info.height
                });
            }
            else {
                if (isHorizontal) {
                    target.css({
                        width: wrapperWidth,
                        height: 'auto'
                    });
                }
                else {
                    target.css({
                        height: wrapperWidth,
                        width: 'auto'
                    });
                }
            }

            if (isHorizontal) {
                $(this.expandImgWrapper).css({
                    height: 'auto'
                });
                $(this.expandImg).css({
                    position: 'static',
                    left: 'auto',
                    top:' auto'
                });
            }
            else {
                var w = parseInt(target.css('width').replace('px', ''), 10);
                var h = parseInt(target.css('height').replace('px', ''), 10);
                $(this.expandImgWrapper).css({
                    height: w
                });

                $(this.expandImg).css({
                    position: 'absolute',
                    left: (wrapperWidth - h) / 2 - (w - h) / 2,
                    top: (w - h) / 2
                });
            }
        },

        /**
         * 重置样式
         */
        resetStyles: function () {
            this.currentRotate = 0;

            $(this.expandImgWrapper).css({
                height: 'auto'
            });
            $(this.expandImg).css({
                position: 'static',
                left: 'auto',
                top:' auto',
                width: 'auto',
                height: 'auto'
            }).removeClass('rotate');

            rotate($(this.expandImg), 0);
        },

        /**
         * 展开大图
         *
         * @param {number} index 展开大图的索引
         */
        expand: function (index) {
            // 需要加载图片
            if (index !== this.index) {
                $($(this.source).find('img')[index]).css({
                    'opacity': '0.5',
                    'filter': 'alpha(opacity=50)'
                });
                this.imgLoading = true;
                this.turnTo(index);
            }
            // 直接展开
            else {
                this.show();
            }
        },

        show: function () {
            $(this.source).hide();
            $(this.expandEle).show();
        },

        /**
         * 收起大图
         *
         * @private
         */
        hide: function () {
            $(this.expandEle).hide();
            $(this.source).show();
            // this.scrollPos(this.source);
        },

        /**
         * 若目标节点的起始位置在视觉范围之外,将页面滚动到目标元素的位置
         *
         * @param {HTMLElement} target 目标节点
         */
        scrollPos: function (target) {
            // TODO 简单处理下,后期改为事件处理
            var offsetTopFix = this.offsetTop || 0;
            var offsetTop = $(target).offset().top;

            if (this.scrollElem && $(this.scrollElem).size()) {
                var scrollElem = $(this.scrollElem);
                var scrollElemOffsetTop = scrollElem.offset().top;
                var scrollTop = scrollElem.scrollTop();

                if (offsetTop < scrollElemOffsetTop) {
                    scrollElem.scrollTop(scrollTop - scrollElemOffsetTop + offsetTop - offsetTopFix);
                }
            }
            else {
                if ($(document).scrollTop() > offsetTop - offsetTopFix) {
                    $(document).scrollTop(offsetTop - offsetTopFix);
                }
            }
        }
    };

    $.extend(ImgAmplify.prototype, proto);

    return ImgAmplify;
});
/**
 * 简易Table控件
 * Copyright 2016 Baidu Inc. All rights reserved.
 *
 * @file 控件用的模板引擎
 * @author otakustay
 */

import {Engine} from 'etpl';
import TEMPLATE from 'text!./LightTable.tpl.html';

let engine = new Engine();
engine.parse(TEMPLATE);
engine.addFilter('camelize', str => str.replace(/[A-Z]/g, char => '-' + char.toLowerCase()));

export default engine;
Exemple #10
0
view.addFilter = function (name, fn) {
    etplEngine.addFilter(name, fn);
};
Exemple #11
0
view.getRendererByTarget = function (target) {
    return etplEngine.getRenderer(target);
};