blob: 4a3471e692d1a1c52418b4122a5314bc6f2373a5 [file] [log] [blame]
/**
* @file 简单的小按钮(支持鼠标按住移入移出控件区域时的视图变化)
* @author sushuang(sushuang@baidu.com)
* @date 2014-03
*/
define(function (require) {
var $ = require('jquery');
var Component = require('./Component');
var lib = require('../lib');
// Constant
var MAIN_CSS = 'dtui-btn';
var EVENTS = ['click', 'mouseenter', 'mouseleave'];
/**
* 模板中声明方法举例:
* <div data-cpt="
* type: 'button',
* name: 'xxxxx',
* text: lib.ob('this is a button')"></div>
* 或
* <div data-cpt="
* type: 'button',
* name: 'xxxxx',
* viewModel: {
* text: lib.ob('this is a button')
* }"></div>
*
* @class
* @extends common/component/Component
*/
var Button = Component.extend({
/**
* @protected
* @type {Object}
*/
_define: {
viewModel: function () {
return {
// button内的文字。如果text是lib.ob,则可由外部控制文字的变化。
text: lib.ob(''),
// encodeHTML是否交由控件负责
dontEncodeHTML: false
};
},
viewModelPublic: ['text'],
css: MAIN_CSS
},
/**
* @override
* @protected
*/
_init: function () {
var viewModel = this._viewModel();
var $el = this.$el();
var that = this;
var hoverCss = this.getFullCss('-hover').join(' ');
var activeCss = this.getFullCss('-active').join(' ');
var actived = false;
var $doc = $(document);
this._eventHandlerMap = {};
$el.on(this._event('mouseenter'), onMouseEnter);
$el.on(this._event('mouseleave'), onMouseLeave);
$el.on(this._event('mousedown'), onMouseDown);
$el.on(this._event('mouseup'), onMouseUp);
var me = this;
$.each(EVENTS, function (idx, eventName) {
$el.on(me._event(eventName), function (e) {
me.trigger.call(me, eventName, e);
});
});
// binding ob
if (lib.obTypeOf(viewModel.text) === 'ob') {
this._disposable(
viewModel.text.subscribe(updateViewByModel, this)
);
}
// 设初始值
var initVal = lib.value(viewModel.text);
$el.html(
viewModel.dontEncodeHTML ? initVal : lib.encodeHTML(initVal)
);
function onMouseEnter() {
if (viewModel.disabled()) {
return;
}
$el.addClass(hoverCss);
if (actived) {
$el.addClass(activeCss);
}
}
function onMouseLeave() {
$el.removeClass(hoverCss);
$el.removeClass(activeCss);
}
function onMouseDown() {
if (viewModel.disabled()) {
return;
}
$el.addClass(activeCss);
actived = true;
// FIXME
// 这个简单实现并不仔细(stopPropagation),但是暂不认为影响很大。
$doc.one(
that._event('mouseup'),
function () {
actived = false;
}
);
}
function onMouseUp() {
$el.removeClass(activeCss);
}
function updateViewByModel(nextText) {
// 暂时内部所有内容都当做text
$el.html(
viewModel.dontEncodeHTML
? nextText
: lib.encodeHTML(nextText)
);
}
},
/**
* @override
* @protected
*/
_parseViewModel: function (inputViewModel, cptDef) {
// 兼容直接在ctpDef设text,而非在viewModel上设text的情况。
// 这是为了简化模板书写。
if (cptDef.text != null) {
inputViewModel.text = cptDef.text;
}
if (cptDef.css != null) {
inputViewModel.css = cptDef.css;
}
if (cptDef.dontEncodeHTML != null) {
inputViewModel.dontEncodeHTML = cptDef.dontEncodeHTML;
}
return inputViewModel;
},
/**
* 注册事件:click、mouseenter、mouseleave
*
* @public
* @param {string} event 不可带后缀
* @param {Function} handler 处理器
*/
on: function (event, handler) {
lib.assert(event.indexOf('.') < 0);
var eventHandlerMap = this._eventHandlerMap;
if ($.inArray(event, EVENTS) >= 0) {
eventHandlerMap[event] = eventHandlerMap[event] || [];
eventHandlerMap[event].push(handler);
}
},
/**
* 触发事件处理handle
*
* @public
* @param {string} eventName 要触发的事件名
* @param {Object} event 事件对象
*/
trigger: function (eventName, event) {
var viewModel = this._viewModel();
var handleList = this._eventHandlerMap[eventName];
if (viewModel.disabled()) {
return;
}
if (handleList && handleList.length) {
$.each(handleList, function (idx, handle) {
if ($.isFunction(handle)) {
handle.call(this, event);
}
});
}
},
/**
* 销毁
*
* @override
* @protected
*/
_dispose: function () {
this.$el().off();
this._eventHandlerMap = null;
}
});
return Button;
});