UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

376 lines (319 loc) 10.2 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2011-2013 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Christopher Zuendorf (czuendorf) ************************************************************************ */ /** * This widget displays a menu. A dialog menu extends a popup and contains a * list, which provides the user the possibility to select one value. * The selected value is identified through selected index. * * * *Example* * <pre class='javascript'> * * var model = new qx.data.Array(["item1","item2","item3"]); * * var menu = new qx.ui.mobile.dialog.Menu(model); * menu.show(); * menu.addListener("changeSelection", function(evt){ * var selectedIndex = evt.getData().index; * var selectedItem = evt.getData().item; * }, this); * </pre> * * This example creates a menu with several choosable items. */ qx.Class.define("qx.ui.mobile.dialog.Menu", { extend: qx.ui.mobile.dialog.Popup, /** * @param itemsModel {qx.data.Array ?}, the model which contains the choosable items of the menu. * @param anchor {qx.ui.mobile.core.Widget ?} The anchor widget for this item. If no anchor is available, the menu will be displayed modal and centered on screen. */ construct(itemsModel, anchor) { // Create the list with a delegate that // configures the list item. this.__selectionList = this._createSelectionList(); if (itemsModel) { this.__selectionList.setModel(itemsModel); } this.__menuContainer = new qx.ui.mobile.container.Composite(); this.__clearButton = this._createClearButton(); this.__listScroller = this._createListScroller(this.__selectionList); this.__menuContainer.add(this.__listScroller); this.__menuContainer.add(this.__clearButton); super(this.__menuContainer, anchor); if (anchor) { this.setModal(false); } else { this.setModal(true); } }, /* ***************************************************************************** EVENTS ***************************************************************************** */ events: { /** * Fired when the selection is changed. */ changeSelection: "qx.event.type.Data" }, /* ***************************************************************************** PROPERTIES ***************************************************************************** */ properties: { // overridden defaultCssClass: { refine: true, init: "menu" }, /** * Class which is assigned to selected items. * Useful for re-styling your menu via LESS. */ selectedItemClass: { init: "item-selected" }, /** * Class which is assigned to unselected items. * Useful for re-styling your menu via LESS. */ unselectedItemClass: { init: "item-unselected" }, /** * Defines if the menu has a null value in the list, which can be chosen * by the user. The label */ nullable: { init: false, check: "Boolean", apply: "_applyNullable" }, /** * The label of the null value entry of the list. Only relevant * when nullable property is set to <code>true</code>. */ clearButtonLabel: { init: "None", check: "String", apply: "_applyClearButtonLabel" }, /** * The selected index of this menu. */ selectedIndex: { check: "Integer", apply: "_applySelectedIndex", nullable: true }, /** * This value defines how much list items are visible inside the menu. */ visibleListItems: { check: "Integer", apply: "_updatePosition", nullable: true } }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members: { __selectionList: null, __clearButton: null, __listScroller: null, __menuContainer: null, // overridden show() { super.show(); this.scrollToItem(this.getSelectedIndex()); }, /** * Creates the clearButton. Override this to customize the widget. * * @return {qx.ui.mobile.form.Button} the clearButton of this menu. */ _createClearButton() { var clearButton = new qx.ui.mobile.form.Button( this.getClearButtonLabel() ); clearButton.addListener("tap", this.__onClearButtonTap, this); clearButton.exclude(); return clearButton; }, /** * Creates the scroll container for the selectionList. Override this to customize the widget. * @param selectionList {qx.ui.mobile.list.List} The selectionList of this menu. * @return {qx.ui.mobile.container.Scroll} the scroll container which contains the selectionList of this menu. */ _createListScroller(selectionList) { var listScroller = new qx.ui.mobile.container.Scroll({ snap: ".list-item" }); listScroller.add(selectionList, { flex: 1 }); listScroller.addCssClass("menu-scroller"); return listScroller; }, /** * Getter for the scroll container which contains a @see {qx.ui.mobile.list.List} with the choosable items. * @return {qx.ui.mobile.container.Scroll} the scroll container which contains the selectionList of this menu. */ _getListScroller() { return this.__listScroller; }, // overridden _updatePosition() { var parentHeight = qx.ui.mobile.dialog.Popup.ROOT.getHeight(); var listScrollerHeight = parseInt(parentHeight, 10) * 0.75; listScrollerHeight = parseInt(listScrollerHeight, 10); if (this.getVisibleListItems() !== null) { var newListScrollerHeight = this.__selectionList.getListItemHeight() * this.getVisibleListItems(); listScrollerHeight = Math.min( newListScrollerHeight, listScrollerHeight ); } qx.bom.element.Style.set( this.__listScroller.getContainerElement(), "maxHeight", listScrollerHeight + "px" ); super._updatePosition(); }, /** * Creates the selection list. Override this to customize the widget. * * @return {qx.ui.mobile.list.List} The selectionList of this menu. */ _createSelectionList() { var self = this; var selectionList = new qx.ui.mobile.list.List({ configureItem(item, data, row) { item.setTitle(data); item.setShowArrow(false); var isItemSelected = self.getSelectedIndex() == row; if (isItemSelected) { item.removeCssClass(self.getUnselectedItemClass()); item.addCssClass(self.getSelectedItemClass()); } else { item.removeCssClass(self.getSelectedItemClass()); item.addCssClass(self.getUnselectedItemClass()); } } }); // Add an changeSelection event selectionList.addListener( "changeSelection", this.__onListChangeSelection, this ); selectionList.addListener("tap", this._onSelectionListTap, this); return selectionList; }, /** * Getter for the selectionList of the menu. * @return {qx.ui.mobile.list.List} The selectionList of this menu. */ getSelectionList() { return this.__selectionList; }, /** Handler for tap event on selection list. */ _onSelectionListTap() { this.hideWithDelay(500); }, /** * Sets the choosable items of the menu. * @param itemsModel {qx.data.Array}, the model of choosable items in the menu. */ setItems(itemsModel) { if (this.__selectionList) { this.__selectionList.setModel(null); this.__selectionList.setModel(itemsModel); } }, /** * Fires an event which contains index and data. * @param evt {qx.event.type.Data}, contains the selected index number. */ __onListChangeSelection(evt) { this.setSelectedIndex(evt.getData()); }, /** * Event handler for tap on clear button. */ __onClearButtonTap() { this.fireDataEvent("changeSelection", { index: null, item: null }); this.hide(); }, // property apply _applySelectedIndex(value, old) { var listModel = this.__selectionList.getModel(); if (listModel !== null) { var selectedItem = listModel.getItem(value); this.fireDataEvent("changeSelection", { index: value, item: selectedItem }); } this._render(); }, // property apply _applyNullable(value, old) { if (value) { this.__clearButton.setVisibility("visible"); } else { this.__clearButton.setVisibility("excluded"); } }, // property apply _applyClearButtonLabel(value, old) { this.__clearButton.setValue(value); }, /** * Triggers (re-)rendering of menu items. */ _render() { var tmpModel = this.__selectionList.getModel(); this.__selectionList.setModel(null); this.__selectionList.setModel(tmpModel); }, /** * Scrolls the scroll wrapper of the selectionList to the item with given index. * @param index {Integer}, the index of the listItem to which the listScroller should scroll to. */ scrollToItem(index) { if (index !== null && this.__selectionList.getModel() != null) { var listItems = qxWeb( "#" + this.__listScroller.getId() + " .list-item" ); var targetListItemElement = listItems[index]; this.__listScroller.scrollToElement(targetListItemElement); } } }, destruct() { this.__selectionList.removeListener("tap", this._onSelectionListTap, this); this._disposeObjects( "__selectionList", "__clearButton", "__listScroller", "__menuContainer" ); } });