devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
478 lines (407 loc) • 14.7 kB
JavaScript
"use strict";
var $ = require("../core/renderer"),
getPublicElement = require("../core/utils/dom").getPublicElement,
noop = require("../core/utils/common").noop,
isDefined = require("../core/utils/type").isDefined,
registerComponent = require("../core/component_registrator"),
extend = require("../core/utils/extend").extend,
map = require("../core/utils/iterator").map,
PlainEditStrategy = require("./collection/ui.collection_widget.edit.strategy.plain"),
SlideOutView = require("./slide_out_view"),
CollectionWidget = require("./collection/ui.collection_widget.edit"),
List = require("./list"),
ChildDefaultTemplate = require("./widget/child_default_template"),
EmptyTemplate = require("./widget/empty_template");
var SLIDEOUT_CLASS = "dx-slideout",
SLIDEOUT_ITEM_CONTAINER_CLASS = "dx-slideout-item-container",
SLIDEOUT_MENU = "dx-slideout-menu",
SLIDEOUT_ITEM_CLASS = "dx-slideout-item",
SLIDEOUT_ITEM_DATA_KEY = "dxSlideoutItemData";
/**
* @name dxSlideout
* @publicName dxSlideOut
* @inherits CollectionWidget
* @module ui/slide_out
* @export default
*/
var SlideOut = CollectionWidget.inherit({
_getDefaultOptions: function _getDefaultOptions() {
/**
* @name dxSlideOutItemTemplate
* @publicName dxSlideOutItemTemplate
* @inherits CollectionWidgetItemTemplate
* @type object
*/
/**
* @name dxSlideOutItemTemplate.menutemplate
* @publicName menuTemplate
* @type template|function
* @type_function_return string|Node|jQuery
*/
return extend(this.callBase(), {
/**
* @name dxSlideOutOptions.activeStateEnabled
* @publicName activeStateEnabled
* @type boolean
* @default false
*/
activeStateEnabled: false,
/**
* @name dxSlideOutOptions.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 dxSlideOutOptions.swipeEnabled
* @publicName swipeEnabled
* @type boolean
* @default true
*/
swipeEnabled: true,
/**
* @name dxSlideOutOptions.menuVisible
* @publicName menuVisible
* @type boolean
* @default false
*/
menuVisible: false,
/**
* @name dxSlideOutOptions.menuPosition
* @publicName menuPosition
* @type Enums.SlideOutMenuPosition
* @default "normal"
*/
menuPosition: "normal",
/**
* @name dxSlideOutOptions.menuGrouped
* @publicName menuGrouped
* @type boolean
* @default false
*/
menuGrouped: false,
/**
* @name dxSlideOutOptions.menuGroupTemplate
* @publicName menuGroupTemplate
* @type template|function
* @default "menuGroup"
* @type_function_param1 groupData:object
* @type_function_param2 groupIndex:number
* @type_function_param3 groupElement:object
* @type_function_return string|Node|jQuery
*/
menuGroupTemplate: "menuGroup",
/**
* @name dxSlideOutOptions.onMenuItemRendered
* @publicName onMenuItemRendered
* @extends Action
* @action
*/
onMenuItemRendered: null,
/**
* @name dxSlideOutOptions.onMenuGroupRendered
* @publicName onMenuGroupRendered
* @extends Action
* @action
*/
onMenuGroupRendered: null,
/**
* @name dxSlideOutOptions.contentTemplate
* @publicName contentTemplate
* @type template|function
* @default "content"
* @type_function_param1 container:dxElement
* @type_function_return string|Node|jQuery
*/
contentTemplate: "content",
selectionMode: "single",
/**
* @name dxSlideOutOptions.selectedIndex
* @publicName selectedIndex
* @type number
* @default 0
*/
selectedIndex: 0,
selectionRequired: true
/**
* @name dxSlideOutOptions.selectedItems
* @publicName selectedItems
* @hidden
* @inheritdoc
*/
/**
* @name dxSlideOutOptions.selectedItemKeys
* @publicName selectedItemKeys
* @hidden
* @inheritdoc
*/
/**
* @name dxSlideOutOptions.keyExpr
* @publicName keyExpr
* @hidden
* @inheritdoc
*/
/**
* @name dxSlideOutOptions.focusStateEnabled
* @publicName focusStateEnabled
* @hidden
* @inheritdoc
*/
/**
* @name dxSlideOutOptions.accessKey
* @publicName accessKey
* @hidden
* @inheritdoc
*/
/**
* @name dxSlideOutOptions.tabIndex
* @publicName tabIndex
* @hidden
* @inheritdoc
*/
});
},
_itemClass: function _itemClass() {
return SLIDEOUT_ITEM_CLASS;
},
_itemDataKey: function _itemDataKey() {
return SLIDEOUT_ITEM_DATA_KEY;
},
_itemContainer: function _itemContainer() {
return $(this._slideOutView.content());
},
_init: function _init() {
this._selectedItemContentRendered = false;
this.callBase();
this.$element().addClass(SLIDEOUT_CLASS);
this._initSlideOutView();
},
_initTemplates: function _initTemplates() {
this.callBase();
this._defaultTemplates["menuItem"] = new ChildDefaultTemplate("item", this);
this._defaultTemplates["menuGroup"] = new ChildDefaultTemplate("group", this);
this._defaultTemplates["content"] = new EmptyTemplate(this);
},
_initEditStrategy: function _initEditStrategy() {
if (this.option("menuGrouped")) {
var strategy = PlainEditStrategy.inherit({
_getPlainItems: function _getPlainItems() {
return map(this.callBase(), function (group) {
return group.items;
});
}
});
this._editStrategy = new strategy(this);
} else {
this.callBase();
}
},
_initSlideOutView: function _initSlideOutView() {
this._slideOutView = this._createComponent(this.$element(), SlideOutView, {
integrationOptions: {},
menuVisible: this.option("menuVisible"),
swipeEnabled: this.option("swipeEnabled"),
menuPosition: this.option("menuPosition"),
onOptionChanged: this._slideOutViewOptionChanged.bind(this)
});
this._itemContainer().addClass(SLIDEOUT_ITEM_CONTAINER_CLASS);
},
_slideOutViewOptionChanged: function _slideOutViewOptionChanged(args) {
if (args.name === "menuVisible") {
this.option(args.name, args.value);
}
},
_initMarkup: function _initMarkup() {
this._renderList();
this._renderContentTemplate();
this.callBase();
},
_render: function _render() {
// TODO: remove this, needed for memory leak tests
this._slideOutView._renderShield();
this.callBase();
},
_renderList: function _renderList() {
var $list = this._list && this._list.$element() || $("<div>").addClass(SLIDEOUT_MENU).appendTo($(this._slideOutView.menuContent()));
this._renderItemClickAction();
this._list = this._createComponent($list, List, {
itemTemplateProperty: "menuTemplate",
selectionMode: this.option("selectionMode"),
selectedIndex: this.option("selectedIndex"),
selectionRequired: this.option("selectionRequired"),
indicateLoading: false,
onItemClick: this._listItemClickHandler.bind(this),
items: this.option("items"),
dataSource: this.option("dataSource"),
itemTemplate: this._getTemplateByOption("menuItemTemplate"),
grouped: this.option("menuGrouped"),
groupTemplate: this._getTemplateByOption("menuGroupTemplate"),
onItemRendered: this.option("onMenuItemRendered"),
onGroupRendered: this.option("onMenuGroupRendered"),
onContentReady: this._updateSlideOutView.bind(this)
});
},
_updateSlideOutView: function _updateSlideOutView() {
this._slideOutView._dimensionChanged();
},
_renderItemClickAction: function _renderItemClickAction() {
this._itemClickAction = this._createActionByOption("onItemClick");
},
_listItemClickHandler: function _listItemClickHandler(e) {
var selectedIndex = this._list.$element().find(".dx-list-item").index(e.itemElement);
this.option("selectedIndex", selectedIndex);
this._itemClickAction(e);
},
_renderContentTemplate: function _renderContentTemplate() {
if (isDefined(this._singleContent)) {
return;
}
var itemsLength = this._itemContainer().html().length;
this._getTemplateByOption("contentTemplate").render({
container: getPublicElement(this._itemContainer())
});
this._singleContent = this._itemContainer().html().length !== itemsLength;
},
_itemClickHandler: noop,
_renderContentImpl: function _renderContentImpl() {
if (this._singleContent) {
return;
}
var items = this.option("items"),
selectedIndex = this.option("selectedIndex");
if (items.length && selectedIndex > -1) {
this._selectedItemContentRendered = true;
var selectedItem = this._list.getItemByIndex(selectedIndex);
this._renderItems([selectedItem]);
}
},
_renderItem: function _renderItem(index, item) {
this._itemContainer().find("." + SLIDEOUT_ITEM_CLASS).remove();
this.callBase(index, item);
},
_selectedItemElement: function _selectedItemElement() {
return this._itemElements().eq(0);
},
_renderSelection: function _renderSelection() {
this._prepareContent();
this._renderContent();
},
_getListWidth: function _getListWidth() {
return this._slideOutView._getMenuWidth();
},
_changeMenuOption: function _changeMenuOption(name, value) {
this._list.option(name, value);
this._updateSlideOutView();
},
_cleanItemContainer: function _cleanItemContainer() {
if (this._singleContent) {
return;
}
this.callBase();
},
beginUpdate: function beginUpdate() {
this.callBase();
this._list && this._list.beginUpdate();
},
endUpdate: function endUpdate() {
this._list && this._list.endUpdate();
this.callBase();
},
_optionChanged: function _optionChanged(args) {
var name = args.name;
var value = args.value;
switch (name) {
case "menuVisible":
case "swipeEnabled":
case "rtlEnabled":
case "menuPosition":
this._slideOutView.option(name, value);
break;
case "width":
this.callBase(args);
this._updateSlideOutView();
break;
case "menuItemTemplate":
this._changeMenuOption("itemTemplate", this._getTemplate(value));
break;
case "items":
this._changeMenuOption("items", this.option("items"));
if (!this._selectedItemContentRendered) {
this._renderSelection();
}
break;
case "dataSource":
case "selectedIndex":
case "selectedItem":
this._changeMenuOption(name, value);
this.callBase(args);
break;
case "menuGrouped":
this._initEditStrategy();
this._changeMenuOption("grouped", value);
break;
case "menuGroupTemplate":
this._changeMenuOption("groupTemplate", this._getTemplate(value));
break;
case "onMenuItemRendered":
this._changeMenuOption("onItemRendered", value);
break;
case "onMenuGroupRendered":
this._changeMenuOption("onGroupRendered", value);
break;
case "onItemClick":
this._renderItemClickAction();
break;
case "contentTemplate":
this._singleContent = null;
this._invalidate();
break;
default:
this.callBase(args);
}
},
/**
* @name dxslideoutmethods.show
* @publicName showMenu()
* @return Promise<void>
*/
showMenu: function showMenu() {
return this._slideOutView.toggleMenuVisibility(true);
},
/**
* @name dxslideoutmethods.hide
* @publicName hideMenu()
* @return Promise<void>
*/
hideMenu: function hideMenu() {
return this._slideOutView.toggleMenuVisibility(false);
},
/**
* @name dxslideoutmethods.toggleMenuVisibility
* @publicName toggleMenuVisibility(showing)
* @param1 showing:boolean
* @return Promise<void>
*/
toggleMenuVisibility: function toggleMenuVisibility(showing) {
return this._slideOutView.toggleMenuVisibility(showing);
}
/**
* @name dxslideoutmethods.registerKeyHandler
* @publicName registerKeyHandler(key, handler)
* @hidden
* @inheritdoc
*/
/**
* @name dxslideoutmethods.focus
* @publicName focus()
* @hidden
* @inheritdoc
*/
});
registerComponent("dxSlideOut", SlideOut);
module.exports = SlideOut;