UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

350 lines (280 loc) 8.46 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 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: * Martin Wittemann (martinwittemann) * Sebastian Werner (wpbasti) * Jonathan Weiß (jonathan_rass) ************************************************************************ */ /** * Basic class for a selectbox like lists. Basically supports a popup * with a list and the whole children management. * * @childControl list {qx.ui.form.List} list component of the selectbox * @childControl popup {qx.ui.popup.Popup} popup which shows the list * */ qx.Class.define("qx.ui.form.AbstractSelectBox", { extend : qx.ui.core.Widget, include : [ qx.ui.core.MRemoteChildrenHandling, qx.ui.form.MForm ], implement : [ qx.ui.form.IForm ], type : "abstract", /* ***************************************************************************** CONSTRUCTOR ***************************************************************************** */ construct : function() { this.base(arguments); // set the layout var layout = new qx.ui.layout.HBox(); this._setLayout(layout); layout.setAlignY("middle"); // Register listeners this.addListener("keypress", this._onKeyPress); this.addListener("blur", this._onBlur, this); // register the resize listener this.addListener("resize", this._onResize, this); }, /* ***************************************************************************** PROPERTIES ***************************************************************************** */ properties : { // overridden focusable : { refine : true, init : true }, // overridden width : { refine : true, init : 120 }, /** * The maximum height of the list popup. Setting this value to * <code>null</code> will set cause the list to be auto-sized. */ maxListHeight : { check : "Number", apply : "_applyMaxListHeight", nullable: true, init : 200 }, /** * Formatter which format the value from the selected <code>ListItem</code>. * Uses the default formatter {@link #_defaultFormat}. */ format : { check : "Function", init : function(item) { return this._defaultFormat(item); }, nullable : true } }, /* ***************************************************************************** MEMBERS ***************************************************************************** */ members : { // overridden _createChildControlImpl : function(id, hash) { var control; switch(id) { case "list": control = new qx.ui.form.List().set({ focusable: false, keepFocus: true, height: null, width: null, maxHeight: this.getMaxListHeight(), selectionMode: "one", quickSelection: true }); control.addListener("changeSelection", this._onListChangeSelection, this); control.addListener("pointerdown", this._onListPointerDown, this); control.getChildControl("pane").addListener("tap", this.close, this); break; case "popup": control = new qx.ui.popup.Popup(new qx.ui.layout.VBox()); control.setAutoHide(false); control.setKeepActive(true); control.add(this.getChildControl("list")); control.addListener("changeVisibility", this._onPopupChangeVisibility, this); break; } return control || this.base(arguments, id); }, /* --------------------------------------------------------------------------- APPLY ROUTINES --------------------------------------------------------------------------- */ // property apply _applyMaxListHeight : function(value, old) { this.getChildControl("list").setMaxHeight(value); }, /* --------------------------------------------------------------------------- PUBLIC METHODS --------------------------------------------------------------------------- */ /** * Returns the list widget. * @return {qx.ui.form.List} the list */ getChildrenContainer : function() { return this.getChildControl("list"); }, /* --------------------------------------------------------------------------- LIST STUFF --------------------------------------------------------------------------- */ /** * Shows the list popup. */ open : function() { var popup = this.getChildControl("popup"); popup.placeToWidget(this, true); popup.show(); }, /** * Hides the list popup. */ close : function() { this.getChildControl("popup").hide(); }, /** * Toggles the popup's visibility. */ toggle : function() { var isListOpen = this.getChildControl("popup").isVisible(); if (isListOpen) { this.close(); } else { this.open(); } }, /* --------------------------------------------------------------------------- FORMAT HANDLING --------------------------------------------------------------------------- */ /** * Return the formatted label text from the <code>ListItem</code>. * The formatter removes all HTML tags and converts all HTML entities * to string characters when the rich property is <code>true</code>. * * @param item {qx.ui.form.ListItem} The list item to format. * @return {String} The formatted text. */ _defaultFormat : function(item) { var valueLabel = item ? item.getLabel() : ""; var rich = item ? item.getRich() : false; if (rich) { valueLabel = valueLabel.replace(/<[^>]+?>/g, ""); valueLabel = qx.bom.String.unescape(valueLabel); } return valueLabel; }, /* --------------------------------------------------------------------------- EVENT LISTENERS --------------------------------------------------------------------------- */ /** * Handler for the blur event of the current widget. * * @param e {qx.event.type.Focus} The blur event. */ _onBlur : function(e) { this.close(); }, /** * Reacts on special keys and forwards other key events to the list widget. * * @param e {qx.event.type.KeySequence} Keypress event */ _onKeyPress : function(e) { // get the key identifier var identifier = e.getKeyIdentifier(); var listPopup = this.getChildControl("popup"); // disabled pageUp and pageDown keys if (listPopup.isHidden() && (identifier == "PageDown" || identifier == "PageUp")) { e.stopPropagation(); } // hide the list always on escape else if (!listPopup.isHidden() && identifier == "Escape") { this.close(); e.stop(); } // forward the rest of the events to the list else { this.getChildControl("list").handleKeyPress(e); } }, /** * Updates list minimum size. * * @param e {qx.event.type.Data} Data event */ _onResize : function(e){ this.getChildControl("popup").setMinWidth(e.getData().width); }, /** * Syncs the own property from the list change * * @param e {qx.event.type.Data} Data Event */ _onListChangeSelection : function(e) { throw new Error("Abstract method: _onListChangeSelection()"); }, /** * Redirects pointerdown event from the list to this widget. * * @param e {qx.event.type.Pointer} Pointer Event */ _onListPointerDown : function(e) { throw new Error("Abstract method: _onListPointerDown()"); }, /** * Redirects changeVisibility event from the list to this widget. * * @param e {qx.event.type.Data} Property change event */ _onPopupChangeVisibility : function(e) { e.getData() == "visible" ? this.addState("popupOpen") : this.removeState("popupOpen"); } } });