blob: 9a591df407a08c795d77c85b4436a6293833c0d0 [file] [log] [blame]
/**
* @file Check buttons and radio buttons.
* @author sushuang(sushuang@baidu.com)
*/
define(function (require) {
var $ = require('jquery');
var lib = require('../lib');
var Component = require('./Component');
var encodeHTML = lib.encodeHTML;
// Constant
var INDEX_ATTR = 'value-index';
/**
* @class
* @extends dt/ui/Component
*/
var CheckButton = Component.extend({
_define: {
css: 'dtui-chkbtn',
viewModel: function () {
return {
/**
* 如果是lib.ob则表示单选,其值对应于dataList中的value,表示选中的项。
* 如果是lib.obArray则表示多选,obArray中每项表示被选中的值。
* 在其subcription响应函数中,如:
* checkBtn.viewModel('checked').subscribe(function (nextValue, ob) {
* var dataItem = ob.peekValueInfo(); // 可以得到该项的传入数据。
* })
*/
checked: lib.ob(),
/**
* 每项为:
* {
* value: ..., // value可以为任意类型。不禁止value重复。如果重复,同value的项会同时被选中。
* text: ..., // 本控件负责encodeHTML
* tooltip: ..., // 鼠标hover提示文字,如果需要的话,string。
* tooltipEncodeHTML: ... // 文字是否要encdeHTML,默认为true。
* }
* 不能有空项。value可为任意基本类型。
*/
dataList: []
};
},
viewModelPublic: ['checked']
},
/**
* @public
*/
getDataItem: function (value) {
var dataList = this._viewModel().dataList;
var index = lib.arrayIndexOf(dataList, value, 'value');
return index >= 0 ? $.extend({}, dataList[index]) : null;
},
/**
* @override
*/
_init: function () {
lib.assert(lib.obTypeOf(this._viewModel().checked));
this._initContent();
this._initTooltip();
this._initChange();
this._initMouse();
},
/**
* @private
*/
_getItemCss: function (type) {
var suffix = ({
'': '-i',
'hover': '-i-hover',
'active': '-i-active'
})[type || ''];
return this.css() + suffix;
},
/**
* @private
*/
_initContent: function () {
var dataList = this._viewModel().dataList;
var itemCss = this._getItemCss();
var html = [];
for (var i = 0, data; data = dataList[i]; i++) {
html.push(
'<span class="', itemCss, '" data-', INDEX_ATTR, '="', i, '">',
encodeHTML(data.text),
'</span>'
);
}
this.el().innerHTML = html.join('');
},
/**
* @private
*/
_initTooltip: function () {
var dataList = this._viewModel().dataList;
var loc = {
x: 0,
y: -15,
xAnchor: 'center',
yAnchor: 'bottom'
};
this._disposable(lib.bindTooltip({
bindEl: this.el(),
followMouse: true,
selector: '.' + this._getItemCss(),
location: loc,
text: getText,
encodeHTML: false // 在getText中处理encodeHTML
}));
function getText(itemEl) {
var dataItem = dataList[$(itemEl).data(INDEX_ATTR)];
var tooltipText = dataItem.tooltip;
if (tooltipText != null) {
return dataItem.tooltipEncodeHTML !== false
? encodeHTML(tooltipText) : tooltipText;
}
// 返回空则不显示tooltip
}
},
/**
* @private
*/
_initChange: function () {
var viewModel = this._viewModel();
var $items = this.$el().find('.' + this._getItemCss());
var itemActiveCss = this._getItemCss('active');
// binding ob
this._disposable(
lib.obSubscribe(viewModel.checked, updateViewByModel)
);
// 设初始值
updateViewByModel(viewModel.checked());
function updateViewByModel(nextValue) {
var obType = lib.obTypeOf(viewModel.checked);
$items.each(function () {
var $this = $(this);
var thisValue = viewModel.dataList[$this.data(INDEX_ATTR)].value;
$this[
(
obType === 'obArray'
? lib.arrayIndexOf(nextValue, thisValue) >= 0 // 多选情况
: thisValue === nextValue // 单选情况
)
? 'addClass' : 'removeClass'
](itemActiveCss);
});
}
},
/**
* @private
*/
_initMouse: function () {
var $el = this.$el();
var viewModel = this._viewModel();
var itemCss = this._getItemCss();
var itemHoverCss = this._getItemCss('hover');
var insUID = this.uid();
// 鼠标事件
$el.on(this._event('mouseenter'), '.' + itemCss, onMouseEnter);
$el.on(this._event('mouseleave'), '.' + itemCss, onMouseLeave);
$el.on(this._event('click'), '.' + itemCss, onClick);
function onMouseEnter() {
if (viewModel.disabled()) {
return;
}
$(this).addClass(itemHoverCss);
}
function onMouseLeave() {
$(this).removeClass(itemHoverCss);
}
function onClick() {
if (viewModel.disabled()) {
return;
}
var item = viewModel.dataList[$(this).data(INDEX_ATTR)];
var currValue = item.value;
if (lib.obTypeOf(viewModel.checked) === 'obArray') {
var checkedValues = viewModel.checked();
var index = lib.arrayIndexOf(checkedValues, currValue);
if (index >= 0) {
checkedValues.splice(index, 1);
}
else {
checkedValues.push(currValue);
}
currValue = checkedValues;
}
viewModel.checked(
currValue,
lib.valueInfoForConfirmed(insUID, {dataItem: item})
);
}
}
});
return CheckButton;
});