UNPKG

ecui

Version:

Enterprise Classic User Interface.

390 lines (320 loc) 11.9 kB
/** * ecui-ext * Copyright 2012 Baidu Inc. All rights reserved. * * path: editor.js * desc: 控件编辑器 * author: cxl(chenxinle@baidu.com) * date: 2012/07/16 */ (function () { var core = ecui, dom = core.dom, ui = core.ui, util = core.util, string = core.string, ext = core.ext, $fastCreate = core.$fastCreate, addEventListener = core.addEventListener, setFocused = core.setFocused, createDom = dom.create, children = dom.children, moveElements = dom.moveElements, getPosition = dom.getPosition, inheritsControl = core.inherits, getView = util.getView, triggerEvent = core.triggerEvent, trim = string.trim, getByteLength = string.getByteLength, encodeHTML = string.encodeHTML, blank = util.blank, UI_CONTROL = ui.Control, UI_CONTROL_CLASS = UI_CONTROL.prototype; var UI_EDITOR_LAYER = ui.EditorLayer = inheritsControl( UI_CONTROL, 'ui-editor-layer', function(el, options) { var type = this.getTypes()[0], o = createDom(), htmls = []; htmls.push('<div class="' + type + '-content"></div>'); htmls.push('<div class="'+ type +'-buttons"><span class="ui-button ui-button-g">确定</span><span class="ui-button">取消</span><span class="'+ type +'-error"></span></div>'); o.innerHTML = htmls.join(''); moveElements(el, o.firstChild, true); moveElements(o, el, true); }, function (el, options) { this.$setBody(el.firstChild); el = children(el.lastChild); this._uSubmitBtn = $fastCreate(this.Button, el[0], this, {command: 'submit'}); this._uCancelBtn = $fastCreate(this.Button, el[1], this, {command: 'cancel'}); this._eError = el[2]; this.$hide(); } ), UI_EDITOR_LAYER_CLASS = UI_EDITOR_LAYER.prototype, UI_EDITOR_LAYER_BTN = UI_EDITOR_LAYER_CLASS.Button = inheritsControl( UI_CONTROL, 'ui-button', null, function (el, options) { this._sCommand = options.command; } ), UI_EDITOR_LAYER_BTN_CLASS = UI_EDITOR_LAYER_BTN.prototype, EXT_EDITOR = ext.Editor = {}, EXT_EDITORS_CONFIG = {}, EXT_EDITOR_LAYERS = {}; function each(arr, callback) { var i, item; for (i = 0; item = arr[i]; i++) { callback.call(null, item, i); } } UI_EDITOR_LAYER_CLASS.show = function (con, options) { var value, pos = getPosition(con.getOuter()); if (options.setValue) { con.$setValue4Editor = options.setValue; delete options.setValue; } if (options.getValue) { con.$getValue4Editor = options.getValue; delete options.getValue; } value = con.$getValue4Editor(); this._oTarget = con; this.setOptions(options); this.setValue(value); UI_CONTROL_CLASS.show.call(this); this.setPosition(pos.left, pos.top + con.getHeight()); setFocused(this); } UI_EDITOR_LAYER_CLASS.$blur = function () { this.hide(); } UI_EDITOR_LAYER_CLASS.changeValue = function (value) { this.setValue(value); this._oTarget.$setValue4Editor(value); } UI_EDITOR_LAYER_CLASS.$submit = function () { var value = this.getValue(), target = this._oTarget; if (this.$validate() && triggerEvent(target, 'editorsubmit', null, [this, value])) { target.$setValue4Editor(value); this.hide(); } } UI_EDITOR_LAYER_CLASS.beforeProcess = function (msg) { msg = msg || '正在处理...'; this.setError(msg); core.mask(0); } UI_EDITOR_LAYER_CLASS.afterProcess = function (value, error) { core.mask(); if (error) { this.setError(error); } else { if (value !== undefined) { this.changeValue(value); } this.hide(); } } UI_EDITOR_LAYER_CLASS.$hide = function () { this._eError.innerHTML = ''; this._oTarget = null; UI_CONTROL_CLASS.$hide.call(this); } UI_EDITOR_LAYER_CLASS.setError = function (msg) { this._eError.innerHTML = msg; } UI_EDITOR_LAYER_CLASS.$validate = function () { return true; } /** * @override */ UI_EDITOR_LAYER_CLASS.setPosition = function (x, y) { var view = getView(), outer = this.getOuter(), width = outer.offsetWidth, height = outer.offsetHeight; if (x + width > view.right) { x = view.right - width; } if (y + height > view.bottom) { y = view.bottom - height; } UI_CONTROL_CLASS.setPosition.call(this, x, y); } // 待实现的接口 each(['setValue', 'getValue', 'setOptions'], function (item, i) { UI_EDITOR_LAYER_CLASS[item] = blank; }); UI_EDITOR_LAYER_BTN_CLASS.$click = function () { var con = this.getParent(); if (this._sCommand == 'cancel') { con.hide(); } if (this._sCommand == 'submit') { triggerEvent(con, 'submit'); } } // 编辑器实体 // 统一的对外入口 EXT_EDITOR.init = function (type, con, options) { var uid = con.getUID(); options = options || {}; EXT_EDITORS_CONFIG[uid] = {type: type, options : options}; addEventListener(con, 'mouseover', EXT_EDITOR.mouseoverHandler); addEventListener(con, 'mouseout', EXT_EDITOR.mouseoutHandler); addEventListener(con, 'dispose', EXT_EDITOR.disposeHandler); con.$setValue4Editor = function (value) { this.setContent(encodeHTML(value)); } con.$getValue4Editor = function () { return this.getBody().innerHTML; } }; EXT_EDITOR.createInput = function (con) { o = createDom('ui-editor', '', 'span'); o.innerHTML = '<span class="ui-editor-content"></span><span class="ui-editor-button"></span>'; o.lastChild.onclick = EXT_EDITOR.clickHandler(con); moveElements(con.getBody(), o.firstChild, true); con.getBody().appendChild(o); con.$setBody(o.firstChild); con._bAddedEditor = true; } EXT_EDITOR.showLayer = function (con) { var config = EXT_EDITORS_CONFIG[con.getUID()], options = config.options, type = config.type, layer = EXT_EDITOR_LAYERS[type]; if ('[object Function]' == Object.prototype.toString.call(options)) { options = options.call(null); } if (!layer) { layer = EXT_EDITOR.createLayer(type); } layer.show(con, options); }; EXT_EDITOR.createLayer = function (type) { var o = createDom('ui-editor-layer ui-editor-'+ type +'-layer'), cls = 'Editor' + type.charAt(0).toUpperCase() + type.substring(1) + 'Layer'; document.body.appendChild(o); o = $fastCreate(ui[cls], o, null, null); EXT_EDITOR_LAYERS[type] = o; return o; }; EXT_EDITOR.clickHandler = function (con) { return function () { EXT_EDITOR.showLayer(con); } }; EXT_EDITOR.mouseoverHandler = function () { var con = this, o; if (!con._bAddedEditor) { EXT_EDITOR.createInput(con); } o = con.getBody().parentNode; o.className += ' ui-editor-show'; }; EXT_EDITOR.mouseoutHandler = function () { var con = this, o; if (con._bAddedEditor) { o = con.getBody().parentNode; o.className = o.className.replace(/\s+ui-editor-show/, ''); } }; EXT_EDITOR.disposeHandler = function () { var uid = this.getUID(); if (EXT_EDITORS_CONFIG[uid]) { delete EXT_EDITORS_CONFIG[uid]; } }; // 创建具体的编辑浮层 // 继承自UI_EDITOR_LAYER /** * 输入框(多行) */ var UI_EDITOR_INPUT_LAYER = ui.EditorInputLayer = inheritsControl(UI_EDITOR_LAYER, 'ui-editor-layer'), UI_EDITOR_INPUT_LAYER_CLASS = UI_EDITOR_INPUT_LAYER.prototype; /** * 设置配置项 * * @param {Object} options * @param {Boolean} textarea 是否是多行输入框 默认单行输入框 * @param {Number} maxlength 最大长度 * @param {Boolean} require 是否是必填 */ UI_EDITOR_INPUT_LAYER_CLASS.setOptions = function (options) { var el = this.getBody(); el.innerHTML = options.textarea == true ? '<textarea></textarea>' : '<input type="text" />'; this._eInput = el.firstChild; this._nMaxlength = options.maxlength || Number.MAX_VALUE; this._bByte = options.isbyte; this._bRequire = options.require; } UI_EDITOR_INPUT_LAYER_CLASS.setValue = function (value) { this._eInput.value = trim(value); }; UI_EDITOR_INPUT_LAYER_CLASS.$validate = function () { var value = this.getValue(), msg = '', len = this._bByte ? getByteLength(value, 'gbk') : value.length; if (this._bRequire && value == '') { msg = '请填写'; } else if (len > this._nMaxlength) { msg = '不能超过' + this._nMaxlength + '个' + (this._bByte ? '字节' : '字符'); } this.setError(msg); return !msg; } UI_EDITOR_INPUT_LAYER_CLASS.getValue = function () { var input = this._eInput; input.value = trim(input.value); return input.value; }; /** * 下拉框 */ var UI_EDITOR_SELECT_LAYER = ui.EditorSelectLayer = inheritsControl(UI_EDITOR_LAYER, 'ui-editor-layer'), UI_EDITOR_SELECT_LAYER_CLASS = UI_EDITOR_SELECT_LAYER.prototype; /** * 设置配置项 * * @param {Object} options * @param {Array/Function} options 下拉框的选项/获取下拉框选项 */ UI_EDITOR_SELECT_LAYER_CLASS.setOptions = function (options) { var items = options.options, htmls = ['<select>'], i, item, el = this.getBody(); if ('[object Function]' == Object.prototype.toString.call(items)) { items = items.call(null); } for (i = 0; item = items[i]; i++) { htmls.push('<option value="'+ item.value +'">' + item.text + '</option>'); } htmls.push('</select>'); el.innerHTML = htmls.push(htmls.join('')); this._eSelect = el.firstChild; } UI_EDITOR_SELECT_LAYER_CLASS.setValue = function (value) { var el = this._eSelect, items = el.options, i, item; for (i = 0; item = items[i]; i++) { if (item.value == value) { el.selectedIndex = i; break; } } }; UI_EDITOR_SELECT_LAYER_CLASS.getValue = function () { var el = this._eSelect; return el[el.selectedIndex].value; }; })();