UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

287 lines (244 loc) 7.93 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2012 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: * Gabriel Munteanu (gabios) * Christopher Zuendorf (czuendorf) ************************************************************************ */ /** * Single renderer is a class used to render forms into a mobile page. * It displays a label above or next to each form element. * */ qx.Class.define("qx.ui.mobile.form.renderer.Single", { extend: qx.ui.mobile.form.renderer.AbstractRenderer, construct(form) { this.__errorMessageContainers = []; this._rows = []; this._labels = []; super(form); this.addCssClass("single"); }, statics: { /** @type {Array} qx.Mobile form widgets which are rendered in one single line. */ ONE_LINE_WIDGETS: [ qx.ui.mobile.form.ToggleButton, qx.ui.mobile.form.RadioButton, qx.ui.mobile.form.TextField, qx.ui.mobile.form.PasswordField, qx.ui.mobile.form.NumberField, qx.ui.mobile.form.CheckBox, qx.ui.mobile.form.SelectBox ] }, members: { _rows: null, _labels: null, _onFormChange() { this._disposeArray("_labels"); this._disposeArray("_rows"); this._rows = []; this._labels = []; super._onFormChange(); }, /** * A collection of error containers used to keep the error messages * resulted after form validation. * Also useful to clear them when the validation passes. */ __errorMessageContainers: null, // override _getTagName() { return "ul"; }, /** * Determines whether the given item can be display in one line * or whether a separate line for the text label is needed. * @param item {qx.ui.mobile.core.Widget} the widget which should be added. * @return {Boolean} it indicates whether the widget can be displayed * in same line as the label. */ _isOneLineWidget(item) { var widgets = qx.ui.mobile.form.renderer.Single.ONE_LINE_WIDGETS; for (var i = 0; i < widgets.length; i++) { var widget = widgets[i]; if (item instanceof widget) { return true; } } return false; }, // override addItems(items, names, title) { if (title !== null) { this._addGroupHeader(title); } this._addGroupHeaderRow(); for (var i = 0, l = items.length; i < l; i++) { var item = items[i]; var name = names[i]; var isLastItem = i == items.length - 1; if (item instanceof qx.ui.mobile.form.TextArea) { if (qx.core.Environment.get("qx.mobile.nativescroll") == false) { this._addToScrollContainer(item, name); } else { this._addRow(item, name, new qx.ui.mobile.layout.VBox()); } } else { if (this._isOneLineWidget(item)) { this._addRow(item, name, new qx.ui.mobile.layout.HBox()); } else { this._addRow(item, name, new qx.ui.mobile.layout.VBox()); } } if (!item.isValid()) { this.showErrorForItem(item); } if (!isLastItem) { this._addSeparationRow(); } } this._addGroupFooterRow(); }, /** * Wraps the given item with a {@link qx.ui.mobile.container.Scroll scroll} container. * @param item {qx.ui.mobile.core.Widget} A form item to render. * @param name {String} A name for the form item. */ _addToScrollContainer(item, name) { var scrollContainer = new qx.ui.mobile.container.Scroll(); scrollContainer.addCssClass("form-row-scroll"); scrollContainer.add(item, { flex: 1 }); this._addRow(scrollContainer, name, new qx.ui.mobile.layout.VBox()); }, /** * Adds a label and its according widget in a row and applies the given layout. * @param item {qx.ui.mobile.core.Widget} A form item to render. * @param name {String} A name for the form item. * @param layout {qx.ui.mobile.layout.Abstract} layout of the rendered row. */ _addRow(item, name, layout) { var row = new qx.ui.mobile.form.Row(layout); row.addCssClass("form-row-content"); if (name !== null) { var label = new qx.ui.mobile.form.Label(name); label.setLabelFor(item.getId()); row.add(label, { flex: 1 }); this._labels.push(label); } row.add(item); this._add(row); this._rows.push(row); }, /** * Adds a separation line into the form. */ _addSeparationRow() { var row = new qx.ui.mobile.form.Row(); row.addCssClass("form-separation-row"); this._add(row); this._rows.push(row); }, /** * Adds an row group header. */ _addGroupHeaderRow() { var row = new qx.ui.mobile.form.Row(); row.addCssClass("form-row-group-first"); this._add(row); this._rows.push(row); }, /** * Adds an row group footer. */ _addGroupFooterRow() { var row = new qx.ui.mobile.form.Row(); row.addCssClass("form-row-group-last"); this._add(row); this._rows.push(row); }, /** * Adds a row with the name of a group of elements * When you want to group certain form elements, this methods implements * the way the header of that group is presented. * @param title {String} the title shown in the group header */ _addGroupHeader(title) { var row = new qx.ui.mobile.form.Row(); row.addCssClass("form-row-group-title"); var titleLabel = new qx.ui.mobile.basic.Label(title); row.add(titleLabel); this._add(row); this._labels.push(titleLabel); this._rows.push(row); }, // override addButton(button) { var row = new qx.ui.mobile.form.Row(new qx.ui.mobile.layout.HBox()); row.add(button, { flex: 1 }); this._add(row); this._rows.push(row); }, // override showErrorForItem(item) { var errorNode = qx.dom.Element.create("div"); errorNode.innerHTML = item.getInvalidMessage(); qx.bom.element.Class.add(errorNode, "form-element-error"); qx.dom.Element.insertAfter( errorNode, this._getParentRow(item).getContainerElement() ); this.__errorMessageContainers.push(errorNode); }, /** * Shows a single item of this form * @param item {qx.ui.form.IForm} form item which should be hidden. */ showItem(item) { this._getParentRow(item).removeCssClass("exclude"); }, /** * Hides a single item of this form * @param item {qx.ui.form.IForm} form item which should be hidden. */ hideItem(item) { this._getParentRow(item).addCssClass("exclude"); }, /** * Returns the parent row of the item. * * @param item {qx.ui.form.IForm} the form item. * @return {qx.ui.mobile.core.Widget} the parent row. */ _getParentRow(item) { var parent = item.getLayoutParent(); while (!parent.hasCssClass("form-row")) { parent = parent.getLayoutParent(); } return parent; }, // override resetForm() { for (var i = 0; i < this.__errorMessageContainers.length; i++) { qx.dom.Element.remove(this.__errorMessageContainers[i]); } } }, /* ***************************************************************************** DESTRUCTOR ***************************************************************************** */ destruct() { this.resetForm(); this._disposeArray("_labels"); this._disposeArray("_rows"); } });