001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.widgets;
029
030import org.opencms.file.CmsObject;
031import org.opencms.util.CmsStringUtil;
032import org.opencms.workplace.CmsWorkplace;
033
034import java.util.Iterator;
035import java.util.List;
036import java.util.Map;
037
038/**
039 * Provides a widget for a standard HTML form multi select list or a group of check boxes.<p>
040 *
041 * Please see the documentation of <code>{@link org.opencms.widgets.CmsSelectWidgetOption}</code> for a description
042 * about the configuration String syntax for the select options.<p>
043 *
044 * The multi select widget does use the following select options:<ul>
045 * <li><code>{@link org.opencms.widgets.CmsSelectWidgetOption#getValue()}</code> for the value of the option
046 * <li><code>{@link org.opencms.widgets.CmsSelectWidgetOption#isDefault()}</code> for pre-selecting a specific value
047 * <li><code>{@link org.opencms.widgets.CmsSelectWidgetOption#getOption()}</code> for the display name of the option
048 * </ul>
049 * <p>
050 *
051 * @since 6.0.0
052 */
053public class CmsMultiSelectWidget extends A_CmsSelectWidget {
054
055    /** Configuration parameter to set the height from the select widget in pixel. */
056    public static final String CONFIGURATION_ASCHECKBOXES = "ascheckboxes";
057
058    /** Configuration parameter to indicate the multi-select needs to be activated by a check box. */
059    public static final String CONFIGURATION_REQUIRES_ACTIVATION = "requiresactivation";
060
061    /** Indicates if used html code is a multi selection list or a list of checkboxes. */
062    private boolean m_asCheckBoxes;
063
064    /** Flag to indicate if the multi-select needs to be activated by a check box. */
065    private boolean m_requiresActivation;
066
067    /**
068     * Creates a new select widget.<p>
069     */
070    public CmsMultiSelectWidget() {
071
072        // empty constructor is required for class registration
073        super();
074    }
075
076    /**
077     * Creates a select widget with the select options specified in the given configuration List.<p>
078     *
079     * The list elements must be of type <code>{@link CmsSelectWidgetOption}</code>.<p>
080     *
081     * @param configuration the configuration (possible options) for the select widget
082     *
083     * @see CmsSelectWidgetOption
084     */
085    public CmsMultiSelectWidget(List<CmsSelectWidgetOption> configuration) {
086
087        this(configuration, false);
088    }
089
090    /**
091     * Creates a select widget with the select options specified in the given configuration List.<p>
092     *
093     * The list elements must be of type <code>{@link CmsSelectWidgetOption}</code>.<p>
094     *
095     * @param configuration the configuration (possible options) for the select widget
096     * @param asCheckboxes indicates if used html code is a multi selection list or a list of checkboxes
097     *
098     * @see CmsSelectWidgetOption
099     */
100    public CmsMultiSelectWidget(List<CmsSelectWidgetOption> configuration, boolean asCheckboxes) {
101
102        super(configuration);
103        m_asCheckBoxes = asCheckboxes;
104    }
105
106    /**
107     * Creates a select widget with the specified select options.<p>
108     *
109     * @param configuration the configuration (possible options) for the select box
110     */
111    public CmsMultiSelectWidget(String configuration) {
112
113        super(configuration);
114    }
115
116    /**
117     * Sets the value of the widget parameter from the provided form parameters.<p>
118     *
119     * @param cms the cms context
120     * @param formParameters the form parameters
121     * @param widgetDialog the widget dialog
122     * @param param the widget parameter
123     */
124    public static void setMultiSelectEditorValue(
125        CmsObject cms,
126        Map<String, String[]> formParameters,
127        I_CmsWidgetDialog widgetDialog,
128        I_CmsWidgetParameter param) {
129
130        String[] values = formParameters.get(param.getId());
131        if ((values != null) && (values.length > 0)) {
132            StringBuffer value = new StringBuffer(128);
133            for (int i = 0; i < values.length; i++) {
134                if (i > 0) {
135                    value.append(',');
136                }
137                value.append(values[i]);
138            }
139            // set the value
140            param.setStringValue(cms, value.toString());
141        } else {
142            // erase:
143            param.setStringValue(cms, "");
144        }
145    }
146
147    /**
148     * @see org.opencms.widgets.I_CmsWidget#getDialogIncludes(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
149     */
150    @Override
151    public String getDialogIncludes(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
152
153        return getJSIncludeFile(CmsWorkplace.getSkinUri() + "components/widgets/multiselector.js");
154    }
155
156    /**
157     * @see org.opencms.widgets.I_CmsWidget#getDialogWidget(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
158     */
159    public String getDialogWidget(CmsObject cms, I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) {
160
161        String id = param.getId();
162        StringBuffer result = new StringBuffer(16);
163
164        List<CmsSelectWidgetOption> options = parseSelectOptions(cms, widgetDialog, param);
165        result.append("<td class=\"xmlTd\">");
166        // the configured select widget height start element
167        if (!m_asCheckBoxes) {
168            if (m_requiresActivation) {
169                result.append(
170                    "<input style=\"vertical-align:middle;\" type=\"checkbox\" id=\"check"
171                        + id
172                        + "\" name=\"check"
173                        + id
174                        + "\""
175                        + "onclick=toggleMultiSelectWidget(this);"
176                        + " />");
177                result.append("&nbsp;<label style=\"vertical-align:middle;\" for=\"check" + id + "\">");
178                result.append(widgetDialog.getMessages().key(Messages.GUI_MULTISELECT_ACTIVATE_0));
179                result.append("</label>&nbsp;");
180                // adding hidden input with the current value, because disabled select box value won't be submitted
181                result.append("<input type='hidden' name='").append(id).append("' id='").append(id).append("' value='");
182                List<String> values = getSelectedValues(cms, param);
183                if (values.size() > 0) {
184                    result.append(values.get(0));
185                    for (int i = 1; i < values.size(); i++) {
186                        result.append(",").append(values.get(i));
187                    }
188                }
189                result.append("' />");
190                id = "display" + id;
191            }
192            result.append("<select multiple size='");
193            result.append(options.size());
194            result.append("' style=\"vertical-align:middle;\" class=\"xmlInput");
195            if (param.hasError()) {
196                result.append(" xmlInputError");
197            }
198            result.append("\" ");
199            if (m_requiresActivation) {
200                result.append("disabled=\"true\" ");
201            }
202            result.append("name=\"");
203            result.append(id);
204            result.append("\" id=\"");
205            result.append(id);
206            result.append("\">");
207        }
208
209        // get select box options from default value String
210        List<String> selected = getSelectedValues(cms, param);
211        Iterator<CmsSelectWidgetOption> i = options.iterator();
212        while (i.hasNext()) {
213            CmsSelectWidgetOption option = i.next();
214            // create the option
215            if (!m_asCheckBoxes) {
216                result.append("<option value=\"");
217                result.append(option.getValue());
218                result.append("\"");
219                if (selected.contains(option.getValue())) {
220                    result.append(" selected=\"selected\"");
221                }
222                result.append(">");
223                result.append(option.getOption());
224                result.append("</option>");
225            } else {
226                result.append("<input type='checkbox' name='");
227                result.append(id);
228                result.append("' value='");
229                result.append(option.getValue());
230                result.append("'");
231                if (selected.contains(option.getValue())) {
232                    result.append(" checked");
233                }
234                result.append(">");
235                result.append(option.getOption());
236                result.append("<br>");
237            }
238        }
239        if (!m_asCheckBoxes) {
240            result.append("</select>");
241        }
242        result.append("</td>");
243        return result.toString();
244    }
245
246    /**
247     * @see org.opencms.widgets.I_CmsADEWidget#getWidgetName()
248     */
249    @Override
250    public String getWidgetName() {
251
252        return CmsMultiSelectWidget.class.getName();
253    }
254
255    /**
256     * @see org.opencms.widgets.I_CmsWidget#newInstance()
257     */
258    public I_CmsWidget newInstance() {
259
260        return new CmsMultiSelectWidget(getConfiguration());
261    }
262
263    /**
264     * @see org.opencms.widgets.A_CmsWidget#setConfiguration(java.lang.String)
265     */
266    @Override
267    public void setConfiguration(String configuration) {
268
269        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration)) {
270            int asCheckBoxesIndex = configuration.indexOf(CONFIGURATION_ASCHECKBOXES);
271            if (asCheckBoxesIndex != -1) {
272                // the height is set
273                String asCheckBoxes = configuration.substring(
274                    asCheckBoxesIndex + CONFIGURATION_ASCHECKBOXES.length() + 1);
275                if (asCheckBoxes.indexOf('|') != -1) {
276                    // cut eventual following configuration values
277                    asCheckBoxes = asCheckBoxes.substring(0, asCheckBoxes.indexOf('|'));
278                }
279                m_asCheckBoxes = Boolean.parseBoolean(asCheckBoxes);
280            }
281            int reqiresActivationIndex = configuration.indexOf(CONFIGURATION_REQUIRES_ACTIVATION);
282            if (reqiresActivationIndex != -1) {
283                // the height is set
284                String requiresActivation = configuration.substring(
285                    reqiresActivationIndex + CONFIGURATION_REQUIRES_ACTIVATION.length() + 1);
286                if (requiresActivation.indexOf('|') != -1) {
287                    // cut eventual following configuration values
288                    requiresActivation = requiresActivation.substring(0, requiresActivation.indexOf('|'));
289                }
290                m_requiresActivation = Boolean.parseBoolean(requiresActivation);
291            }
292        }
293        super.setConfiguration(configuration);
294    }
295
296    /**
297     * @see org.opencms.widgets.I_CmsWidget#setEditorValue(org.opencms.file.CmsObject, java.util.Map, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
298     */
299    @Override
300    public void setEditorValue(
301        CmsObject cms,
302        Map<String, String[]> formParameters,
303        I_CmsWidgetDialog widgetDialog,
304        I_CmsWidgetParameter param) {
305
306        setMultiSelectEditorValue(cms, formParameters, widgetDialog, param);
307    }
308}