View Javadoc

1   /*
2    * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/taglib/DbSelectTag.java,v 1.44 2006/03/30 02:08:07 nicparise Exp $
3    * $Revision: 1.44 $
4    * $Date: 2006/03/30 02:08:07 $
5    *
6    * DbForms - a Rapid Application Development Framework
7    * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8    *
9    * This library is free software; you can redistribute it and/or
10   * modify it under the terms of the GNU Lesser General Public
11   * License as published by the Free Software Foundation; either
12   * version 2.1 of the License, or (at your option) any later version.
13   *
14   * This library is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this library; if not, write to the Free Software
21   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22   */
23  
24  package org.dbforms.taglib;
25  
26  import org.dbforms.event.AbstractWebEvent;
27  import org.dbforms.event.eventtype.EventType;
28  import org.dbforms.interfaces.IDataContainer;
29  import org.dbforms.interfaces.StaticData;
30  
31  import org.dbforms.util.*;
32  
33  import java.util.List;
34  
35  import javax.servlet.http.*;
36  import javax.servlet.jsp.*;
37  
38  /***
39   * <p>
40   * This tag renders a html SELECT element including embedding OPTION elements.
41   * </p>
42   * 
43   * @author Joachim Peer
44   * @author Philip Grunikiewicz
45   */
46  public class DbSelectTag extends AbstractDbBaseHandlerTag implements
47  		IDataContainer, javax.servlet.jsp.tagext.TryCatchFinally {
48  	private List embeddedData = null;
49  
50  	private String customEntry;
51  
52  	private String ifEmptyDontDraw = "false";
53  
54  	private String ifEmptyItem = null;
55  
56  	private String overrideReadOnly = "false";
57  
58  	private String selectedIndex;
59  
60  	private String size;
61  
62  	/***
63  	 * Sets the customEntry
64  	 * 
65  	 * @param customEntry
66  	 *            The customEntry to set
67  	 */
68  	public void setCustomEntry(String customEntry) {
69  		this.customEntry = customEntry;
70  	}
71  
72  	/***
73  	 * Gets the customEntry
74  	 * 
75  	 * @return Returns a String
76  	 */
77  	public String getCustomEntry() {
78  		return customEntry;
79  	}
80  
81  	/***
82  	 * This method is a "hookup" for EmbeddedData - Tags which can assign the
83  	 * lines of data they loaded (by querying a database, or by rendering
84  	 * data-subelements, etc. etc.) and make the data available to this tag.
85  	 * [this method is defined in Interface DataContainer]
86  	 * 
87  	 * @param embeddedData
88  	 *            DOCUMENT ME!
89  	 */
90  	public void setEmbeddedData(List embeddedData) {
91  		this.embeddedData = embeddedData;
92  	}
93  
94  	/***
95  	 * DOCUMENT ME!
96  	 * 
97  	 * @return DOCUMENT ME!
98  	 */
99  	public String getFormattedFieldValue() {
100 		String res = getFieldValue();
101 
102 		if (res == null) {
103 			res = ParseUtil.getParameter((HttpServletRequest) this.pageContext
104 					.getRequest(), getFormFieldName());
105 		}
106 
107 		return res;
108 	}
109 
110 	/***
111 	 * DOCUMENT ME!
112 	 * 
113 	 * @param b
114 	 */
115 	public void setIfEmptyDontDraw(String b) {
116 		ifEmptyDontDraw = b;
117 	}
118 
119 	/***
120 	 * DOCUMENT ME!
121 	 * 
122 	 * @return
123 	 */
124 	public boolean hasIfEmptyDontDrawSet() {
125 		return Util.getTrue(ifEmptyDontDraw);
126 	}
127 
128 	/***
129 	 * DOCUMENT ME!
130 	 * 
131 	 * @param string
132 	 */
133 	public void setIfEmptyItem(String string) {
134 		ifEmptyItem = string;
135 	}
136 
137 	/***
138 	 * DOCUMENT ME!
139 	 * 
140 	 * @return
141 	 */
142 	public String getIfEmptyItem() {
143 		return ifEmptyItem;
144 	}
145 
146 	/***
147 	 * DOCUMENT ME!
148 	 * 
149 	 * @param b
150 	 */
151 	public void setOverrideReadOnly(String b) {
152 		overrideReadOnly = b;
153 	}
154 
155 	/***
156 	 * DOCUMENT ME!
157 	 * 
158 	 * @param selectedIndex
159 	 *            DOCUMENT ME!
160 	 */
161 	public void setSelectedIndex(String selectedIndex) {
162 		this.selectedIndex = selectedIndex;
163 	}
164 
165 	/***
166 	 * DOCUMENT ME!
167 	 * 
168 	 * @return DOCUMENT ME!
169 	 */
170 	public String getSelectedIndex() {
171 		return selectedIndex;
172 	}
173 
174 	/***
175 	 * Set the size of this field (synonym for <code>setCols()</code>).
176 	 * 
177 	 * @param size
178 	 *            The new size
179 	 */
180 	public void setSize(String size) {
181 		this.size = size;
182 	}
183 
184 	/***
185 	 * Return the size of this field (synonym for <code>getCols()</code>).
186 	 * 
187 	 * @return DOCUMENT ME!
188 	 */
189 	public String getSize() {
190 		return size;
191 	}
192 
193 	/***
194 	 * DOCUMENT ME!
195 	 * 
196 	 * @return DOCUMENT ME!
197 	 * 
198 	 * @throws javax.servlet.jsp.JspException
199 	 *             DOCUMENT ME!
200 	 * @throws JspException
201 	 *             DOCUMENT ME!
202 	 */
203 	public int doEndTag() throws javax.servlet.jsp.JspException {
204 		HttpServletRequest request = (HttpServletRequest) this.pageContext
205 				.getRequest();
206 		List errors = (List) request.getAttribute("errors");
207 		AbstractWebEvent we = getParentForm().getWebEvent();
208 
209 		StringBuffer tagBuf = new StringBuffer();
210 		StringBuffer selectedOptions = new StringBuffer();
211 		int embeddedDataSize = 0;
212 
213 		String currentValue = getFormFieldValue();
214 
215 		if (embeddedData != null) {
216 			// PG, 2001-12-14
217 			// Is their a custom entry? Display first...
218 			String ce = null;
219 
220 			if (((ce = this.getCustomEntry()) != null)
221 					&& (ce.trim().length() > 0)) {
222 				boolean isSelected = false;
223 				String aKey = org.dbforms.util.StringUtil
224 						.getEmbeddedStringWithoutDots(ce, 0, ',');
225 				String aValue = org.dbforms.util.StringUtil
226 						.getEmbeddedStringWithoutDots(ce, 1, ',');
227 
228            	    // is captionResource is activated, retrieve the value from the MessageResources bundle
229 				if (getParentForm().hasCaptionResourceSet()) {
230                   aValue = MessageResources.getMessage(request,aValue);
231 	            }
232 
233 				
234 				// Check if we are in redisplayFieldsOnError mode and errors
235 				// have occured
236 				// If so, only set to selected if currentRow is equal to custom
237 				// row.
238 				if ((getParentForm().hasRedisplayFieldsOnErrorSet()
239 						&& (errors != null) && (errors.size() > 0))
240 						|| ((we != null) && (we.getType()
241 								.equals(EventType.EVENT_NAVIGATION_RELOAD)))) {
242 					isSelected = (currentValue.equals(aKey));
243 				} else {
244 					isSelected = "true".equals(org.dbforms.util.StringUtil
245 							.getEmbeddedStringWithoutDots(ce, 2, ','));
246 				}
247 
248 				if (isSelected) {
249 					selectedOptions.append("-").append(aKey);
250 					/*
251 					 * Philip Grunikiewicz 2005-12-05
252 					 * 
253 					 * If in INSERT Mode and custom entry is set as default
254 					 * 
255 					 * Henner Kollmann 2005-12-15 
256 					 * 
257 					 * Only if this is a valid field!
258 					 */
259 					if (getParentForm().isFooterReached() && getField() != null) {
260 						currentValue = aKey;
261 					}
262 				}
263 
264 				tagBuf.append(generateTagString(aKey, aValue, isSelected));
265 			}
266 
267 			embeddedDataSize = embeddedData.size();
268 
269 			// check for special 'IfEmpty' processing. if used skip the
270 			// datadriven loop
271 			boolean drawIt = true;
272 			String me = null;
273 
274 			if (embeddedDataSize == 0) {
275 				if (hasIfEmptyDontDrawSet()) {
276 					drawIt = false;
277 				} else if ((me = getIfEmptyItem()) != null) {
278 					drawIt = false;
279 
280 					String aKey = org.dbforms.util.StringUtil
281 							.getEmbeddedStringWithoutDots(me, 0, ',');
282 					String aValue = org.dbforms.util.StringUtil
283 							.getEmbeddedStringWithoutDots(me, 1, ',');
284 
285 					// always selected, since no other items
286 					selectedOptions.append("-").append(aKey);
287 					tagBuf.append(generateTagString(aKey, aValue, true));
288 				}
289 			}
290 
291 			if (drawIt) {
292 				for (int i = 0; i < embeddedDataSize; i++) {
293 					StaticData aKeyValuePair = (StaticData) embeddedData.get(i);
294 					String aKey = aKeyValuePair.getKey();
295 					String aValue = aKeyValuePair.getValue();
296 
297 					// select, if datadriven and data matches with current value
298 					// OR if explicitly set by user
299 					boolean isSelected = aKey.equals(currentValue);
300 
301 					if (isSelected) {
302 						selectedOptions.append("-").append(aKey);
303 					}
304 
305 					tagBuf.append(generateTagString(aKey, aValue, isSelected));
306 				}
307 			}
308 		}
309 
310 		tagBuf.append("</select>");
311 
312 		//
313 		// For read-only mode. Add unique generic javascript function.
314 		// Reset to the default selected values (in case of multiselection)
315 		// using javascript function on client side.
316 		//
317 		if (((!hasOverrideReadOnlySet()) && hasReadOnlySet())
318 				|| getParentForm().hasReadOnlySet()) {
319 			selectedOptions.append("-");
320 
321 			String onChange = "resetSelect(this,'" + selectedOptions.toString()
322 					+ "');";
323 			setOnChange(onChange
324 					+ ((getOnChange() != null) ? getOnChange() : ""));
325 
326 			if (!getParentForm().existJavascriptFunction("resetSelect")) {
327 				StringBuffer buf = new StringBuffer();
328 				buf.append("\nfunction resetSelect(sel,x){\n");
329 				buf.append("   for(i=0;i<sel.length;i++){\n");
330 				buf.append("      var tmp = sel.options[i].value;\n");
331 				buf.append("      if(x.indexOf(('-'+tmp+'-'))!=-1){\n");
332 				buf.append("         sel.options[i].selected=true;\n");
333 				buf.append("      }else{;\n");
334 				buf.append("         sel.options[i].selected=false;\n");
335 				buf.append("      }\n");
336 				buf.append("   }\n");
337 				buf.append("}\n");
338 
339 				getParentForm().addJavascriptFunction("resetSelect", buf);
340 			}
341 		}
342 
343 		// For generation Javascript Validation. Need original and modified
344 		// fields name
345 		getParentForm().addChildName(getName(), getFormFieldName());
346 
347 		try {
348 			if ((embeddedDataSize > 0) || !hasIfEmptyDontDrawSet()) {
349 				pageContext.getOut().write(generateSelectHeader());
350 				pageContext.getOut().write(tagBuf.toString());
351 				writeOutSpecialValues();
352 			}
353 		} catch (java.io.IOException ioe) {
354 			throw new JspException("IO Error: " + ioe.getMessage());
355 		}
356 
357 		return EVAL_PAGE;
358 	}
359 
360 	/***
361 	 * DOCUMENT ME!
362 	 */
363 	public void doFinally() {
364 		embeddedData = null;
365 		selectedIndex = null;
366 		customEntry = null;
367 		size = null;
368 		ifEmptyDontDraw = "false";
369 		ifEmptyItem = null;
370 		overrideReadOnly = "false";
371 		super.doFinally();
372 	}
373 
374 	/***
375 	 * DOCUMENT ME!
376 	 * 
377 	 * @return DOCUMENT ME!
378 	 * 
379 	 * @throws javax.servlet.jsp.JspException
380 	 *             DOCUMENT ME!
381 	 */
382 	public int doStartTag() throws javax.servlet.jsp.JspException {
383 		return EVAL_BODY_BUFFERED;
384 	}
385 
386 	/***
387 	 * DOCUMENT ME!
388 	 * 
389 	 * @return
390 	 */
391 	public boolean hasOverrideReadOnlySet() {
392 		return overrideReadOnly.equalsIgnoreCase("true");
393 	}
394 
395 	/***
396 	 * DOCUMENT ME!
397 	 * 
398 	 * @return DOCUMENT ME!
399 	 */
400 	protected String typicalDefaultValue() {
401 		String val;
402 
403 		// Lets check if the selectedIndex parameter has been input
404 		if (((val = this.getSelectedIndex()) != null)
405 				&& (val.trim().length() != 0)) {
406 			return val;
407 		}
408 
409 		// No selectedIndex - business as usual...
410 		return (super.typicalDefaultValue());
411 	}
412 
413 	private String generateSelectHeader() throws javax.servlet.jsp.JspException {
414 		// This method have been
415 		StringBuffer tagBuf = new StringBuffer();
416 
417 		tagBuf.append("<select name=\"");
418 
419 		tagBuf.append(getFormFieldName());
420 		tagBuf.append("\"");
421 
422 		if (size != null) {
423 			tagBuf.append(" size=\"");
424 			tagBuf.append(size);
425 			tagBuf.append("\"");
426 		}
427 
428 		if (getAccessKey() != null) {
429 			tagBuf.append(" accesskey=\"");
430 			tagBuf.append(getAccessKey());
431 			tagBuf.append("\"");
432 		}
433 
434 		if (getTabIndex() != null) {
435 			tagBuf.append(" tabindex=\"");
436 			tagBuf.append(getTabIndex());
437 			tagBuf.append("\"");
438 		}
439 
440 		tagBuf.append(prepareStyles());
441 		tagBuf.append(prepareEventHandlers());
442 		tagBuf.append(">");
443 
444 		return tagBuf.toString();
445 	}
446 
447 	private String generateTagString(String value, String description,
448 			boolean selected) {
449 		StringBuffer tagBuf = new StringBuffer();
450 		tagBuf.append("<option value=\"");
451 		tagBuf.append(escapeHTML(value));
452 		tagBuf.append("\"");
453 
454 		if (selected) {
455 			tagBuf.append(" selected=\"selected\" ");
456 		}
457 
458 		// 20021203-HKK: Removed unneeded blank
459 		tagBuf.append(">");
460 		tagBuf.append(escapeHTML(description));
461 
462 		// 20021025-HKK: Appended </option>
463 		tagBuf.append("</option>");
464 
465 		return tagBuf.toString();
466 	}
467 }