bat-ria
Version:
RIA extension for Brand Ads Team
649 lines (570 loc) • 20.2 kB
JavaScript
/**
* ADM 2.0
* Copyright 2014 Baidu Inc. All rights reserved.
*
* @ignore
* @file 富选择单元控件
* @author lixiang(lixiang05@baidu.com)
*/
define(
function (require) {
require('esui/Label');
require('esui/Panel');
require('esui/SearchBox');
var lib = require('esui/lib');
var painter = require('esui/painters');
var InputControl = require('esui/InputControl');
var u = require('underscore');
/**
* 控件类
*
* @constructor
* @param {Object} options 初始化参数
*/
function RichSelector(options) {
InputControl.apply(this, arguments);
}
lib.inherits(RichSelector, InputControl);
/**
* 控件类型,始终为`"RichSelector"`
*
* @type {string}
* @readonly
* @override
*/
RichSelector.prototype.type = 'RichSelector';
/**
* @override
*/
RichSelector.prototype.initOptions = function (options) {
var properties = {
height: '200',
width: '200',
// 是否需要标题栏
hasHead: true,
// 这个名字出现在标题栏
title: '标题名',
// 是否需要批量操作
needBatchAction: false,
// 批量操作文字
batchActionLabel: '批量操作',
// 是否有搜索功能
hasSearchBox: true,
// 是否有腿部信息
hasFoot: true,
// 这个字段是对腿部信息的填充
itemName: '结果',
// 搜索为空的提示
emptyText: '没有相应的搜索结果',
// 是否刷新数据时保持搜索状态
holdState: false,
// 选择器类型 'load', 'add', 'delete'
// load: 点击某个节点,加载 出一堆别的数据,主要用于样式区分
// add: 点击一个节点,把这个节点加到另一个容器里
// delete: 点击一个节点,删
mode: 'add',
multi: true
};
if (options.hasHead === 'false') {
options.hasHead = false;
}
if (options.hasSearchBox === 'false') {
options.hasSearchBox = false;
}
if (options.hasFoot === 'false') {
options.hasFoot = false;
}
if (options.holdState === 'false') {
options.holdState = false;
}
if (options.multi === 'false') {
options.multi = false;
}
// load型的选择器只能是单选的
if (options.mode === 'load') {
options.multi = false;
}
lib.extend(properties, options);
// properties.width = Math.max(200, properties.width);
this.setProperties(properties);
};
/**
* 获取头部HTML
*
* @return {string} 头部HTML代码
*/
RichSelector.prototype.getHeadHTML = function () {
var helper = this.helper;
var actionLink = '';
if (this.needBatchAction) {
var linkClassName =
helper.getPartClassName('batch-action-link');
var linkId = this.helper.getId('batch-action');
actionLink = ''
+ '<span class="' + linkClassName
+ '" id="' + linkId + '" >'
+ this.batchActionLabel
+ '</span>';
}
var head = [
'<div data-ui="type:Panel;childName:head;"',
' class="${headClass}">',
'<h3 data-ui="type:Label;childName:title;">',
'${title}</h3>',
'${actionLink}',
'</div>'
].join('\n');
head = lib.format(
head,
{
headClass: helper.getPartClassName('head'),
title: this.title,
actionLink: actionLink
}
);
return head;
};
/**
* 获取底部HTML
*
* @return {string} 底部HTML代码
*/
RichSelector.prototype.getFootHTML = function () {
return [
'<div data-ui="type:Panel;childName:foot;"',
' class="' + this.helper.getPartClassName('foot') + '">',
'<span data-ui="type:Label;childName:totalCount">',
'</span>',
'</div>'
].join('\n');
};
/**
* @override
*/
RichSelector.prototype.initStructure = function () {
/* eslint-disable fecs-indent */
var tpl = [
// 表头
'${head}',
// 内容
'<div data-ui="type:Panel;childName:body;"',
' class="${bodyClass}">',
'${searchInput}',
// 搜索结果列表区
'<div data-ui="type:Panel;childName:content"',
' class="${contentClass}">',
// 结果为空提示
'<div data-ui="type:Label;childName:emptyText"',
' class="${emptyTextClass}">${emptyText}</div>',
// 结果列表
'<div data-ui="type:Panel;childName:queryList"',
' class="${queryListClass}">',
'</div>',
'</div>',
'</div>',
// 腿部概要信息
'${footInfo}'
];
/* eslint-enable fecs-indent */
var helper = this.helper;
var head = '';
if (this.hasHead) {
head = this.getHeadHTML();
}
var searchInput = '';
if (this.hasSearchBox) {
var searchBoxWidth = this.width - 45;
// var searchBoxWidth = 150;
searchInput = [
// 搜索区
'<div data-ui="type:Panel;childName:searchBoxArea"',
' class="${searchWrapperClass}">',
'<div data-ui="type:SearchBox;childName:itemSearch;"',
' data-ui-skin="magnifier"',
' data-ui-width="' + searchBoxWidth + '">',
'</div>',
'</div>',
// 搜索结果概要
'<div data-ui="type:Panel;',
'childName:generalQueryResultArea"',
' class="${generalQueryResultClass}"',
' id="${queryResultId}">',
'<span class="${linkClass}" id="${linkId}">清空</span>',
'共找到<span id="${queryResultCountId}"></span>个',
'</div>'
].join('\n');
searchInput = lib.format(
searchInput,
{
searchWrapperClass:
helper.getPartClassName('search-wrapper'),
generalQueryResultClass:
helper.getPartClassName('query-result-general'),
queryResultCountId: helper.getId('result-count'),
linkClass: helper.getPartClassName('clear-query-link'),
linkId: helper.getId('clear-query')
}
);
}
var footInfo = '';
if (this.hasFoot) {
footInfo = this.getFootHTML();
}
this.main.style.width = this.width + 'px';
this.main.innerHTML = lib.format(
tpl.join('\n'),
{
head: head,
bodyClass: helper.getPartClassName('body'),
searchInput: searchInput,
contentClass: helper.getPartClassName('content-wrapper'),
emptyTextClass: helper.getPartClassName('empty-text'),
emptyText: this.emptyText,
queryListClass: helper.getPartClassName('query-list'),
footInfo: footInfo
}
);
this.initChildren();
// 初始化模式状态
if (this.mode === 'load') {
this.addState('load');
}
else if (this.mode === 'add') {
this.addState('add');
}
else {
this.addState('del');
}
// 绑事件
var batchActionLink = helper.getPart('batch-action');
if (batchActionLink) {
helper.addDOMEvent(
batchActionLink,
'click',
u.bind(this.batchAction, this)
);
}
var clearQueryLink = helper.getPart('clear-query');
if (clearQueryLink) {
helper.addDOMEvent(
clearQueryLink,
'click',
u.bind(this.clearQuery, this)
);
}
var searchBox = this.getSearchBox();
if (searchBox) {
searchBox.on('search', this.search, this);
}
// 为备选区绑定事件
var queryList = this.getQueryList().main;
helper.addDOMEvent(
queryList,
'click',
u.bind(this.eventDispatcher, this)
);
};
/**
* 点击行为分发器
* @param {Event} e 事件对象
* @return {false} 阻止默认行为
* @ignore
*/
RichSelector.prototype.eventDispatcher = function (e) {
return false;
};
/**
* 根据关键词搜索结果
* @param {event} e SearchBox的点击事件对象
* @ignore
*/
RichSelector.prototype.search = function (e) {
var keyword = lib.trim(e.target.getValue());
// 查询
this.queryItem(keyword);
// 更新概要搜索结果区
this.refreshResult();
// 更新腿部总结果
this.refreshFoot();
// 更新状态
this.addState('queried');
// 调整高度
this.adjustHeight();
};
RichSelector.prototype.refreshResult = function () {
var count = this.getCurrentStateItemsCount();
this.helper.getPart('result-count').innerHTML = count;
};
/**
* 清除搜索结果
* @param {ui.RichSelector} richSelector 类实例
* @return {false} 阻止默认行为
* @ignore
*/
RichSelector.prototype.clearQuery = function () {
// 更新状态
this.removeState('queried');
// 清空搜索框
var searchBox = this.getSearchBox();
if (searchBox) {
searchBox.set('text', '');
}
// 清空数据
this.clearData();
// 概要搜索结果区归零
this.refreshResult();
// 更新备选区
this.refreshContent();
// 更新腿部总结果
this.refreshFoot();
// 调整高度
this.adjustHeight();
return false;
};
/**
* 获取结果列表承载容器控件,列表在它里面
* @param {ui.RichSelector} richSelector 类实例
* @return {ui.Panel}
* @ignore
*/
RichSelector.prototype.getContent = function () {
var body = this.getChild('body');
if (body) {
return body.getChild('content');
}
return null;
};
RichSelector.prototype.getKeyword = function () {
var searchBox = this.getSearchBox();
var isQuery = this.isQuery();
if (searchBox && isQuery) {
return lib.trim(searchBox.getValue());
}
return null;
};
/**
* 获取结果列表控件
* @return {ui.TreeForSelector | ui.ListForSelector}
* @ignore
*/
RichSelector.prototype.getQueryList = function () {
var content = this.getContent();
if (content) {
return content.getChild('queryList');
}
return null;
};
/**
* 获取搜索控件
* @return {ui.Panel}
* @ignore
*/
RichSelector.prototype.getSearchBox = function () {
var searchBoxArea =
this.getChild('body').getChild('searchBoxArea');
if (searchBoxArea) {
return searchBoxArea.getChild('itemSearch');
}
};
/**
* 获取腿部总个数容器
* @param {ui.RichSelector} richSelector 类实例
* @return {ui.Panel}
* @ignore
*/
RichSelector.prototype.getTotalCountPanel = function () {
var foot = this.getChild('foot');
if (!foot) {
return null;
}
return foot.getChild('totalCount');
};
/**
* 判断是否处于query状态
* @return {boolean}
*/
RichSelector.prototype.isQuery = function () {
return this.hasState('queried');
};
/**
* 批量操作事件处理
* 可重写
*
* @return {false} 阻止默认行为
*/
RichSelector.prototype.batchAction = function () {
if (this.mode === 'delete') {
this.deleteAll();
this.refreshFoot();
}
else if (this.mode === 'add') {
this.selectAll();
}
return false;
};
RichSelector.prototype.deleteAll = function () {
return false;
};
RichSelector.prototype.addAll = function () {
return false;
};
/**
* 调整高度。
* 出现搜索信息时,结果区域的高度要变小,才能使整个控件高度不变
*
*/
RichSelector.prototype.adjustHeight = function() {
// 用户设置总高度
var settingHeight = this.height;
// 头部高度 contentHeight + border
var headHeight = 28;
// 是否有搜索框
var searchBoxHeight = this.hasSearchBox ? 45 : 0;
// 是否有腿部信息
var footHeight = this.hasFoot ? 25 : 0;
var content = this.getContent().main;
if (settingHeight === 'auto') {
content.style.height = 'auto';
}
else {
// 结果区高度 = 总高度 - 头部高度 - 搜索框高度 - 腿部高度
var contentHeight =
settingHeight - headHeight - searchBoxHeight - footHeight;
// 处于query状态时,会有一个30px的概要信息区
if (this.isQuery()) {
contentHeight -= 30;
}
content.style.height = contentHeight + 'px';
}
};
RichSelector.prototype.adaptData = function () {};
/**
* 手动刷新
*
* @param {ui.RichSelector} richSelector 类实例
* @ignore
*/
RichSelector.prototype.refresh = function () {
// 刷新搜索区
if (this.hasSearchBox) {
// 有的时候需要保留搜索状态
if (this.holdState && this.isQuery()) {
var keyword = this.getKeyword();
// 根据关键字获取结果
this.queryItem(keyword);
}
else {
// 清空搜索区
this.clearQuery();
// 重建数据
this.adaptData();
// 构建选区
this.refreshContent();
}
}
else {
// 重建数据
this.adaptData();
// 构建选区
this.refreshContent();
}
// 更新底部信息
this.refreshFoot();
// 更新高度
this.adjustHeight();
};
/**
* 更新腿部信息
*
* @param {ui.RichSelector} richSelector 类实例
* @ignore
*/
RichSelector.prototype.refreshFoot = function () {
if (!this.hasFoot) {
return;
}
var count = this.getCurrentStateItemsCount();
// 更新腿部总结果
var totalCountPanel = this.getTotalCountPanel();
if (totalCountPanel) {
var itemName = u.escape(this.itemName);
totalCountPanel.setText('共 ' + count + ' 个' + itemName);
}
};
RichSelector.prototype.getCurrentStateItemsCount = function () {
return 0;
};
/**
* 重新渲染视图
* 仅当生命周期处于RENDER时,该方法才重新渲染
*
* @param {Array} 变更过的属性的集合
* @override
*/
RichSelector.prototype.repaint = painter.createRepaint(
InputControl.prototype.repaint,
{
name: 'title',
paint: function (control, title) {
var head = control.getChild('head');
var titleLabel = head && head.getChild('title');
titleLabel && titleLabel.setText(title);
}
}
);
/**
* 获取已经选择的数据项
* 就是一个代理,最后从结果列表控件里获取
* @return {Array}
* @public
*/
RichSelector.prototype.getSelectedItems = function () {
return [];
};
/**
* 批量更新状态
* @param {Array} items 需要更新的对象集合
* @param {boolean} toBeSelected 要选择还是取消选择
* @public
*/
/**
* 批量更新选择状态
* @param {Array} items 需要更新的对象集合
* @param {boolean} toBeSelected 要选择还是取消选择
* @public
*/
RichSelector.prototype.selectItems = function (items, toBeSelected) {};
/**
* 设置元数据
*
* @param {Array} selectedItems 置为选择的项.
*/
RichSelector.prototype.setRawValue = function (selectedItems) {
this.rawValue = selectedItems;
this.selectItems(selectedItems, true);
};
/**
* 获取已经选择的数据项
*
* @return {Array}
*/
RichSelector.prototype.getRawValue = function () {
return this.getSelectedItems();
};
/**
* 将value从原始格式转换成string
*
* @param {*} rawValue 原始值
* @return {string}
*/
RichSelector.prototype.stringifyValue = function (rawValue) {
var selectedIds = [];
u.each(rawValue, function (item) {
selectedIds.push(item.id);
});
return selectedIds.join(',');
};
require('esui').register(RichSelector);
return RichSelector;
}
);