/** * @class BI.Combo * @extends BI.Widget */ BI.Combo = BI.inherit(BI.Widget, { _defaultConfig: function () { var conf = BI.Combo.superclass._defaultConfig.apply(this, arguments); return BI.extend(conf, { baseCls: (conf.baseCls || "") + " bi-combo", trigger: "click", toggle: true, direction: "bottom", //top||bottom||left||right||top,left||top,right||bottom,left||bottom,right isDefaultInit: false, isNeedAdjustHeight: true,//是否需要高度调整 isNeedAdjustWidth: true, stopEvent: false, stopPropagation: false, adjustLength: 0,//调整的距离 adjustXOffset: 0, adjustYOffset: 0, hideChecker: BI.emptyFn, offsetStyle: "left", //left,right,center el: {}, popup: {}, comboClass: "bi-combo-popup", hoverClass: "bi-combo-hover" }) }, _init: function () { BI.Combo.superclass._init.apply(this, arguments); var self = this, o = this.options; this._initCombo(); this._initPullDownAction(); this.combo.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (self.isEnabled() && this.isEnabled()) { if (type === BI.Events.EXPAND) { self._popupView(); } if (type === BI.Events.COLLAPSE) { self._hideView(); } if (type === BI.Events.EXPAND || type === BI.Events.COLLAPSE) { self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); } if (type === BI.Events.CLICK) { self.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE, obj); } } }); self.element.on("mouseenter." + self.getName(), function (e) { if (self.isEnabled() && self.combo.isEnabled()) { self.element.addClass(o.hoverClass); } }); self.element.on("mouseleave." + self.getName(), function (e) { if (self.isEnabled() && self.combo.isEnabled()) { self.element.removeClass(o.hoverClass); } }); BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [ {el: this.combo} ] }); o.isDefaultInit && (this._assertPopupView()); BI.Resizers.add(this.getName(), BI.bind(function () { if (this.isViewVisible()) { this._hideView(); } }, this)); }, _toggle: function () { this._assertPopupViewRender(); if (this.popupView.isVisible()) { this._hideView(); } else { if (this.isEnabled()) { this._popupView(); } } }, _initPullDownAction: function () { var self = this, o = this.options; var evs = this.options.trigger.split(","); var st = function (e) { if (o.stopEvent) { e.stopEvent(); } if (o.stopPropagation) { e.stopPropagation(); } }; BI.each(evs, function (i, ev) { switch (ev) { case "hover": self.element.on("mouseenter." + self.getName(), function (e) { if (self.isEnabled() && self.combo.isEnabled()) { self._popupView(); self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); self.fireEvent(BI.Combo.EVENT_EXPAND); } }); self.element.on("mouseleave." + self.getName(), function (e) { if (self.isEnabled() && self.combo.isEnabled() && o.toggle === true) { self._hideView(); self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); self.fireEvent(BI.Combo.EVENT_COLLAPSE); } }); break; case "click": var debounce = BI.debounce(function (e) { if (self.combo.element.__isMouseInBounds__(e)) { if (self.isEnabled() && self.combo.isEnabled()) { o.toggle ? self._toggle() : self._popupView(); if (self.isViewVisible()) { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.EXPAND, "", self.combo); self.fireEvent(BI.Combo.EVENT_EXPAND); } else { self.fireEvent(BI.Controller.EVENT_CHANGE, BI.Events.COLLAPSE, "", self.combo); self.fireEvent(BI.Combo.EVENT_COLLAPSE); } } } }, BI.EVENT_RESPONSE_TIME, true); self.element.off(ev + "." + self.getName()).on(ev + "." + self.getName(), function(e){ debounce(e); st(e); }); break; } }); }, _initCombo: function () { this.combo = BI.createWidget(this.options.el); }, _assertPopupView: function () { var self = this; if (this.popupView == null) { this.popupView = BI.createWidget(this.options.popup, { type: "bi.popup_view" }); this.popupView.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { if (type === BI.Events.CLICK) { self.combo.setValue(self.getValue()); self.fireEvent(BI.Combo.EVENT_CHANGE, value, obj); } self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); }); this.popupView.setVisible(false); BI.nextTick(function () { self.fireEvent(BI.Combo.EVENT_AFTER_INIT); }); } }, _assertPopupViewRender: function () { this._assertPopupView(); if (!this._rendered) { BI.createWidget({ type: "bi.vertical", scrolly: false, element: this, items: [ {el: this.popupView} ] }); this._rendered = true; } }, _hideIf: function (e) { if (this.element.__isMouseInBounds__(e) || (this.popupView && this.popupView.element.__isMouseInBounds__(e))) { return; } if (this.element.find(e.target).length > 0) { return; } var isHide = this.options.hideChecker.apply(this, [e]); if (isHide === false) { return; } this._hideView(); }, _hideView: function () { this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW); this.popupView && this.popupView.invisible(); this.element.removeClass(this.options.comboClass); $(document).unbind("mousedown." + this.getName()).unbind("mousewheel." + this.getName()); this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW); }, _popupView: function () { this._assertPopupViewRender(); this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW); this.popupView.visible(); this.adjustWidth(); this.adjustHeight(); this.element.addClass(this.options.comboClass); $(document).bind("mousedown." + this.getName(), BI.bind(this._hideIf, this)).bind("mousewheel." + this.getName(), BI.bind(this._hideIf, this)); this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW); }, adjustWidth: function () { var o = this.options; if (!this.popupView) { return; } if (o.isNeedAdjustWidth === true) { this.resetListWidth(""); var width = this.popupView.element.outerWidth(); var maxW = this.element.outerWidth() || o.width; if (width > maxW + 80) { maxW = maxW + 80; } else if (width > maxW) { maxW = width; } this.resetListWidth(maxW < 100 ? 100 : maxW); } }, adjustHeight: function () { var o = this.options, p = {}; if (!this.popupView) { return; } var isVisible = this.popupView.isVisible(); this.popupView.visible(); switch (o.direction) { case "bottom": case "bottom,right": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'right', 'left'], o.offsetStyle); break; case "top": case "top,right": p = $.getComboPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'right', 'left'], o.offsetStyle); break; case "left": case "left,bottom": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'bottom', 'top'], o.offsetStyle); break; case "right": case "right,bottom": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'bottom', 'top'], o.offsetStyle); break; case "top,left": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['top', 'bottom', 'left', 'right'], o.offsetStyle); break; case "bottom,left": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight, ['bottom', 'top', 'left', 'right'], o.offsetStyle); break; case "left,top": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['left', 'right', 'top', 'bottom'], o.offsetStyle); break; case "right,top": p = $.getComboPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength, o.adjustYOffset, o.isNeedAdjustHeight, ['right', 'left', 'top', 'bottom'], o.offsetStyle); break; case "top,custom": case "custom,top": p = $.getTopAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); break; case "custom,bottom": case "bottom,custom": p = $.getBottomAdaptPosition(this.combo, this.popupView, o.adjustYOffset || o.adjustLength, o.isNeedAdjustHeight); break; case "left,custom": case "custom,left": p = $.getLeftAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); delete p.top; delete p.adaptHeight; break; case "custom,right": case "right,custom": p = $.getRightAdaptPosition(this.combo, this.popupView, o.adjustXOffset || o.adjustLength); delete p.top; delete p.adaptHeight; break; } if ("adaptHeight" in p) { this.resetListHeight(p['adaptHeight']); } if ("left" in p) { this.popupView.element.css({ left: p.left }); } if ("top" in p) { this.popupView.element.css({ top: p.top }); } this.position = p; this.popupView.setVisible(isVisible); }, resetListHeight: function (h) { this._assertPopupView(); this.popupView.resetHeight && this.popupView.resetHeight(h); }, resetListWidth: function (w) { this._assertPopupView(); this.popupView.resetWidth && this.popupView.resetWidth(w); }, populate: function (items) { this._assertPopupView(); this.popupView.populate.apply(this.popupView, arguments); this.combo.populate.apply(this.combo, arguments); }, setEnable: function (arg) { BI.Combo.superclass.setEnable.apply(this, arguments); this.combo && this.combo.setEnable(arg); this.popupView && this.popupView.setEnable(arg); !arg && this.isViewVisible() && this._hideView(); }, setValue: function (v) { this._assertPopupView(); this.combo.setValue(v); this.popupView && this.popupView.setValue(v); }, getValue: function () { this._assertPopupView(); return this.popupView && this.popupView.getValue(); }, isViewVisible: function () { return this.isEnabled() && this.combo.isEnabled() && !!this.popupView && this.popupView.isVisible(); }, showView: function () { if (this.isEnabled() && this.combo.isEnabled()) { this._popupView(); } }, hideView: function () { this._hideView(); }, getView: function () { return this.popupView; }, getPopupPosition: function () { return this.position; }, doBehavior: function () { this._assertPopupView(); this.popupView && this.popupView.doBehavior.apply(this.popupView, arguments); }, toggle: function () { this._toggle(); }, destroy: function () { $(document).unbind("mousedown." + this.getName()) .unbind("mousewheel." + this.getName()) .unbind("mouseenter." + this.getName()) .unbind("mousemove." + this.getName()) .unbind("mouseleave." + this.getName()); BI.Resizers.remove(this.getName()); BI.Combo.superclass.destroy.apply(this, arguments); } }); BI.Combo.EVENT_TRIGGER_CHANGE = "EVENT_TRIGGER_CHANGE"; BI.Combo.EVENT_CHANGE = "EVENT_CHANGE"; BI.Combo.EVENT_EXPAND = "EVENT_EXPAND"; BI.Combo.EVENT_COLLAPSE = "EVENT_COLLAPSE"; BI.Combo.EVENT_AFTER_INIT = "EVENT_AFTER_INIT"; BI.Combo.EVENT_BEFORE_POPUPVIEW = "EVENT_BEFORE_POPUPVIEW"; BI.Combo.EVENT_AFTER_POPUPVIEW = "EVENT_AFTER_POPUPVIEW"; BI.Combo.EVENT_BEFORE_HIDEVIEW = "EVENT_BEFORE_HIDEVIEW"; BI.Combo.EVENT_AFTER_HIDEVIEW = "EVENT_AFTER_HIDEVIEW"; BI.shortcut("bi.combo", BI.Combo);