Esempio n. 1
0
define(function (require) {
    var etpl = require('etpl');
    var lib = require('esui/lib');
    var main = require('esui/main');
    var Control = require('esui/Control');
    var regionData = require('./regionData');
    require('etpl/tpl!./template.tpl');

    // 每一行最多显示的省份数量
    var LINE_MAX_NUM = 5;
    // 每个省份元素的宽度
    var PROVINCE_ITEM_WIDTH = 90;
    // 父子容器除去省份元素外宽度差
    var WIDTH_DIFF = 157;

    /**
     * 控件默认选项值
     * @type {Object}
     */
    var defaultOptions = {
        /**
         * 控件数据源
         * @type {Array.<Object>}
         */
        datasource: null,

        /**
         * 控件依附的元素ID
         * @type {string}
         */
        attachToElement: '',

        /**
         * 默认选择的地域
         * @type {?number}
         */
        currentRegion: null,

        /**
         * 自定义地域
         * @type {Array}
         */
        customRegions: {}
    };

    /**
     * 根据依附的元素定位控件主体元素
     * @param {jQuery} attachElem
     */
    function positionByAttachElement(attachElem) {
        var offset = attachElem.offset();
        var container = this.getContainerElement();
        var bodyWidth = $(document.body).outerWidth();
        if (!offset) {
            return;
        }

        offset.top += attachElem.outerHeight();
        // 若浮层超过屏幕宽度时,折向左边
        if ((offset.left + container.width()) > bodyWidth) {
            offset.left -= container.width() - attachElem.outerWidth(); 
        }

        this.positionAt(offset.left, offset.top);
    }

    /**
     * 地域单选组件
     * @param {Object} options
     * @constructor
     * @extends Control
     */
    function SingleRegion(options) {
        /**
         * 记录当前选择的地域
         * @type {?Object}
         * @private
         */
        this._currentRegion = null;

        /**
         * 记录当前选择的地域元素
         * @type {?jQuery}
         * @private
         */
        this._currentRegionElement = null;

        /**
         * 记录当前选择的地域元素的父级地域元素
         * @type {?jQuery}
         * @private
         */
        this._currentRegionParentElement = null;

        /**
         * 用户自定义的地域信息记录
         * @type {Object}
         * @private
         */
        this._customRegionInfo = {};

        Control.apply(this, arguments);
    }

    /**
     * 继承于Control基类
     */
    lib.inherits(SingleRegion, Control);

    /**
     * 控件类型,始终为SingleRegion
     * @type {string}
     */
    SingleRegion.prototype.type = 'SingleRegion';

    /**
     * 获取当前选择的地域
     * @returns {?Object}
     */
    SingleRegion.prototype.getCurrentRegion = function () {
        return this._currentRegion;
    };

    /**
     * 重置已选择的地域
     */
    SingleRegion.prototype.restoreRegion = function () {
        var currentRegionElement = this._currentRegionElement;
        var currentRegionParentElement = this._currentRegionParentElement;
        if (currentRegionElement) {
            currentRegionElement.find('input').prop('checked', false);
        }

        if (currentRegionParentElement) {
            this.helper.removePartClasses(
                'parent-active', 
                currentRegionParentElement[0]
            );
        }

        this._currentRegion = null;
        this._currentRegionElement = null;
        this._currentRegionParentElement = null;
    };

    /**
     * 设置当前已选地域
     * @param {number} regionCode 地域编码
     */
    SingleRegion.prototype.selectRegion = function (regionCode) {
        var lastRegion = this.getCurrentRegion();
        var currentRegion = this.getRegion(regionCode);

        // 如果没发生变化就啥也不干
        if (lastRegion && (lastRegion.code === currentRegion.code)) {
            return;
        }

        this.restoreRegion();

        var parentRegion = this.getParentRegion(regionCode);
        var containerElement = this.getContainerElement();
        var currentRegionElement = containerElement.find(
            '[data-item-value="' + regionCode + '"]'
        );
        var currentRegionParentElement = parentRegion
            ? containerElement
                .find('[data-item-value="' + parentRegion.code + '"]')
            : null;

        this._currentRegion = currentRegion;
        this._currentRegionElement = currentRegionElement;

        currentRegionElement.find('input').prop('checked', true);

        if (parentRegion) {
            this._currentRegionParentElement = currentRegionParentElement;
            this.helper.removePartClasses(
                'parent-active',
                currentRegionParentElement[0]
            );
        }

        // 用事件对调用者进行通知
        this.fire('change', {
            last: lastRegion,
            current: currentRegion
        });
    };

    /**
     * 设置自定义地域
     * @param {Object} regionInfo
     */
    SingleRegion.prototype.setCustomRegion = function (regionInfo) {
        var customRegionInfo = this._customRegionInfo;
        if (!customRegionInfo) {
            customRegionInfo = this._customRegionInfo = {};
        }
        customRegionInfo[regionInfo.code] = regionInfo;
    };

    /**
     * 获取地域对象
     * @param {number} regionCode 地域编码
     * @returns {Object}
     */
    SingleRegion.prototype.getRegion = function (regionCode) {
        var customRegionInfo = this._customRegionInfo;
        if (customRegionInfo.hasOwnProperty(regionCode)) {
            return customRegionInfo[regionCode];
        }

        return regionData.getRegion(regionCode);
    };

    /**
     * 获取父级地域对象
     * @param {number} regionCode 地域编码
     * @returns {Object}
     */
    SingleRegion.prototype.getParentRegion = function (regionCode) {
        var region = this.getRegion(regionCode);
        if (!region.parent) {
            return null;
        }

        return this.getRegion(region.parent);
    };

    /**
     * 初始化参数
     * @param {Object} options
     * @override
     */
    SingleRegion.prototype.initOptions = function (options) {
        var properties = $.extend(true, {}, defaultOptions, options);
        if (!properties.datasource) {
            properties.datasource = regionData.buildRegionList();
        }

        var customRegions = properties.customRegions;
        for (var i = 0, customRegion; customRegion = customRegions[i++];) {
            this.setCustomRegion(customRegion);
        }

        this.setProperties(properties);
    };

    /**
     * 初始化控件结构
     * @override
     */
    SingleRegion.prototype.initStructure = function () {
        // 默认隐藏控件
        this.hide();
        // 渲染控件内容
        this.renderContent();
        // 初始化事件
        this.initDomEvents();

        var currentRegion = this.currentRegion;
        if (typeof currentRegion === 'number') {
            this.selectRegion(currentRegion);
        }
    };

    /**
     * 依附元素的点击事件
     * @param {jQuery.Event} event
     */
    function attachElementClickHandler(event) {
        var regionEntity = event.data.regionEntity;

        // 将地域选择控件元素展示在依附元素下方
        positionByAttachElement.call(regionEntity, $(this));
        // 地域选择控件的显示切换
        regionEntity.toggle();

        event.stopPropagation();
    }

    /**
     * 控件元素的鼠标移入处理
     * @param {Object} options 选项参数
     */
    function containerElementMouseEnter(options, me) {
        var elem = options.elem;
        var offset = elem.offset();
        var subContainer = options.subContainer;
        var elemPosition = elem.position();
        var bodyWidth = $(document.body).outerWidth();

        if (subContainer.length > 0) {
            me.helper.addPartClasses('parent-active', elem[0]);
        }
        var left = elemPosition.left;
        var top = elemPosition.top + elem.outerHeight();
        if ((offset.left + subContainer.outerWidth()) > bodyWidth) {
            left -= subContainer.outerWidth() - elem.outerWidth();
        }
        subContainer.css({
            left: left + 'px',
            top: top + 'px',
            'z-index': Math.floor(+new Date / 1000)
        }).show();
    }

    /**
     * 控件元素的鼠标移出处理
     * @param {Object} options 选项参数
     */
    function containerElementMouseLeave(options, me) {
        var elem = options.elem;
        var subContainer = options.subContainer;
        var toElement = options.toElement;

        // 在子地域的container上绑定数据fromElement
        // 其值为鼠标在移入子地域container之前所在的元素
        // 即一级地域的选择所在的元素
        // 作用是在子地域container移出的时候
        // 顺便将这个元素的class清除掉
        subContainer.data('fromElement', elem);

        // 如果鼠标移出,则判断目标元素是否为相应的子地域
        // 在目标元素不是相应的子地域元素时,将子地域的container隐藏
        if (!toElement.closest(subContainer).length) {
            subContainer.hide();
            me.helper.removePartClasses('parent-active', elem[0]);
            return;
        }
    }

    /**
     * 控件元素的鼠标响应代理事件
     * @param {jQuery.Event} event
     */
    function containerElementMouseoverHandler(event) {
        var elem = $(this);
        var type = event.type;
        var regionEntity = event.data.regionEntity;
        var regionCode = elem.attr('data-item-value');
        var toElement = $(event.relatedTarget);
        var subContainer = $('.ui-singleregion-sub-container'
            + '[data-item-parent="' + regionCode + '"]');

        /**
         * 组织必要的参数
         * @type {Object}
         */
        var data = {
            elem: elem,
            subContainer: subContainer,
            toElement: toElement,
            regionCode: regionCode
        };

        if (type === 'mouseover') {
            containerElementMouseEnter(data, regionEntity);
        } else {
            containerElementMouseLeave(data, regionEntity);
        }

        event.stopPropagation();
    }

    /**
     * 控件子地域的容器鼠标移出事件
     * @param {jQuery.Event} event
     */
    function subContainerMouseLeaveHandler(event) {
        var elem = $(this);
        var toElement = $(event.relatedTarget);
        var regionEntity = event.data.regionEntity;
        var originalFromElement = elem.data('fromElement');

        if (!toElement.closest(elem.closest('div')).length) {
            regionEntity.helper.removePartClasses(
                'parent-active', 
                originalFromElement && originalFromElement[0]
            );
            elem.hide();
            elem.removeData('fromElement');
        }

        event.stopPropagation();
    }

    /**
     * 视窗大小改变的事件
     * @param {jQuery.Event} event
     */
    function windowResizeHandler(event) {
        var data = event.data;
        positionByAttachElement.call(data.regionEntity, data.attachElement);
    }

    /**
     * 全局委托点击事件
     * @param {jQuery.Event} event
     */
    function documentClickHandler(event) {
        var data = event.data;
        var target = $(event.target);
        if (!target.closest(data.containerElement).length) {
            data.regionEntity.hide();
        }
    }

    /**
     * 控件元素点击事件
     * @param {jQuery.Event} event
     */
    function regionClickHandler(event) {
        var elem = $(this);
        
        var data = event.data;
        var regionEntity = data.regionEntity;
        var regionCode = elem.attr('data-item-value');
        var regionDisabled = elem.attr('data-item-disabled') === 'true';

        if (!regionDisabled) {
            regionEntity.selectRegion(regionCode);
            data.subContainerElement.hide();
        }

        event.stopPropagation();
    }

    /**
     * 初始化控件事件
     */
    SingleRegion.prototype.initDomEvents = function () {
        var me = this;
        var containerElement = me.getContainerElement();
        var attachElement = me.getAttachElement();
        var subContainerElement = containerElement.find(
            '.ui-singleregion-sub-container'
        );
        var regionElement = containerElement.find(
            '[data-item-type="region"]'
        );

        var parentRegionElement = containerElement.find(
            '[data-item-rank="province"]'
        );

        var data = {
            regionEntity: me,
            containerElement: containerElement,
            attachElement: attachElement,
            subContainerElement: subContainerElement
        };

        // 绑定依附元素的点击事件
        attachElement.on('click', data, attachElementClickHandler);

        // 绑定地域元素的点击事件
        regionElement.on('click', data, regionClickHandler);

        // 绑定控件子地域的容器鼠标移出事件
        subContainerElement.on(
            'mouseout',
            data,
            subContainerMouseLeaveHandler
        );

        // 绑定控件主体的鼠标响应事件
        parentRegionElement.on(
            'mouseover mouseout',
            data,
            containerElementMouseoverHandler
        );

        // 绑定window的resize事件
        $(window).on('resize', data, windowResizeHandler);

        // 在document上委托click
        $(document).on('click', data, documentClickHandler);
    };

    /**
     * 渲染控件内容
     */
    SingleRegion.prototype.renderContent = function () {
        var container = this.getContainerElement();
        var datasource = this.get('datasource');
        var content = etpl.render('library-ui-single-region', {
            list: datasource,
            className: {
                container: this.helper.getPartClassName('container'),
                area: this.helper.getPartClassName('area'),
                itemChina: this.helper.getPartClassName('item-for-china'),
                itemForeign: this.helper.getPartClassName('item-for-foreign'),
                sectorItem: this.helper.getPartClassName('sector-item'),
                provinceItem: this.helper.getPartClassName('province-item'),
                subContainer: this.helper.getPartClassName('sub-container'),
                subLast: this.helper.getPartClassName('sub-last')
            }
        });

        container.html(content);
        this.changeContainerWidth(datasource, container);
    };

    /**
     * 根据展示地域的个数设置容器宽度
     *
     * @param {Object} data 显示的地域数据
     * @param {jQuery} container 父容器
     */
    SingleRegion.prototype.changeContainerWidth = function (data, container) {
        var sectorContainer = container.find(
            '.ui-singleregion-sector-item'
        );

        var length = 0;
        for (var i = 0; i < data.length; i++) {
            var item = data[i].provinces;
            var len = 0;
            for (var j = 0; j < item.length; j++) {
                if (item[j].status) {
                    len++;
                }
            }
            if (len > length) {
                length = len;
            }
        }
        if (length < LINE_MAX_NUM) {
            sectorContainer.css('width', length * PROVINCE_ITEM_WIDTH);
            container.css(
                'width', 
                length * PROVINCE_ITEM_WIDTH + WIDTH_DIFF
            );
        }
        return;
    }

    /**
     * 获取控件主体元素
     * @returns {jQuery}
     */
    SingleRegion.prototype.getContainerElement = function () {
        return $(this.main);
    };

    /**
     * 获取控件所依附的元素
     * @returns {jQuery}
     */
    SingleRegion.prototype.getAttachElement = function () {
        return $(this.get('attachToElement'));
    };

    /**
     * 控件定位
     * @param {number} left
     * @param {number} top
     */
    SingleRegion.prototype.positionAt = function (left, top) {
        this.getContainerElement().css({
            left: left + 'px',
            top: top + 'px'
        });
    };

    /**
     * 销毁控件
     * @override
     */
    SingleRegion.prototype.dispose = function () {
        if (this.helper.isInStage('DISPOSED')) {
            return;
        }

        // 解除window的resize事件
        $(window).off('resize', windowResizeHandler);

        // 解除document上委托click
        $(document).off('click', documentClickHandler);

        Control.prototype.dispose.apply(this, arguments);
    };

    // 注册控件
    main.register(SingleRegion);

    return SingleRegion;
});
Esempio n. 2
0
define(function (require) {
    var lib = require('esui/lib');
    var u = require('underscore');
    var InputControl = require('esui/InputControl');
    var eoo = require('eoo');
    var esui = require('esui/main');
    var painters = require('esui/painters');
    var $ = require('jquery');

    require('esui/Label');

    /**
     * FilterResult
     *
     * @extends Panel
     * @constructor
     */
    var FilterResult = eoo.create(
        InputControl,
        {
            type: 'FilterResult',

            /**
             * 初始化配置
             *
             * @protected
             * @override
             */
            initOptions: function (options) {
                var properties = {
                    datasource: []
                };
                u.extend(properties, options);

                this.setProperties(properties);
            },

            /**
             * 初始化DOM结构
             *
             * @protected
             * @override
             */
            initStructure: function () {
                var controlHelper = this.helper;
                var mainEle = this.main;
                var html
                        = '<div id="${filterPanelId}" class="${filterPanelStyle}">'
                        + '<label id="${labelId}"></label>'
                        + '<div id="${contentPanelId}" class="${contentPanelStyle}"></div>'
                        + '</div>';
                mainEle.innerHTML = lib.format(
                    html,
                    {
                        filterPanelStyle: controlHelper.getPartClassName('panel'),
                        filterPanelId: controlHelper.getId('items-wrapper-panel'),
                        labelId: controlHelper.getId('items-label'),
                        contentPanelId: controlHelper.getId('items-panel'),
                        contentPanelStyle: controlHelper.getPartClassName('items-panel')
                    }
                );

                // 创建控件树
                this.initChildren(mainEle);
            },

            /**
             * 增加项
             * @param {Object} item 选中项的数据 格式如: {value: '', text: ''}
             * @public
             */
            addItem: function (item) {
                if (this.getItemByValue(item.value)) {
                    return;
                }
                this.datasource.push(item);
                this.buildItems();
            },

            /**
             * 获取提示已选项Panel
             * @return {Panel} 提示已选项Panel
             * @private
             */
            getSelectedItemsPanel: function () {
                var selectedPanelId = this.helper.getId('items-panel');
                return this.viewContext.get(selectedPanelId);
            },

            /**
             * 初始化事件交互
             *
             * @protected
             * @override
             */
            initEvents: function () {
                var me = this;
                this.helper.addDOMEvent(
                    me.main,
                    'click',
                    'a',
                    function (e) {
                        e.preventDefault();

                        var $target = $(e.currentTarget);

                        var value = $target.attr('data-value');
                        var text = $target.children(':first-child').text();
                        var item = {
                            value: value,
                            text: text
                        };

                        me.removeItem(item);
                    }
                );
            },

            /**
             * 移除选中项
             * @param {Object} item 选中项的数据 格式如: {value: '', text: ''}
             * @param {HtmlElement} target 取消选中的元素
             * @private
             */
            removeItem: function (item) {
                if (!item) {
                    return;
                }
                var selectedItem = this.getItemByValue(item.value);
                this.datasource = u.without(this.datasource, selectedItem);
                /**
                 * @event select
                 *
                 * 移除时触发
                 */
                this.fire('change', {
                    item: item
                });
                this.buildItems();
            },

            /**
             * 根据值获取整个选择项的数据
             * @param {string} value 值
             * @param {Object=} datasource 数据源
             * @return {Object} item 选中项的数据 格式如: {value: '', text: ''}
             * @public
             */
            getItemByValue: function (value) {
                var item;

                u.each(this.datasource, function (single, index) {
                    if (single.value === value) {
                        item = single;
                    }
                });
                return item;
            },

            /**
             * 重渲染
             *
             * @method
             * @protected
             * @override
             */
            repaint: painters.createRepaint(
                InputControl.prototype.repaint,
                {
                    name: ['datasource'],
                    paint: function (resultPanel, datasource) {
                        resultPanel.buildItems();
                    }
                },
                {
                    name: ['label'],
                    paint: function (resultPanel, selectedLabel) {
                        $(resultPanel.helper.getPart('items-label')).text(selectedLabel);
                    }
                }
            ),

            /**
             * 根据datasource生成选择项
             * @param {Array} datasource 选项列表数据源
             * @private
             */
            buildItems: function () {
                var html
                    = '<a href="#" class="${style}" data-value="${value}">'
                    + '<span>${text}</span>'
                    + '<span class="${iconClass} ${removeClass}"></span>'
                    + '</a>';
                var s = '';
                var helper = this.helper;

                u.forEach(this.datasource, function (item) {
                    s += lib.format(
                        html,
                        {
                            value: item.value,
                            text: item.text,
                            style: helper.getPartClassName('item'),
                            iconClass: helper.getIconClass(),
                            removeClass: helper.getPartClassName('remove')
                        }
                    );
                });
                var selectedItemsPanel = helper.getPart('items-panel');
                $(selectedItemsPanel).html(s);
            },

            /**
             * 获取选中的
             * @return {Object} 选中的条件
             */
            getSelectedItems: function () {
                var items = [];
                u.each(this.datasource, function (item, index) {
                    if (item.selected) {
                        items.push(item);
                    }
                });
                return items;
            },

            /**
             * 获取选中的值
             * @return {Object} 选中项
             */
            getValue: function () {
                var items = this.getSelectedItems();
                var valueArr = [];
                u.each(items, function (item, index) {
                    valueArr.push(item.value);
                });
                return valueArr;
            }
        }
    );

    esui.register(FilterResult);
    return FilterResult;
});
Esempio n. 3
0
    function (require) {
        // 引用创建SWF元素的帮助类
        require('./helper/swfHelper');
        var u = require('underscore');
        var Control = require('esui/Control');
        var eoo = require('eoo');
        var esui = require('esui/main');
        var $ = require('jquery');
        // 引用Flash swf的路径通过AMD路径计算
        var swfPath = require.toUrl('../resource/fClipboard.swf');

        /**
         * CopyButton类定义
         *
         * @class
         * @extends Control
         *
         * @constructor
         *
         * 创建新的CopyButton实例
         *
         * @param {Object} [options] 组件参数
         */
        var CopyButton = eoo.create(
            Control,
            {
                /**
                 * CopyButton类型用于注册到ESUI库
                 *
                 * @override
                 */
                type: 'CopyButton',

                /**
                 * 初始化传入参数
                 *
                 * @param {Object} options 初始化参数
                 * @override
                 */
                initOptions: function (options) {
                    var properties = {
                        /**
                         * @property {boolean}
                         *
                         * 是否把Flash Hover鼠标设置成小手
                         */
                        setHandCursor: true,
                        /**
                         * @property {string}
                         *
                         * 要拷贝到剪切板的字符串
                         */
                        content: ''
                    };
                    u.extend(properties, options);
                    this.$super([properties]);
                },

                /**
                 * @override
                 */
                initStructure: function () {
                    var helper = this.helper;
                    this.flashId = helper.getId('flash');
                    var jqFlashWrapper = $('<span id="' + helper.getId('flash-wrapper') + '"></span>');
                    var jqMainElement = $(this.main);

                    // 创建Flash页面元素
                    jqFlashWrapper.append(
                        $.flash.create(
                            {
                                id: this.flashId,
                                swf: swfPath,
                                width: '100%',
                                height: '100%',
                                wmode: 'transparent'
                            }
                        )
                    );

                    // 对齐元素
                    jqMainElement.append(jqFlashWrapper);
                    jqMainElement.css('position', 'relative');
                    jqFlashWrapper.css({
                        position: 'absolute',
                        top: 0,
                        left: 0,
                        bottom: 0,
                        right: 0
                    });
                },

                /**
                 * @override
                 */
                initEvents: function () {
                    var me = this;

                    me.copyScriptFun = me.id + '_proxy';
                    window[me.copyScriptFun] = u.bind(onCopyScript, me);
                    checkFlashState.call(me, function () {
                        /**
                         * Flash元素完成初始化时触发
                         *
                         * @event CopyButton#ready
                         */
                        me.fire('ready');
                    });
                },

                /**
                 * @override
                 */
                dispose: function () {
                    var helper = this.helper;
                    if (helper.isInStage('DISPOSED')) {
                        return;
                    }

                    // 移除添加的DOM元素
                    $(this.main).css('position', '');
                    $('#' + helper.getId('flash-wrapper')).remove();
                    // 清除全局Flash Proxy函数
                    delete window[this.copyScriptFun];
                    this.$super(arguments);
                }
            }
        );

        /**
         * 触发copy事件使用者从外部传入要拷贝到剪切板的内容
         *
         * @return {string} 需要拷贝到剪切板的内容
         * @private
         */
        function onCopyScript() {
            /**
             * 值变更时触发
             *
             * @event
             * @param {Object} e 事件参数
             * @param {string} e.content CopyButton当前content的值
             *
             * @example
             *     copyButtonInstance.on('copy', function (e) {
             *         // 上一次的值
             *         console.log(e.content);
             *         this.content = 'new value to copy';
             *     );
             */
            this.fire('copy', {
                content: this.content
            });

            return this.content;
        }

        /**
         * 循环检测 flash 的初始化情况,初始化后注册回调函数
         *
         * @param  {Function} callback 完成初始化后的回调函数
         */
        function checkFlashState(callback) {
            var me = this;
            var flash = $('#' + me.flashId)[0];
            if (flash.flashInit && flash.flashInit()) {
                flash.setHandCursor(me.setHandCursor);
                flash.setContentFuncName(me.copyScriptFun);

                if (callback) {
                    callback();
                }
            }
            else {
                setTimeout(
                    function () {
                        checkFlashState.call(me, callback);
                    },
                    10
                );
            }
        }

        esui.register(CopyButton);
        return CopyButton;
    }
Esempio n. 4
0
    function (require) {
        var u = require('underscore');
        var $ = require('jquery');
        var esui = require('esui/main');
        var InputControl = require('esui/InputControl');
        var eoo = require('eoo');
        var painters = require('esui/painters');

        /**
         * 单选框
         *
         * @extends InputControl
         * @constructor
         */
        var Radio = eoo.create(InputControl, {
            /**
             * 控件类型,始终为`"Radio"`
             *
             * @type {string}
             * @readonly
             * @override
             */
            type: 'Radio',

            /**
             * 初始化配置
             *
             * @protected
             * @override
             */
            initOptions: function (options) {
                var properties = {
                    /**
                     * @property {string} [selectedValue='']
                     *
                     * Radio的Value
                     */
                    selectedValue: ''
                };

                u.extend(properties, options);
                properties.name = properties.name || this.main.getAttribute('name');
                this.setProperties(properties);
            },

            /**
             * 初始化DOM结构
             *
             * @protected
             * @override
             */
            initStructure: function () {
                var name = this.name;
                var inputs = $('input[name="' + name + '"]');
                var id = this.helper.getId();
                var classes = this.helper.getPartClasses('custom');
                var count = 0;

                u.each(
                    inputs,
                    function (input) {
                        input = $(input);
                        var inputId = id + '-part' + count++;
                        inputId = input.attr('id') || inputId;
                        input.attr('id', inputId);
                        input.wrap('<div class="' + classes + '"></div>');

                        var labelValue = input.data('label');
                        var label = $('<label for="' + inputId + '">' + labelValue + '</label>');
                        input.after(label);
                    }
                );
            },

            /**
             * 初始化事件交互
             *
             * @protected
             * @override
             */
            initEvents: function () {
                var name = this.name;
                var inputs = $('input[name="' + name + '"]');
                var that = this;

                inputs.on('change', function () {
                    var value = $('input[name="' + name + '"]:checked').val();
                    that.setValue(value);
                    that.fire('change', {
                        value: value
                    });
                });
            },

            /**
             * 重渲染
             *
             * @method
             * @protected
             * @override
             */
            repaint: painters.createRepaint(
                InputControl.prototype.repaint,
                {
                    /**
                     * @property {string} selectedValue
                     */
                    name: 'selectedValue',
                    paint: function (box, selectedValue) {
                        var name = box.name;
                        $('input[name="' + name + '"][value="' + selectedValue + '"]').prop('checked', true);
                    }
                },
                {
                    name: 'disabled',
                    paint: function (box, disabled) {
                        var name = box.name;
                        var inputs = $('input[name="' + name + '"]');

                        if (disabled) {
                            inputs.prop('disabled', true);
                        }
                        else {
                            inputs.prop('disabled', false);
                        }
                    }
                }
            )
        });

        esui.register(Radio);
        return Radio;
    }