View Javadoc

1   /**
2    * This file Copyright (c) 2003-2011 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.cms.gui.dialog;
35  
36  import info.magnolia.cms.gui.control.Button;
37  import info.magnolia.cms.gui.control.ControlImpl;
38  import info.magnolia.freemarker.FreemarkerUtil;
39  import org.apache.commons.lang.BooleanUtils;
40  import org.apache.commons.lang.StringEscapeUtils;
41  import org.apache.commons.lang.StringUtils;
42  
43  import java.io.IOException;
44  import java.io.Writer;
45  import java.util.ArrayList;
46  import java.util.Arrays;
47  import java.util.HashMap;
48  import java.util.Iterator;
49  import java.util.List;
50  import java.util.Map;
51  
52  
53  /**
54   * Control to select multiple values. The values can get stored as list, in JSON format or as a multiple values
55   * @author Philipp Bracher
56   * @version $Revision: 47715 $ ($Author: dlipp $)
57   */
58  public class DialogMultiSelect extends DialogBox {
59  
60      /**
61       * The values are saved a properties
62       */
63      public static final String SAVE_MODE_MULTIPLE = "multiple";
64  
65      /**
66       * The values are saved as a single json string
67       */
68      public static final String SAVE_MODE_JSON = "json";
69  
70      /**
71       * The values are saved as semicolon separated list
72       */
73      public static final String SAVE_MODE_LIST = "list";
74  
75      /**
76       * Set the save mode
77       */
78      public static final String CONFIG_SAVE_MODE = "saveMode";
79  
80      /**
81       * Set the onclick js code of the coose button. If non is set the button is not rendered.
82       */
83      private static final String CONFIG_CHOOSE_ONCLICK = "chooseOnclick";
84  
85      /**
86       * If you like to select the data from a tree, just define the config value tree instead of chooseOnclick
87       */
88      private static final String CONFIG_TREE = "tree";
89  
90      /**
91       * Render the Html using a template
92       */
93      public void drawHtml(Writer out) throws IOException {
94          this.drawHtmlPre(out);
95          // this could be replaced by
96          //   out.write(FreemarkerUtil.process(this));
97          // except this could cause problems with subclasses
98          out.write(FreemarkerUtil.process(DialogMultiSelect.class, this));
99          this.drawHtmlPost(out);
100     }
101 
102     /**
103      * The button to add a new row
104      */
105     public String getAddButton() {
106         Button add = new Button();
107         add.setLabel(getMessage("buttons.add"));
108         add.setOnclick(this.getName() + "DynamicTable.addNew();");
109         add.setSmall(true);
110         return add.getHtml();
111     }
112 
113     /**
114      * If this control has a choose button
115      */
116     public String getChooseButton() {
117 
118         String chooseOnclick = this.getConfigValue(CONFIG_CHOOSE_ONCLICK);
119         if(StringUtils.isEmpty(chooseOnclick)){
120             String tree = this.getConfigValue(CONFIG_TREE);
121             if(StringUtils.isNotEmpty(tree)){
122                 chooseOnclick = "mgnlOpenTreeBrowserWithControl($('${prefix}'), '" + tree + "');";
123 
124             }
125         }
126 
127         if (StringUtils.isNotEmpty(chooseOnclick)) {
128             Button choose = new Button();
129             choose.setLabel(this.getMessage("buttons.choose"));
130             choose.setOnclick(chooseOnclick);
131 
132             choose.setSmall(true);
133             return choose.getHtml();
134         }
135         return "";
136     }
137 
138     /**
139      * Button for deleting a row
140      */
141     public String getDeleteButton() {
142         Button delete = new Button();
143         delete.setLabel(this.getMessage("buttons.delete"));
144         delete
145             .setOnclick(this.getName() + "DynamicTable.del('${index}');" + this.getName() + "DynamicTable.persist();");
146         delete.setSmall(true);
147         return delete.getHtml();
148     }
149 
150     /**
151      * Called by the template. It renders the dynamic inner row using trimpaths templating mechanism.
152      */
153     public String getInnerHtml() {
154         // TODO - this could potentially be replaced by
155         //   return FreemarkerUtil.process(this, "Inner", "html");
156         // except this might cause problems with subclasses
157         String name = "/" + StringUtils.replace(DialogMultiSelect.class.getName(), ".", "/") + "Inner.html";
158         Map map = new HashMap();
159         map.put("this", this);
160         return FreemarkerUtil.process(name, map);
161     }
162 
163     /**
164      * JS function used to create an object out of the input fields
165      */
166     public String getGetObjectFunction() {
167         return "function(prefix, index){return {value: $(prefix).value }}";
168     }
169 
170     /**
171      * JS function used to create a new empty object
172      */
173     public String getNewObjectFunction() {
174         return "function(){return {value: ''}}";
175     }
176 
177     /**
178      * Create the object to initialize the table
179      */
180     public String getJSON() {
181         if (this.isSaveAsJSON()) {
182             return this.getValue();
183         }
184 
185         List values;
186         if (this.isSaveAsList()) {
187             values = Arrays.asList(this.getValue().split(","));
188         }
189         else {
190             values = this.getValues();
191         }
192 
193         if (values.size() == 0) {
194             return "[{value:''}]";
195         }
196 
197         List objects = new ArrayList();
198         for (Iterator iter = values.iterator(); iter.hasNext();) {
199             String value = (String) iter.next();
200             objects.add("{value: '" + StringEscapeUtils.escapeJavaScript(value) + "'}");
201         }
202         return "[" + StringUtils.join(objects.iterator(), ",") + "]";
203     }
204 
205     public String getSaveInfo() {
206         Boolean renderSaveInfo = BooleanUtils.toBooleanObject(this.getConfigValue("saveInfo"));
207         if (BooleanUtils.toBooleanDefaultIfNull(renderSaveInfo, true)) {
208             ControlImpl dummy = new ControlImpl(this.getName(), (String) null);
209             if (!isSaveAsList() && !isSaveAsJSON()) {
210                 dummy.setValueType(ControlImpl.VALUETYPE_MULTIPLE);
211             }
212             return dummy.getHtmlSaveInfo();
213         }
214         // don' create the save info
215         return "";
216     }
217 
218     public boolean isSaveAsList() {
219         return StringUtils.equals(this.getConfigValue(CONFIG_SAVE_MODE), SAVE_MODE_LIST);
220     }
221 
222     public boolean isSaveAsJSON() {
223         return StringUtils.equals(this.getConfigValue(CONFIG_SAVE_MODE), SAVE_MODE_JSON);
224     }
225 
226     /**
227      * If the values are saved using the valueType multiple, we can not use the same name for the hidden field we use
228      * for persisting the data.
229      * @return the name of the hidden field
230      */
231     public String getHiddenFieldName() {
232         if (this.isSaveAsList()) {
233             return this.getName();
234         }
235 
236         return this.getName() + "Persisted";
237     }
238 
239 }