fieldPicker.js 15.8 KB
define('fieldPicker', ['components/common', 'scroll', 'i18n/lang', 'utils', 'htmlEditor', 'jquery'], function (common, Scroll, lang, utils, htmlEditor) {
    var template = '\
<div class="field-picker" id={{id}}>\
    <ul class="nav nav-tabs">\
        <li class="active" data-tab="fieldSelect">'+ SystemEnv.getHtmlNoteName(4139) /* 选择字段 */ +'</li>\
        <li data-tab="dtFieldSelect">'+ SystemEnv.getHtmlNoteName(4865) /* 明细字段 */ +'</li>\
        <li data-tab="fieldInput">'+ SystemEnv.getHtmlNoteName(4753) /* 输入Html */ +'</li>\
    </ul>\
    <div class="tab-panel active" id="fieldSelect">\
        {{search}}\
        <div class="normal">\
            <label class="field-label field-none" fieldid="0">' + SystemEnv.getHtmlNoteName(4168) /* 无 */ + '</label>\
        </div>\
    </div>\
    <div class="tab-panel" id="dtFieldSelect">\
	    {{search}}\
	    <div class="detail-normal">\
	        <label class="field-label field-none" fieldid="0">' + SystemEnv.getHtmlNoteName(4168) /* 无 */ + '</label>\
	    </div>\
	</div>\
    <div class="custom tab-panel" id="fieldInput">\
        <div class="field-content"><div class="htmlEditor"></div><div class="btn btn-confirm btn-block">' + SystemEnv.getHtmlNoteName(3451) /* 确定 */ + '</div></div>\
    </div>\
    <div class="arrow"></div>\
</div>';

    var cssText = '\
.field-picker { margin: 8px 0 0 0px; border: 1px solid rgba(0,0,0,0.2); -webkit-background-clip: padding-box; background-clip: padding-box; background-color: #fff; border-radius: 6px; box-sizing: border-box; color: #333; line-height: 20px; padding: 10px; position: fixed; text-align: left; top: -999px; left: -999px; white-space: normal; width: 440px; z-index: 1010; display: none; }\
.field-picker .arrow{ position: absolute; width: 22px; height:11px; top:0px; left: 0; right: 0; margin: 0 auto;}\
.field-picker.top .arrow{ bottom: 0; top: auto;}\
.field-picker.top { margin: -10px 0 0 0;} \
.field-picker.top .arrow:after { top: 100%;  border-bottom: 0px solid rgba(0,0,0,0); border-top: 10px solid #fff;}\
.field-picker.top .arrow:before { top: 100%; border-bottom: 0px solid rgba(0,0,0,0); border-top: 11px solid rgba(0,0,0,0.247059);}\
.field-picker .arrow:before,.field-picker .arrow:after { content: " "; display: block; position: absolute; width: 22px; height: 11px; white-space: normal; color: #333; line-height: 20px; text-align: left; font-size: 13px; box-sizing: border-box; }\
.field-picker .arrow:before { border-bottom: 11px solid rgba(0,0,0,0.247059); border-left: 11px solid rgba(0,0,0,0); border-right: 11px solid rgba(0,0,0,0); border-top: 0 solid rgba(0,0,0,0); top: -11px; z-index: 1011; }\
.field-picker .arrow:after { border-bottom: 10px solid #fff; border-left: 10px solid rgba(0,0,0,0); border-right: 10px solid rgba(0,0,0,0); border-top: 0 solid rgba(0,0,0,0); top: -10px; z-index: 1012; }\
.field-picker.left:before, .field-picker.left:after { left: 25px; margin: 0; }\
    .field-picker .nav-tabs { border-bottom: 1px solid #dfdfdf; text-align: center;}\
    .field-picker .field-search + .normal .field-none { margin-top: 0;}\
    .field-picker .nav>li { transition: none;}\
    .field-picker .normal,.field-picker .detail-normal {position: relative;margin-right: -10px; max-height: 160px; overflow-y: auto;}\
	.field-picker .normal:after,.field-picker .detail-normal:after { content: " "; display: table; clear: both; }\
	.field-picker .custom { margin: 5px 0 2px 0; padding: 6px 0 0 0; }\
	.field-picker .field-search { padding: 6px 0; }\
    .field-picker .nav>li:nth-child(1) { padding-left: 0; }\
    .field-picker .nav-tabs li { padding: 3px 0; margin-right: 5px; display: inline-block; cursor: pointer; } \
    .field-picker .nav-tabs li.active { border-bottom: 3px solid #0066b1; color: #0066b1;}\
    .field-picker .tab-panel { margin: 0;}\
    .field-picker .nav-tabs .active:after, .field-picker .tab-panel.active:after,.field-picker .tab-panel.active:before { content: ""; display:none; }\
		.field-picker .field-label { margin: 0; background: url(/mobilemode/images/mec/flag_wev8.png) no-repeat; background-position: 0 1px; color: #333; cursor: pointer; display: block; font-family: "Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; height: 22px; line-height: 21px; overflow: hidden; padding: 1px 2px 1px 23px; text-align: left; text-overflow: ellipsis; white-space: nowrap; width: 140px; float: left;}\
		.field-picker .field-label.checked { background: url(/mobilemode/images/mec/flag2_wev8.png) no-repeat; background-position: -1px 1px;}\
		.field-picker .custom .field-label { width: 100%; cursor: text; font-size: 12px; color: #666; line-height: 23px; height: auto; }\
		.field-picker .custom .htmlEditor { border: 1px solid #ccc; height: 200px; width: 100%; overflow: auto; margin-bottom: 5px; }\
		.field-picker .field-none { float: none; margin-top: 5px; width: 100%; }\
';

    var settings = {
        sourceId: '',
        callback: {
            afterSelect: function (field, target) { } // 字段对象, 源目标
        }
    }

    var FP = function (options) {
        var t = this;

        t.id = options.id = 'fp_' + options.id;
        t.settings = $.extend({}, settings, options);
        t.el = null;
        t.target = null; // 源目标
        t.fields = null; // 内容来源字段的html片段
        t.dtfields = null; // 内容来源明细字段的html片段
        t.render();

        return t;
    };

    FP.pt = FP.prototype;

    FP.pt.vessel = function () { // 创建容器
        var config = this.settings;

        config.search = config.sourceId && '<div class="field-search"> <input type="text" placeholder="'+ SystemEnv.getHtmlNoteName(4748) /* 请输入检索项 */ +'"  class="form-control"/> </div>' || '';

        return common.tempEngine(template, config);
    };

    FP.pt.create = function () { // 创建元素
        var fp = this,
            tmp = fp.vessel();

        fp.el = $(tmp);
        $('body').append(fp.el);
        new Scroll(fp.el.find(".normal,.detail-normal"), true);

        return fp;
    };

    FP.pt.getFields = function (sourceId) {
        var fp = this,
            deferred = $.Deferred();

        if (fp.fields) return deferred.resolve();
        if (!sourceId) return deferred.reject();

        var fieldTemplate = '<label class="field-label" title="{{fieldName}}" fieldDescPy="{{fieldDescPy}}" fieldid="{{fieldid}}">{{fieldDesc}}</label>'; // 后台中fielddesc对应为fieldDesc
        if(String(sourceId).indexOf("api_") == 0){//接口
        	utils.api('api', {
                action: "info",
                type: "get",
                data: {
                    "id": sourceId.substring(4)
                }
            }).then(function (result) {
            	var mainFields = [], resultDefine = result.data.resultDefine || [], resultKey = fp.settings.resultKey;

            	!resultKey && resultDefine.every(function(ele, i) {
            		if(ele.type === "ARRAY"){
            			resultKey = ele.name;
            			return false;
            		}
            		return true;
            	});

            	resultKey && resultDefine.forEach(function(ele, i) {
            		var pname = ele.name;
            		if(pname !== resultKey && pname.substring(resultKey.length).indexOf(".") === 0){
            			mainFields.push({
                			fieldid: ele.id,
                			fieldName: ele.name,
                			fieldDesc: ele.remark,
                			fieldDescPy: ele.remarkPy
                		});
            		}
            	});

            	fp.fields = common.tempEngine(fieldTemplate, mainFields);
            	deferred.resolve(result.data);
            });
        }else if(String(sourceId).indexOf("sql_") == 0){
            sourceId = sourceId.substring(4);
            var sourceArr = sourceId.split("_datasource_");
            utils.api("designer/plugin", {
                action: "getSourceFields",
                notification: false,
                type: 'POST',
                data: {
                    source: "3",
                    datasource: compressByLZ(sourceArr[1]),
                    sql: compressByLZ(sourceArr[0])
                }
            }).then(function(result){
                var data = result.data || [];
                var fields = common.tempEngine(fieldTemplate, data);
                fp.fields = fields;
                deferred.resolve(data);
            });
        }else{
            var parseSearchFields = function(data){
                var mainFields = [], dtFields = [];

                data && data.forEach(function(item){
                    item.fieldDesc = MLanguage.parse(item.fieldDesc);
                    item.detailtable ? dtFields.push(item) : mainFields.push(item);
                });

                var fields = common.tempEngine(fieldTemplate, mainFields);
                var dtfields = common.tempEngine(fieldTemplate, dtFields);

                fp.fields = fields;
                fp.dtfields = dtfields;
                deferred.resolve(data);
            };
            if(String(sourceId).indexOf("search_") == 0){//表单建模查询列表id
                utils.api("designer/plugin", {
                    action: "getSourceFields",
                    type: 'POST',
                    data: {
                        source: "1",
                        searchid: sourceId.substring(7)
                    },
                }).then(function(result){
                    parseSearchFields(result.data);
                });
            }else{//appFormUI id
                common.ajax({
                    url: common.jionActionUrl("com.weaver.formmodel.mobile.ui.servlet.MobileAppUIAction",
                        "action=getUIField&id=" + sourceId)
                }, function (data) {
                    parseSearchFields(data);
                });
            }
        }
        return deferred;
    };

    FP.pt.renderFields = function (callback) { // 渲染字段列表
        var fp = this,
            fpEl = fp.el,
            sourceId = fp.settings.sourceId;

        $.when(fp.getFields(sourceId))
            .then(function (data) {
                fpEl.find('.normal').append($(fp.fields));
                fpEl.find('.detail-normal').append($(fp.dtfields));
                fpEl.find('.checked').removeClass('checked');
                $.isFunction(callback) && callback(data);
            });

        return fp;
    };

    FP.pt.mounted = function(){
    	var fp = this,
        fpEl = fp.el;

    	if(!fp.dtfields){
        	fpEl.find(".nav-tabs li[data-tab='dtFieldSelect']").remove();
        	fpEl.find("#dtFieldSelect").remove();
        }
    	return fp;
    }

    FP.pt.render = function () {
        return this.destory().create().events().customEvents();
    };

    FP.pt.events = function () {
        var fp = this,
            el = fp.el,
            config = fp.settings;

        var setField = function (field) {
            $(fp.target).data('field', field);
            config.callback.afterSelect.call(null, field, fp.target);
            fp.destory();
        };

        el.find('.btn').one('click', function (e) { // 设置自定义字段值
            setField({
                'fieldid': '-1',
                'fielddesc': $.trim(fp.editor ? fp.editor.getValue() : "")
            });
        });

        el.find('.nav-tabs').on('click', 'li', function (e) {
            var $target = $(e.target), tab, $pane;

            if ($target.hasClass('active')) return;

            tab = $target.data('tab'),
            $pane = $(common.toId(tab));

            el.find('.active').removeClass('active');
            $target.addClass('active');
            $pane.addClass('active');
            setTimeout(function() {
                $pane.find('input').focus();
            });
            fp.editor && fp.editor.focus();
            fp.position();
        });

        el.one('mousedown.checked', '.normal .field-label,.detail-normal .field-label', function () { // 设置字段值
            var $checked = $(this); // 被选中字段

            setField({
                fieldid: $checked.attr("fieldid"),
                fielddesc: $.trim($checked.html())
            });
        }).on('mousedown', function (e) { // 阻止点击fieldPicker时关闭
            return false;
        });

        $('body').off('mousedown.fp')
            .one('mousedown.fp', function (e) { // 自动关闭
                fp.destory();
                e.stopPropagation();
            });

        if (!config.sourceId) return fp;

         el.find('input').on('input', function (e) { // 搜索功能 默认有内容来源时才显示
        	var $parent = $(this).closest(".tab-panel");

        	$parent.find('.field-label').each(function () {
        		var $this = $(this),
        			searchTxt = common.toLowerCase(e.target.value),
        			pattern = new RegExp('.*' + searchTxt.split('').join('.*') + '.*'),
        			text = common.toLowerCase($this.html()),
        			py = common.toLowerCase($this.attr("fieldDescPy"));
                if (text.indexOf(searchTxt) == -1 && py.match(pattern) == null) {
                    return $(this).hide();
                }
                $(this).show();
            });
        });

        setTimeout(function() {
           el.find("input").focus();
        });

        return fp;
    };

    FP.pt.customEvents = function () {
        var fp = this;

        fp.el.on('field:change', function () {
            var fpEl = $(this),
                field = $(fp.target).data('field');

            fp.editor = htmlEditor.editor(fpEl.find(".htmlEditor")[0], 'html', ['Mobile_NS']);

            if (!field) return;

            var $tabpanel = fpEl.find('[fieldid=' + field.fieldid + ']').addClass('checked').closest('.tab-panel');

            fp.el.find('.nav-tabs li').eq($tabpanel.index()-1).trigger('click');
            if (field.fieldid == -1) {
                fpEl.find('[data-tab=fieldInput]').trigger('click');
                fp.editor.setValue(field.fielddesc || "", true);
            }
        });

        return fp;
    };

    FP.pt.position = function () {
        var position = common.position(this.target, this.el, "center");

        this.el.toggleClass("top", !!position);

        var tOffset = this.target.offset(),
            tWidth = this.target.outerWidth(),
            elWidth = this.el.outerWidth(),
            tOffsetRight = $('body').outerWidth() - tOffset.left - tWidth/2;
        if(tOffsetRight < elWidth/2 + 10){//计算角标位置
            this.el.find(".arrow").css("right", (tOffsetRight - elWidth/2 - 10)*2);
        }
        return this.el;
    };

    FP.pt.destory = function () {
        this.el && this.el.remove();

        return this;
    }

    common.importCssText('fieldPicker', cssText);

    var fps = {
        setFP: function (fp) {
            this[fp.id] = fp;
        },
        getFP: function (id) {
            return this['fp_' + id];
        }
    };

    return {
        run: function (settings) {
            var fp = new FP(settings);

            fps.setFP(fp);
        },
        show: function (el, id) {
            var fp = fps.getFP(id);

            fp.target = $(el);

            $('.field-picker').remove(); // 清除所有fieldPicker

            return fp.render()
                .renderFields().mounted().position().trigger('field:change').show();
        },
        change: function (sourceId, callback, id, resultKey) {
            var fp = fps.getFP(id);
            if(utils.isArray(sourceId)){

            }else{
                fp.settings.sourceId = sourceId;
                fp.settings.resultKey = resultKey;
            }

            fp.fields = null;
            fp.dtfields = null;
            return fp.renderFields(callback).mounted();
        },
        resetField: function (el) {
            $(el).data('field', null);
        },
        setField: function (el, field, id) {
            $(el).data('field', field);
            if(id) {
                var fp = fps.getFP(id);
                fp.settings.callback.afterSelect(field, el);
            }
        }
    }
});