All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.acacia.client.widgets.CmsAttributeSelectWidget Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

The newest version!
/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.acacia.client.widgets;

import org.opencms.acacia.client.css.I_CmsWidgetsLayoutBundle;
import org.opencms.gwt.client.ui.input.CmsSelectBox;
import org.opencms.gwt.shared.attributeselect.I_CmsAttributeSelectData;
import org.opencms.gwt.shared.attributeselect.I_CmsAttributeSelectData.AttributeDefinition;
import org.opencms.gwt.shared.attributeselect.I_CmsAttributeSelectData.Option;
import org.opencms.gwt.shared.attributeselect.I_CmsAttributeSelectData.OptionWithAttributes;
import org.opencms.util.CmsStringUtil;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

import com.google.common.collect.HashMultimap;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;

/**
 * An attribute select widget acts as a select widget and consists of several attribute filter select boxes and one main select box, such
 * that choosing values from the attribute filters restricts the available options in the main select box to those which
 * have a matching value for every filter attribute.
 *
 * 

All data related to the options and filter attributes must be passed into the constructor, this widget does not use any RPC calls. */ public class CmsAttributeSelectWidget extends Composite implements I_CmsEditWidget { /** * Class representing a pair of an attribute name and value, for use as a key in the option index. */ class IndexKey { /** The attribute name. */ private String m_name; /** The attribute value. */ private String m_value; /** * Creates a new instance. * * @param name the attribute name * @param value the attribute value */ public IndexKey(String name, String value) { m_name = name; m_value = value; } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object o) { if (!(o instanceof IndexKey)) { return false; } IndexKey other = (IndexKey)o; return other.m_name.equals(m_name) && other.m_value.equals(m_value); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return (31 * m_name.hashCode()) + m_value.hashCode(); } } /** The panel containing everything else. */ protected FlowPanel m_root = new FlowPanel(); /** Tracks if the widget is active. */ private boolean m_active = true; /** Map of attribute definitions by name. */ private Map m_attributeDefinitions = new HashMap<>(); /** Map of attribute select boxes by attribute name. */ private Map m_attributeSelects = new HashMap<>(); /** Value set from the outside. */ private String m_externalValue; /** The main select box for actually choosing the widget value. */ private CmsSelectBox m_mainSelect; /** An index for quickly locating all options with a given attribute value. */ private HashMultimap m_optionIndex = HashMultimap.create(); /** Map of all options. */ private LinkedHashMap m_options = new LinkedHashMap<>(); /** * Creates a new instance. * * @param data the widget data */ public CmsAttributeSelectWidget(I_CmsAttributeSelectData data) { initWidget(m_root); for (AttributeDefinition attrDef : data.getAttributeDefinitions()) { m_attributeDefinitions.put(attrDef.getName(), attrDef); CmsSelectBox selectBox = new CmsSelectBox(); LinkedHashMap selectBoxOptions = new LinkedHashMap<>(); for (Option option : attrDef.getOptions()) { selectBoxOptions.put(option.getValue(), option.getLabel()); if (option.getHelpText() != null) { selectBox.setTitle(option.getValue(), option.getHelpText()); } } selectBox.setItems(selectBoxOptions); // set the value before adding the change handler, since we already call handleFilterChange() below to initialize the main select box selectBox.setFormValueAsString(getDefaultOption(attrDef)); addFilterLine(attrDef.getLabel(), selectBox); m_attributeSelects.put(attrDef.getName(), selectBox); selectBox.addValueChangeHandler(event -> handleFilterChange()); } m_mainSelect = new CmsSelectBox(); m_root.add(m_mainSelect); LinkedHashMap mainOptions = new LinkedHashMap<>(); for (OptionWithAttributes option : data.getOptions()) { if (option.getHelpText() != null) { // we only need to set all the help texts once, they will be preserved during option changes m_mainSelect.setTitle(option.getValue(), option.getHelpText()); } m_options.put(option.getValue(), option); mainOptions.put(option.getValue(), option.getLabel()); for (String attribute : option.getAttributes().keySet()) { for (String attrValue : option.getAttributes().get(attribute)) { m_optionIndex.put(new IndexKey(attribute, attrValue), option.getValue()); } } } m_mainSelect.addValueChangeHandler(event -> fireChangeEvent()); handleFilterChange(); } /** * Adds the focus handler. * * @param handler the handler * @return the handler registration * @see com.google.gwt.event.dom.client.HasFocusHandlers#addFocusHandler(com.google.gwt.event.dom.client.FocusHandler) */ public HandlerRegistration addFocusHandler(FocusHandler handler) { return addDomHandler(handler, FocusEvent.getType()); } /** * Adds the value change handler. * * @param handler the handler * @return the handler registration * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) */ public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) { return addHandler(handler, ValueChangeEvent.getType()); } /** * Represents a value change event.

* */ public void fireChangeEvent() { String val = m_mainSelect.getFormValueAsString(); if (val != null) { ValueChangeEvent.fire(this, val); } } /** * @see com.google.gwt.user.client.ui.HasValue#getValue() */ public String getValue() { String value = m_mainSelect.getFormValueAsString(); return value; } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#isActive() */ public boolean isActive() { return m_active; } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#onAttachWidget() */ public void onAttachWidget() { super.onAttach(); } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#owns(com.google.gwt.dom.client.Element) */ public boolean owns(Element element) { return false; } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setActive(boolean) */ public void setActive(boolean active) { if (active == m_active) { // Trying to set one value while initializing the widget can result in a different value being set. // But at that time the event handler for the widget may not yet be set up correctly, so fireChangeEvent // does nothing. So we have to fire the event here in setActive (which is called during widget // initialization, after the change handler is set up). if (active && !Objects.equals(getValue(), m_externalValue)) { fireChangeEvent(); } return; } m_active = active; m_mainSelect.setEnabled(active); for (CmsSelectBox attrSelect : m_attributeSelects.values()) { attrSelect.setEnabled(active); } if (active) { fireChangeEvent(); } } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setName(java.lang.String) */ public void setName(String name) { // do nothing } /** * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object) */ public void setValue(String value) { setValue(value, false); } /** * @see org.opencms.acacia.client.widgets.I_CmsEditWidget#setValue(java.lang.String, boolean) */ public void setValue(String value, boolean fireEvent) { m_externalValue = value; OptionWithAttributes option = m_options.get(value); if (option != null) { for (String optionAttribute : option.getAttributes().keySet()) { m_attributeSelects.get(optionAttribute).setFormValue( option.getAttributes().get(optionAttribute).get(0), false); } handleFilterChange(); m_mainSelect.setFormValue(value, false); } else { for (AttributeDefinition attrDef : m_attributeDefinitions.values()) { CmsSelectBox select = m_attributeSelects.get(attrDef.getName()); // the editor initializes new widgets with the empty value, so we want to use the default option instead // the neutral option for the attribute in that case. String attrSelectValue = CmsStringUtil.isEmpty(value) ? getDefaultOption(attrDef) : getNeutralOption(attrDef); select.setFormValue(attrSelectValue, false); } handleFilterChange(); m_mainSelect.setFormValue(value, false); } if (fireEvent) { fireChangeEvent(); } } /** * Gets the currently selected attribute filters. * * @return a map with attribute names as its keys and attribute values as its values */ protected Map getFilterAttributes() { Map result = new HashMap<>(); for (Map.Entry entry : m_attributeSelects.entrySet()) { String filterValue = entry.getValue().getFormValueAsString(); result.put(entry.getKey(), filterValue); } return result; } /** * Changes the set of available options in the main select box to those which match the currently * selected attribute filters. */ protected void handleFilterChange() { Map attributes = getFilterAttributes(); Map newMainOptions = new LinkedHashMap<>(); // first generate a map of all options, then reduce the keys for each chosen filter using the option index for (Map.Entry option : m_options.entrySet()) { newMainOptions.put(option.getKey(), option.getValue().getLabel()); } for (Map.Entry filterEntry : attributes.entrySet()) { newMainOptions.keySet().retainAll( m_optionIndex.get(new IndexKey(filterEntry.getKey(), filterEntry.getValue()))); } m_mainSelect.setItems(newMainOptions); fireChangeEvent(); } /** * Adds a new line with an attribute filter select box and a label. * * @param label the label * @param selectBox the select box */ private void addFilterLine(String label, CmsSelectBox selectBox) { FlowPanel filterLine = new FlowPanel(); filterLine.add(new Label(label)); filterLine.add(selectBox); filterLine.addStyleName(I_CmsWidgetsLayoutBundle.INSTANCE.widgetCss().attributeFilterLine()); m_root.add(filterLine); } /** * Gets the default option for an attribute. * @param attrDef the attribute * @return the default option */ private String getDefaultOption(AttributeDefinition attrDef) { if (attrDef.getDefaultOption() != null) { return attrDef.getDefaultOption(); } return attrDef.getOptions().get(0).getValue(); } /** * Gets the filter attribute value to use if no other filter attribute value can be used. * * @param attrDef the attribute definition * * @return the neutral option */ private String getNeutralOption(AttributeDefinition attrDef) { if (attrDef.getNeutralOption() != null) { return attrDef.getNeutralOption(); } return attrDef.getOptions().get(0).getValue(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy