devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
435 lines (364 loc) • 13.1 kB
JavaScript
"use strict";
var $ = require("../core/renderer"),
themes = require("./themes"),
registerComponent = require("../core/component_registrator"),
grep = require("../core/utils/common").grep,
extend = require("../core/utils/extend").extend,
arrayUtils = require("../core/utils/array"),
iteratorUtils = require("../core/utils/iterator"),
ActionSheetStrategy = require("./toolbar/ui.toolbar.strategy.action_sheet"),
DropDownMenuStrategy = require("./toolbar/ui.toolbar.strategy.drop_down_menu"),
ListBottomStrategy = require("./toolbar/ui.toolbar.strategy.list_bottom"),
ListTopStrategy = require("./toolbar/ui.toolbar.strategy.list_top"),
ToolbarBase = require("./toolbar/ui.toolbar.base"),
ChildDefaultTemplate = require("./widget/child_default_template");
var STRATEGIES = {
actionSheet: ActionSheetStrategy,
dropDownMenu: DropDownMenuStrategy,
listBottom: ListBottomStrategy,
listTop: ListTopStrategy
};
var TOOLBAR_AUTO_HIDE_ITEM_CLASS = "dx-toolbar-item-auto-hide",
TOOLBAR_AUTO_HIDE_TEXT_CLASS = "dx-toolbar-text-auto-hide",
TOOLBAR_HIDDEN_ITEM = "dx-toolbar-item-invisible";
/**
* @name dxToolbar
* @publicName dxToolbar
* @inherits CollectionWidget
* @module ui/toolbar
* @export default
*/
var Toolbar = ToolbarBase.inherit({
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), {
/**
* @name dxToolbarOptions.menuItemTemplate
* @publicName menuItemTemplate
* @type template|function
* @default "menuItem"
* @type_function_param1 itemData:object
* @type_function_param2 itemIndex:number
* @type_function_param3 itemElement:dxElement
* @type_function_return string|Node|jQuery
*/
menuItemTemplate: "menuItem",
/**
* @name dxToolbarOptions.submenuType
* @publicName submenuType
* @type string
* @default 'dropDownMenu'
* @acceptValues 'actionSheet'|'listTop'|'listBottom'|'dropDownMenu'
* @hidden
*/
submenuType: "dropDownMenu"
/**
* @name dxToolbarItemTemplate.location
* @publicName location
* @type Enums.ToolbarItemLocation
* @default 'center'
*/
/**
* @name dxToolbarItemTemplate.locateInMenu
* @publicName locateInMenu
* @type Enums.ToolbarItemLocateInMenuMode
* @default 'never'
*/
/**
* @name dxToolbarItemTemplate.showText
* @publicName showText
* @type Enums.ToolbarItemShowTextMode
* @default 'always'
*/
/**
* @name dxToolbarItemTemplate.menuItemTemplate
* @publicName menuItemTemplate
* @type template|function
* @type_function_return string|Node|jQuery
*/
/**
* @name dxToolbarOptions.renderAs
* @publicName renderAs
* @type Enums.ToolbarRenderMode
* @default 'topToolbar'
*/
/**
* @name dxToolbarOptions.selectedIndex
* @publicName selectedIndex
* @type number
* @default -1
* @hidden
*/
/**
* @name dxToolbarOptions.activeStateEnabled
* @publicName activeStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.focusStateEnabled
* @publicName focusStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.accessKey
* @publicName accessKey
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.tabIndex
* @publicName tabIndex
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.selectedItems
* @publicName selectedItems
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.selectedItemKeys
* @publicName selectedItemKeys
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.keyExpr
* @publicName keyExpr
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.selectedItem
* @publicName selectedItem
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarOptions.onSelectionChanged
* @publicName onSelectionChanged
* @action
* @hidden
* @inheritdoc
*/
});
},
_defaultOptionsRules: function _defaultOptionsRules() {
return this.callBase().concat([{
device: function device() {
return (/ios7.*/.test(themes.current())
);
},
options: {
submenuType: "actionSheet"
}
}, {
device: function device() {
return (/android5.*/.test(themes.current())
);
},
options: {
submenuType: "dropDownMenu"
}
}, {
device: function device() {
return (/win8.*/.test(themes.current())
);
},
options: {
submenuType: "listBottom"
}
}, {
device: function device() {
return (/win10.*/.test(themes.current())
);
},
options: {
submenuType: "listTop"
}
}]);
},
_dimensionChanged: function _dimensionChanged(dimension) {
if (dimension === "height") {
return;
}
this._menuStrategy.toggleMenuVisibility(false, true);
this.callBase();
this._menuStrategy.renderMenuItems();
},
_initTemplates: function _initTemplates() {
this.callBase();
this._defaultTemplates["actionSheetItem"] = new ChildDefaultTemplate("item", this);
},
_initMarkup: function _initMarkup() {
this.callBase();
this._renderMenu();
},
_render: function _render() {
this._hideOverflowItems();
this._menuStrategy._updateMenuVisibility();
this.callBase();
this._menuStrategy.renderMenuItems();
},
_renderItem: function _renderItem(index, item, itemContainer, $after) {
var itemElement = this.callBase(index, item, itemContainer, $after);
if (item.locateInMenu === "auto") {
itemElement.addClass(TOOLBAR_AUTO_HIDE_ITEM_CLASS);
}
if (item.widget === "dxButton" && item.showText === "inMenu") {
itemElement.toggleClass(TOOLBAR_AUTO_HIDE_TEXT_CLASS);
}
return itemElement;
},
_hideOverflowItems: function _hideOverflowItems(elementWidth) {
var overflowItems = this.$element().find("." + TOOLBAR_AUTO_HIDE_ITEM_CLASS);
if (!overflowItems.length) {
return;
}
elementWidth = elementWidth || this.$element().width();
$(overflowItems).removeClass(TOOLBAR_HIDDEN_ITEM);
var beforeWidth = this._$beforeSection.outerWidth(),
centerWidth = this._$centerSection.outerWidth(),
afterWidth = this._$afterSection.outerWidth(),
itemsWidth = beforeWidth + centerWidth + afterWidth;
while (overflowItems.length && elementWidth < itemsWidth) {
var $item = overflowItems.eq(-1);
itemsWidth -= $item.outerWidth();
$item.addClass(TOOLBAR_HIDDEN_ITEM);
overflowItems.splice(-1, 1);
}
},
_getMenuItems: function _getMenuItems() {
var that = this;
var menuItems = grep(this.option("items") || [], function (item) {
return that._isMenuItem(item);
});
var $hiddenItems = this._itemContainer().children("." + TOOLBAR_AUTO_HIDE_ITEM_CLASS + "." + TOOLBAR_HIDDEN_ITEM).not(".dx-state-invisible");
this._restoreItems = this._restoreItems || [];
var overflowItems = iteratorUtils.map($hiddenItems, function (item) {
var itemData = that._getItemData(item),
$itemContainer = $(item).children(),
$itemMarkup = $itemContainer.children();
return extend({
menuItemTemplate: function menuItemTemplate() {
that._restoreItems.push({
container: $itemContainer,
item: $itemMarkup
});
var $container = $("<div>").addClass(TOOLBAR_AUTO_HIDE_ITEM_CLASS);
return $container.append($itemMarkup);
}
}, itemData);
});
return arrayUtils.merge(overflowItems, menuItems);
},
_getToolbarItems: function _getToolbarItems() {
var that = this;
return grep(this.option("items") || [], function (item) {
return !that._isMenuItem(item);
});
},
_renderMenu: function _renderMenu() {
this._renderMenuStrategy();
this._menuStrategy.render();
},
_renderMenuStrategy: function _renderMenuStrategy() {
var strategyName = this.option("submenuType");
if (this._requireDropDownStrategy()) {
strategyName = "dropDownMenu";
}
var strategy = STRATEGIES[strategyName];
if (!(this._menuStrategy && this._menuStrategy.NAME === strategyName)) {
this._menuStrategy = new strategy(this);
}
},
_requireDropDownStrategy: function _requireDropDownStrategy() {
var strategyName = this.option("submenuType");
if ((strategyName === "listBottom" || strategyName === "listTop") && this.option("renderAs") === "topToolbar") {
return true;
}
var items = this.option("items") || [],
result = false;
iteratorUtils.each(items, function (index, item) {
if (item.locateInMenu === "auto") {
result = true;
} else if (item.locateInMenu === "always" && item.widget) {
result = true;
}
});
return result;
},
_arrangeItems: function _arrangeItems() {
if (this.$element().is(":hidden")) {
return;
}
this._$centerSection.css({
margin: "0 auto",
float: "none"
});
iteratorUtils.each(this._restoreItems || [], function (_, obj) {
$(obj.container).append(obj.item);
});
this._restoreItems = [];
var elementWidth = this.$element().width();
this._hideOverflowItems(elementWidth);
this.callBase(elementWidth);
},
_itemOptionChanged: function _itemOptionChanged(item, property, value) {
if (this._isMenuItem(item)) {
this._menuStrategy.renderMenuItems();
} else if (this._isToolbarItem(item)) {
this.callBase(item, property, value);
} else {
this.callBase(item, property, value);
this._menuStrategy.renderMenuItems();
}
},
_isMenuItem: function _isMenuItem(itemData) {
return itemData.location === "menu" || itemData.locateInMenu === "always";
},
_isToolbarItem: function _isToolbarItem(itemData) {
return itemData.location === undefined || itemData.locateInMenu === "never";
},
_optionChanged: function _optionChanged(args) {
var name = args.name;
var value = args.value;
switch (name) {
case "submenuType":
this._invalidate();
break;
case "visible":
this.callBase.apply(this, arguments);
this._menuStrategy.handleToolbarVisibilityChange(value);
break;
case "menuItemTemplate":
this._changeMenuOption("itemTemplate", this._getTemplate(value));
break;
case "onItemClick":
this._changeMenuOption(name, value);
this.callBase.apply(this, arguments);
break;
default:
this.callBase.apply(this, arguments);
}
},
_changeMenuOption: function _changeMenuOption(name, value) {
this._menuStrategy.widgetOption(name, value);
}
/**
* @name dxToolbarMethods.registerKeyHandler
* @publicName registerKeyHandler(key, handler)
* @hidden
* @inheritdoc
*/
/**
* @name dxToolbarMethods.focus
* @publicName focus()
* @hidden
* @inheritdoc
*/
});
registerComponent("dxToolbar", Toolbar);
module.exports = Toolbar;