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.StringUtils;
41  
42  import java.io.IOException;
43  import java.io.Writer;
44  import java.util.ArrayList;
45  import java.util.Arrays;
46  import java.util.HashMap;
47  import java.util.Iterator;
48  import java.util.List;
49  import java.util.Map;
50  
51  
52  /**
53   * Control to select multiple values. The values can get stored as list, in JSON format or as a multiple values
54   * @author Philipp Bracher
55   * @version $Revision: 41137 $ ($Author: gjoseph $)
56   */
57  public class DialogMultiSelect extends DialogBox {
58  
59      /**
60       * The values are saved a properties
61       */
62      public static final String SAVE_MODE_MULTIPLE = "multiple";
63  
64      /**
65       * The values are saved as a single json string
66       */
67      public static final String SAVE_MODE_JSON = "json";
68  
69      /**
70       * The values are saved as semicolon separated list
71       */
72      public static final String SAVE_MODE_LIST = "list";
73  
74      /**
75       * Set the save mode
76       */
77      public static final String CONFIG_SAVE_MODE = "saveMode";
78  
79      /**
80       * Set the onclick js code of the coose button. If non is set the button is not rendered.
81       */
82      private static final String CONFIG_CHOOSE_ONCLICK = "chooseOnclick";
83      
84      /**
85       * If you like to select the data from a tree, just define the config value tree instead of chooseOnclick
86       */
87      private static final String CONFIG_TREE = "tree";    
88  
89      /**
90       * Render the Html using a template
91       */
92      public void drawHtml(Writer out) throws IOException {
93          this.drawHtmlPre(out);
94          // this could be replaced by
95          //   out.write(FreemarkerUtil.process(this));
96          // except this could cause problems with subclasses
97          out.write(FreemarkerUtil.process(DialogMultiSelect.class, this));
98          this.drawHtmlPost(out);
99      }
100 
101     /**
102      * The button to add a new row
103      */
104     public String getAddButton() {
105         Button add = new Button();
106         add.setLabel(getMessage("buttons.add")); //$NON-NLS-1$ 
107         add.setOnclick(this.getName() + "DynamicTable.addNew();"); //$NON-NLS-1$ 
108         add.setSmall(true);
109         return add.getHtml();
110     }
111 
112     /**
113      * If this control has a choose button
114      */
115     public String getChooseButton() {
116         
117         String chooseOnclick = this.getConfigValue(CONFIG_CHOOSE_ONCLICK);
118         if(StringUtils.isEmpty(chooseOnclick)){
119             String tree = this.getConfigValue(CONFIG_TREE);
120             if(StringUtils.isNotEmpty(tree)){
121                 chooseOnclick = "mgnlOpenTreeBrowserWithControl($('${prefix}'), '" + tree + "');";
122 
123             }
124         }
125 
126         if (StringUtils.isNotEmpty(chooseOnclick)) {
127             Button choose = new Button();
128             choose.setLabel(this.getMessage("buttons.choose")); //$NON-NLS-1$
129             choose.setOnclick(chooseOnclick);
130 
131             choose.setSmall(true);
132             return choose.getHtml();
133         }
134         return "";
135     }
136 
137     /**
138      * Button for deleting a row
139      */
140     public String getDeleteButton() {
141         Button delete = new Button();
142         delete.setLabel(this.getMessage("buttons.delete")); //$NON-NLS-1$
143         delete
144             .setOnclick(this.getName() + "DynamicTable.del('${index}');" + this.getName() + "DynamicTable.persist();"); //$NON-NLS-1$
145         delete.setSmall(true);
146         return delete.getHtml();
147     }
148 
149     /**
150      * Called by the template. It renders the dynamic inner row using trimpaths templating mechanism.
151      */
152     public String getInnerHtml() {
153         // TODO - this could potentially be replaced by
154         //   return FreemarkerUtil.process(this, "Inner", "html");
155         // except this might cause problems with subclasses
156         String name = "/" + StringUtils.replace(DialogMultiSelect.class.getName(), ".", "/") + "Inner.html";
157         Map map = new HashMap();
158         map.put("this", this);
159         return FreemarkerUtil.process(name, map);
160     }
161 
162     /**
163      * JS function used to create an object out of the input fields
164      */
165     public String getGetObjectFunction() {
166         return "function(prefix, index){return {value: $(prefix).value }}";
167     }
168 
169     /**
170      * JS function used to create a new empty object
171      */
172     public String getNewObjectFunction() {
173         return "function(){return {value: ''}}";
174     }
175 
176     /**
177      * Create the object to initialize the table
178      */
179     public String getJSON() {
180         if (this.isSaveAsJSON()) {
181             return this.getValue();
182         }
183 
184         List values;
185         if (this.isSaveAsList()) {
186             values = Arrays.asList(this.getValue().split(","));
187         }
188         else {
189             values = this.getValues();
190         }
191 
192         if (values.size() == 0) {
193             return "[{value:''}]";
194         }
195 
196         List objects = new ArrayList();
197         for (Iterator iter = values.iterator(); iter.hasNext();) {
198             String value = (String) iter.next();
199             objects.add("{value: '" + value + "'}");
200         }
201         return "[" + StringUtils.join(objects.iterator(), ",") + "]";
202     }
203 
204     public String getSaveInfo() {
205         Boolean renderSaveInfo = BooleanUtils.toBooleanObject(this.getConfigValue("saveInfo"));
206         if (BooleanUtils.toBooleanDefaultIfNull(renderSaveInfo, true)) {
207             ControlImpl dummy = new ControlImpl(this.getName(), (String) null);
208             if (!isSaveAsList() && !isSaveAsJSON()) {
209                 dummy.setValueType(ControlImpl.VALUETYPE_MULTIPLE);
210             }
211             return dummy.getHtmlSaveInfo();
212         }
213         // don' create the save info
214         return "";
215     }
216 
217     public boolean isSaveAsList() {
218         return StringUtils.equals(this.getConfigValue(CONFIG_SAVE_MODE), SAVE_MODE_LIST);
219     }
220 
221     public boolean isSaveAsJSON() {
222         return StringUtils.equals(this.getConfigValue(CONFIG_SAVE_MODE), SAVE_MODE_JSON);
223     }
224 
225     /**
226      * If the values are saved using the valueType multiple, we can not use the same name for the hidden field we use
227      * for persisting the data.
228      * @return the name of the hidden field
229      */
230     public String getHiddenFieldName() {
231         if (this.isSaveAsList()) {
232             return this.getName();
233         }
234 
235         return this.getName() + "Persisted";
236     }
237 
238 }