KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > myfaces > renderkit > html > HtmlRendererUtils


1 /*
2  * Copyright 2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.myfaces.renderkit.html;
17
18 import java.io.IOException JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
25
26 import javax.faces.FacesException;
27 import javax.faces.component.EditableValueHolder;
28 import javax.faces.component.NamingContainer;
29 import javax.faces.component.UIComponent;
30 import javax.faces.component.UIForm;
31 import javax.faces.component.UISelectMany;
32 import javax.faces.component.UISelectOne;
33 import javax.faces.component.UIViewRoot;
34 import javax.faces.context.FacesContext;
35 import javax.faces.context.ResponseWriter;
36 import javax.faces.convert.Converter;
37 import javax.faces.model.SelectItem;
38 import javax.faces.model.SelectItemGroup;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.myfaces.config.MyfacesConfig;
43 import org.apache.myfaces.renderkit.RendererUtils;
44 import org.apache.myfaces.renderkit.html.util.DummyFormUtils;
45 import org.apache.myfaces.renderkit.html.util.JavascriptUtils;
46
47 /**
48  * @author Manfred Geiler (latest modification by $Author: tomsp $)
49  * @version $Revision: 1.30 $ $Date: 2005/03/22 12:25:30 $
50  * $Log: HtmlRendererUtils.java,v $
51  * Revision 1.30 2005/03/22 12:25:30 tomsp
52  * fixed bug in renderSelectOptions - looking for itemStrValue in lookupSet did not work
53  *
54  * Revision 1.29 2005/03/16 20:34:36 mmarinschek
55  * fix for MYFACES-89, alien commit for Heath Borders
56  *
57  * Revision 1.28 2005/03/15 05:24:03 svieujot
58  * Add a fallback textarea mode to the htmlEditor.
59  *
60  * Revision 1.27 2005/01/24 15:43:13 svieujot
61  * Adjust comments.
62  *
63  * Revision 1.20 2004/10/13 11:51:01 matze
64  * renamed packages to org.apache
65  *
66  * Revision 1.19 2004/09/08 09:32:03 manolito MyfacesConfig moved to config
67  * package
68  *
69  * Revision 1.18 2004/08/09 11:47:09 manolito CSS style support also for non OL
70  * or UL layout
71  *
72  * Revision 1.17 2004/07/18 22:45:11 o_rossmueller fix #992668: convert values
73  * to string for 'selected' comparision
74  *
75  * Revision 1.16 2004/07/09 02:26:19 dave0000 cleanup
76  *
77  * Revision 1.15 2004/07/01 22:00:57 mwessendorf ASF switch
78  *
79  * Revision 1.14 2004/06/21 23:23:37 o_rossmueller fix #976411: removed </input>
80  * tag for selectMultiCheckbox fix #972165: also check for readonly and also
81  * check for selectMultiCheckbox
82  *
83  * Revision 1.13 2004/06/17 00:35:50 o_rossmueller fix #972165: do not reset
84  * disabled html checkboxes (the browser does not send a form value for disabled
85  * checkboxes even if value=true)
86  *
87  * Revision 1.12 2004/06/16 23:51:15 o_rossmueller fix #970747: force separate
88  * end tag for empty select list
89  *
90  * Revision 1.11 2004/06/03 12:57:03 o_rossmueller modified link renderer to use
91  * one hidden field for all links according to 1.1 renderkit docs added
92  * onclick=clear_XXX to button
93  *
94  * Revision 1.10 2004/05/29 10:19:54 mwessendorf made the class FINAL, because
95  * has only one private const
96  *
97  * Revision 1.9 2004/05/18 14:31:39 manolito user role support completely moved
98  * to components source tree
99  *
100  * Revision 1.8 2004/05/03 11:34:27 manolito bug #945118 (Checkbox session
101  * state) fixed
102  *
103  * Revision 1.7 2004/04/30 09:11:38 manolito no message
104  *
105  * Revision 1.6 2004/04/29 19:34:38 o_rossmueller javascript for 'target'
106  * attribute handling
107  *
108  * Revision 1.5 2004/04/29 14:25:23 manolito javascript function name bugfix
109  *
110  * Revision 1.4 2004/04/27 10:32:24 manolito clear hidden inputs javascript
111  * function
112  *
113  * Revision 1.3 2004/04/06 15:34:12 manolito decode methods must not set
114  * submitted value to null
115  *
116  * Revision 1.2 2004/04/01 12:43:18 manolito html nesting bug fixed
117  *
118  * Revision 1.1 2004/03/29 14:57:00 manolito refactoring for implementation and
119  * non-standard component split
120  *
121  * Revision 1.17 2004/03/26 13:39:14 manolito added javascript 'return false' to
122  * onClick attribute in render link method
123  *
124  */

125 public final class HtmlRendererUtils {
126     private static final Log log = LogFactory.getLog(HtmlRendererUtils.class);
127
128     //private static final String[] EMPTY_STRING_ARRAY = new String[0];
129
private static final String JavaDoc LINE_SEPARATOR = System.getProperty(
130             "line.separator", "\r\n");
131
132     private static final String JavaDoc HIDDEN_COMMANDLINK_FIELD_NAME = "_link_hidden_";
133
134
135     private HtmlRendererUtils() {
136         // utility class, do not instantiate
137
}
138
139     /**
140      * X-CHECKED: tlddoc h:inputText
141      *
142      * @param facesContext
143      * @param component
144      */

145     public static void decodeUIInput(FacesContext facesContext,
146             UIComponent component) {
147         if (!(component instanceof EditableValueHolder)) {
148             throw new IllegalArgumentException JavaDoc("Component "
149                     + component.getClientId(facesContext)
150                     + " is not an EditableValueHolder");
151         }
152         Map JavaDoc paramMap = facesContext.getExternalContext()
153                 .getRequestParameterMap();
154         String JavaDoc clientId = component.getClientId(facesContext);
155         if (paramMap.containsKey(clientId)) {
156             //request parameter found, set submittedValue
157
((EditableValueHolder) component).setSubmittedValue(paramMap
158                     .get(clientId));
159         } else {
160             //request parameter not found, nothing to decode - set submitted value to empty
161
//if the component has not been disabled
162
if(!isDisabledOrReadOnly(component))
163             {
164                 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING );
165             }
166         }
167     }
168
169     /**
170      * X-CHECKED: tlddoc h:selectBooleanCheckbox
171      *
172      * @param facesContext
173      * @param component
174      */

175     public static void decodeUISelectBoolean(FacesContext facesContext,
176             UIComponent component) {
177         if (!(component instanceof EditableValueHolder)) {
178             throw new IllegalArgumentException JavaDoc("Component "
179                     + component.getClientId(facesContext)
180                     + " is not an EditableValueHolder");
181         }
182         Map JavaDoc paramMap = facesContext.getExternalContext()
183                 .getRequestParameterMap();
184         String JavaDoc clientId = component.getClientId(facesContext);
185         if (paramMap.containsKey(clientId)) {
186             String JavaDoc reqValue = (String JavaDoc) paramMap.get(clientId);
187             if (reqValue != null
188                     && (reqValue.equalsIgnoreCase("on")
189                             || reqValue.equalsIgnoreCase("yes") || reqValue
190                             .equalsIgnoreCase("true"))) {
191                 ((EditableValueHolder) component)
192                         .setSubmittedValue(Boolean.TRUE);
193             } else {
194                 ((EditableValueHolder) component)
195                         .setSubmittedValue(Boolean.FALSE);
196             }
197         } else {
198             //request parameter not found, nothing to decode - set submitted value to empty
199
//if the component has not been disabled
200
if(!isDisabledOrReadOnly(component))
201             {
202                 ((EditableValueHolder) component).setSubmittedValue( Boolean.FALSE );
203                 // Necessary for unchecked chek box
204
}
205         }
206     }
207
208     public static boolean isDisabledOrReadOnly(UIComponent component)
209     {
210         return isTrue(component.getAttributes().get("disabled")) ||
211                     isTrue(component.getAttributes().get("readOnly"));
212     }
213
214     private static boolean isTrue(Object JavaDoc obj)
215     {
216         if(!(obj instanceof Boolean JavaDoc))
217             return false;
218
219         return ((Boolean JavaDoc) obj).booleanValue();
220     }
221
222     /**
223      * X-CHECKED: tlddoc h:selectManyListbox
224      *
225      * @param facesContext
226      * @param component
227      */

228     public static void decodeUISelectMany(FacesContext facesContext,
229             UIComponent component) {
230         if (!(component instanceof EditableValueHolder)) {
231             throw new IllegalArgumentException JavaDoc("Component "
232                     + component.getClientId(facesContext)
233                     + " is not an EditableValueHolder");
234         }
235         Map JavaDoc paramValuesMap = facesContext.getExternalContext()
236                 .getRequestParameterValuesMap();
237         String JavaDoc clientId = component.getClientId(facesContext);
238         if (paramValuesMap.containsKey(clientId)) {
239             String JavaDoc[] reqValues = (String JavaDoc[]) paramValuesMap.get(clientId);
240             ((EditableValueHolder) component).setSubmittedValue(reqValues);
241         } else {
242             //request parameter not found, nothing to decode - set submitted value to empty
243
//if the component has not been disabled
244
if(!isDisabledOrReadOnly(component))
245             {
246                 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING );
247                 // Necessary for combo box / list with no selected item
248
}
249         }
250     }
251
252     /**
253      * X-CHECKED: tlddoc h:selectManyListbox
254      *
255      * @param facesContext
256      * @param component
257      */

258     public static void decodeUISelectOne(FacesContext facesContext,
259             UIComponent component) {
260         if (!(component instanceof EditableValueHolder)) {
261             throw new IllegalArgumentException JavaDoc("Component "
262                     + component.getClientId(facesContext)
263                     + " is not an EditableValueHolder");
264         }
265         Map JavaDoc paramMap = facesContext.getExternalContext()
266                 .getRequestParameterMap();
267         String JavaDoc clientId = component.getClientId(facesContext);
268         if (paramMap.containsKey(clientId)) {
269             //request parameter found, set submitted value
270
((EditableValueHolder) component).setSubmittedValue(paramMap
271                     .get(clientId));
272         } else {
273             //request parameter not found, nothing to decode - set submitted value to empty
274
//if the component has not been disabled
275

276             if(!isDisabledOrReadOnly(component))
277             {
278                 ((EditableValueHolder) component).setSubmittedValue( RendererUtils.EMPTY_STRING );
279                 // Necessary for list with no selected item
280
}
281         }
282     }
283
284     /*
285      * public static void renderCheckbox(FacesContext facesContext, UIComponent
286      * uiComponent, String value, String label, boolean checked) throws
287      * IOException { String clientId = uiComponent.getClientId(facesContext);
288      *
289      * ResponseWriter writer = facesContext.getResponseWriter();
290      *
291      * writer.startElement(HTML.INPUT_ELEM, uiComponent);
292      * writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_CHECKBOX, null);
293      * writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
294      * writer.writeAttribute(HTML.ID_ATTR, clientId, null);
295      *
296      * if (checked) { writer.writeAttribute(HTML.CHECKED_ATTR,
297      * HTML.CHECKED_ATTR, null); }
298      *
299      * if ((value != null) && (value.length() > 0)) {
300      * writer.writeAttribute(HTML.VALUE_ATTR, value, null); }
301      *
302      * renderHTMLAttributes(writer, uiComponent,
303      * HTML.INPUT_PASSTHROUGH_ATTRIBUTES); renderDisabledOnUserRole(writer,
304      * uiComponent, facesContext);
305      *
306      * if ((label != null) && (label.length() > 0)) {
307      * writer.write(HTML.NBSP_ENTITY); writer.writeText(label, null); }
308      *
309      * writer.endElement(HTML.INPUT_ELEM); }
310      */

311
312     public static void renderListbox(FacesContext facesContext,
313             UISelectOne selectOne, boolean disabled, int size)
314             throws IOException JavaDoc {
315         internalRenderSelect(facesContext, selectOne, disabled, size, false);
316     }
317
318     public static void renderListbox(FacesContext facesContext,
319             UISelectMany selectMany, boolean disabled, int size)
320             throws IOException JavaDoc {
321         internalRenderSelect(facesContext, selectMany, disabled, size, true);
322     }
323
324     public static void renderMenu(FacesContext facesContext,
325             UISelectOne selectOne, boolean disabled) throws IOException JavaDoc {
326         internalRenderSelect(facesContext, selectOne, disabled, 1, false);
327     }
328
329     public static void renderMenu(FacesContext facesContext,
330             UISelectMany selectMany, boolean disabled) throws IOException JavaDoc {
331         internalRenderSelect(facesContext, selectMany, disabled, 1, true);
332     }
333
334     private static void internalRenderSelect(FacesContext facesContext,
335             UIComponent uiComponent, boolean disabled, int size,
336             boolean selectMany) throws IOException JavaDoc {
337         ResponseWriter writer = facesContext.getResponseWriter();
338
339         writer.startElement(HTML.SELECT_ELEM, uiComponent);
340         HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
341         writer.writeAttribute(HTML.NAME_ATTR, uiComponent
342                 .getClientId(facesContext), null);
343
344         List JavaDoc selectItemList;
345         Converter converter;
346         if (selectMany) {
347             writer.writeAttribute(HTML.MULTIPLE_ATTR, "true", null);
348             selectItemList = RendererUtils
349                     .getSelectItemList((UISelectMany) uiComponent);
350             try {
351                 converter = RendererUtils.findUISelectManyConverter(
352                         facesContext, (UISelectMany) uiComponent);
353             } catch (FacesException e) {
354                 log.error("Error finding Converter for component with id "
355                         + uiComponent.getClientId(facesContext));
356                 converter = null;
357             }
358         } else {
359             selectItemList = RendererUtils
360                     .getSelectItemList((UISelectOne) uiComponent);
361             try {
362                 converter = RendererUtils.findUIOutputConverter(facesContext,
363                         (UISelectOne) uiComponent);
364             } catch (FacesException e) {
365                 log.error("Error finding Converter for component with id "
366                         + uiComponent.getClientId(facesContext));
367                 converter = null;
368             }
369         }
370
371         if (size == 0) {
372             //No size given (Listbox) --> size is number of select items
373
writer.writeAttribute(HTML.SIZE_ATTR, Integer
374                     .toString(selectItemList.size()), null);
375         } else {
376             writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
377         }
378         renderHTMLAttributes(writer, uiComponent,
379                 HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
380         if (disabled) {
381             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
382         }
383
384         Set JavaDoc lookupSet;
385         boolean useSubmittedValue;
386         if (selectMany) {
387             UISelectMany uiSelectMany = (UISelectMany) uiComponent;
388             lookupSet = RendererUtils.getSubmittedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
389             if (lookupSet == null)
390             {
391                 useSubmittedValue = false;
392                 lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
393             }
394             else
395             {
396                 useSubmittedValue = true;
397             }
398         } else {
399             UISelectOne uiSelectOne = (UISelectOne) uiComponent;
400             Object JavaDoc lookup = uiSelectOne.getSubmittedValue();
401             if (lookup == null)
402             {
403                 useSubmittedValue = false;
404                 lookup = uiSelectOne.getValue();
405             }
406             else
407             {
408                 useSubmittedValue = true;
409             }
410             String JavaDoc lookupString = RendererUtils.getConvertedStringValue(facesContext, uiComponent, converter, lookup);
411             lookupSet = Collections.singleton(lookupString);
412         }
413
414         renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
415                 useSubmittedValue, selectItemList);
416         // bug #970747: force separate end tag
417
writer.writeText("", null);
418         writer.endElement(HTML.SELECT_ELEM);
419     }
420
421     /**
422      * Renders the select options for a <code>UIComponent</code> that is
423      * rendered as an HTML select element.
424      *
425      * @param context
426      * the current <code>FacesContext</code>.
427      * @param component
428      * the <code>UIComponent</code> whose options need to be
429      * rendered.
430      * @param converter
431      * <code>component</code>'s converter
432      * @param lookupSet
433      * the <code>Set</code> to use to look up selected options
434      * @param useSubmittedValue
435      * whether we are using the submittedValue
436      * @param selectItemList
437      * the <code>List</code> of <code>SelectItem</code> s to be
438      * rendered as HTML option elements.
439      * @throws IOException
440      */

441     private static void renderSelectOptions(FacesContext context,
442             UIComponent component, Converter converter, Set JavaDoc lookupSet,
443             boolean useSubmittedValue, List JavaDoc selectItemList) throws IOException JavaDoc {
444         ResponseWriter writer = context.getResponseWriter();
445
446         for (Iterator JavaDoc it = selectItemList.iterator(); it.hasNext();) {
447             SelectItem selectItem = (SelectItem) it.next();
448
449             if (selectItem instanceof SelectItemGroup) {
450                 writer.startElement(HTML.OPTGROUP_ELEM, null);
451                 writer.writeAttribute(HTML.LABEL_ATTR, selectItem.getLabel(),
452                         null);
453                 SelectItem[] selectItems = ((SelectItemGroup) selectItem)
454                         .getSelectItems();
455                 renderSelectOptions(context, component, converter, lookupSet,
456                         useSubmittedValue, Arrays.asList(selectItems));
457                 writer.endElement(HTML.OPTGROUP_ELEM);
458             } else {
459                 String JavaDoc itemStrValue = RendererUtils.getConvertedStringValue(context, component,
460                         converter, selectItem);
461
462                 writer.write("\t\t");
463                 writer.startElement(HTML.OPTION_ELEM, null);
464                 if (itemStrValue != null) {
465                     writer.writeAttribute(HTML.VALUE_ATTR, itemStrValue, null);
466                 }
467
468                 if (lookupSet.contains(itemStrValue)) { //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings only when useSubmittedValue==true, else use the real item value Objects
469
writer.writeAttribute(HTML.SELECTED_ATTR,
470                             HTML.SELECTED_ATTR, null);
471                 }
472
473                 if (selectItem.isDisabled()) {
474                     writer.writeAttribute(HTML.DISABLED_ATTR,
475                             HTML.DISABLED_ATTR, null);
476                 }
477
478                 writer.writeText(selectItem.getLabel(), null);
479
480                 writer.endElement(HTML.OPTION_ELEM);
481             }
482         }
483     }
484
485     /*
486      * public static void renderRadio(FacesContext facesContext, UIInput
487      * uiComponent, String value, String label, boolean checked) throws
488      * IOException { String clientId = uiComponent.getClientId(facesContext);
489      *
490      * ResponseWriter writer = facesContext.getResponseWriter();
491      *
492      * writer.startElement(HTML.INPUT_ELEM, uiComponent);
493      * writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
494      * writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
495      * writer.writeAttribute(HTML.ID_ATTR, clientId, null);
496      *
497      * if (checked) { writer.writeAttribute(HTML.CHECKED_ATTR,
498      * HTML.CHECKED_ATTR, null); }
499      *
500      * if ((value != null) && (value.length() > 0)) {
501      * writer.writeAttribute(HTML.VALUE_ATTR, value, null); }
502      *
503      * renderHTMLAttributes(writer, uiComponent,
504      * HTML.INPUT_PASSTHROUGH_ATTRIBUTES); renderDisabledOnUserRole(writer,
505      * uiComponent, facesContext);
506      *
507      * if ((label != null) && (label.length() > 0)) {
508      * writer.write(HTML.NBSP_ENTITY); writer.writeText(label, null); }
509      *
510      * writer.endElement(HTML.INPUT_ELEM); }
511      */

512
513     public static void writePrettyLineSeparator(FacesContext facesContext)
514             throws IOException JavaDoc {
515         if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext())
516                 .isPrettyHtml()) {
517             facesContext.getResponseWriter().write(LINE_SEPARATOR);
518         }
519     }
520
521     public static void writePrettyIndent(FacesContext facesContext)
522             throws IOException JavaDoc {
523         if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext())
524                 .isPrettyHtml()) {
525             facesContext.getResponseWriter().write('\t');
526         }
527     }
528
529     /**
530      * @return true, if the attribute was written
531      * @throws java.io.IOException
532      */

533     public static boolean renderHTMLAttribute(ResponseWriter writer,
534             String JavaDoc componentProperty, String JavaDoc attrName, Object JavaDoc value)
535             throws IOException JavaDoc {
536         if (!RendererUtils.isDefaultAttributeValue(value)) {
537             // render JSF "styleClass" attribute as "class"
538
String JavaDoc htmlAttrName = attrName.equals(HTML.STYLE_CLASS_ATTR) ? HTML.CLASS_ATTR
539                     : attrName;
540             writer.writeAttribute(htmlAttrName, value, componentProperty);
541             return true;
542         }
543         
544         return false;
545     }
546
547     /**
548      * @return true, if the attribute was written
549      * @throws java.io.IOException
550      */

551     public static boolean renderHTMLAttribute(ResponseWriter writer,
552             UIComponent component, String JavaDoc componentProperty, String JavaDoc htmlAttrName)
553             throws IOException JavaDoc {
554         Object JavaDoc value = component.getAttributes().get(componentProperty);
555         return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
556                 value);
557     }
558
559     /**
560      * @return true, if an attribute was written
561      * @throws java.io.IOException
562      */

563     public static boolean renderHTMLAttributes(ResponseWriter writer,
564             UIComponent component, String JavaDoc[] attributes) throws IOException JavaDoc {
565         boolean somethingDone = false;
566         for (int i = 0, len = attributes.length; i < len; i++) {
567             String JavaDoc attrName = attributes[i];
568             if (renderHTMLAttribute(writer, component, attrName, attrName)) {
569                 somethingDone = true;
570             }
571         }
572         return somethingDone;
573     }
574
575     public static boolean renderHTMLAttributeWithOptionalStartElement(
576             ResponseWriter writer, UIComponent component, String JavaDoc elementName,
577             String JavaDoc attrName, Object JavaDoc value, boolean startElementWritten)
578             throws IOException JavaDoc {
579         if (!RendererUtils.isDefaultAttributeValue(value)) {
580             if (!startElementWritten) {
581                 writer.startElement(elementName, component);
582                 startElementWritten = true;
583             }
584             renderHTMLAttribute(writer, attrName, attrName, value);
585         }
586         return startElementWritten;
587     }
588
589     public static boolean renderHTMLAttributesWithOptionalStartElement(
590             ResponseWriter writer, UIComponent component, String JavaDoc elementName,
591             String JavaDoc[] attributes) throws IOException JavaDoc {
592         boolean startElementWritten = false;
593         for (int i = 0, len = attributes.length; i < len; i++) {
594             String JavaDoc attrName = attributes[i];
595             Object JavaDoc value = component.getAttributes().get(attrName);
596             if (!RendererUtils.isDefaultAttributeValue(value)) {
597                 if (!startElementWritten) {
598                     writer.startElement(elementName, component);
599                     startElementWritten = true;
600                 }
601                 renderHTMLAttribute(writer, attrName, attrName, value);
602             }
603         }
604         return startElementWritten;
605     }
606
607     public static boolean renderOptionalEndElement(ResponseWriter writer,
608             UIComponent component, String JavaDoc elementName, String JavaDoc[] attributes)
609             throws IOException JavaDoc {
610         boolean endElementNeeded = false;
611         for (int i = 0, len = attributes.length; i < len; i++) {
612             String JavaDoc attrName = attributes[i];
613             Object JavaDoc value = component.getAttributes().get(attrName);
614             if (!RendererUtils.isDefaultAttributeValue(value)) {
615                 endElementNeeded = true;
616                 break;
617             }
618         }
619         if (endElementNeeded) {
620             writer.endElement(elementName);
621             return true;
622         }
623
624         return false;
625     }
626
627     public static void writeIdIfNecessary(ResponseWriter writer, UIComponent component,
628                                           FacesContext facesContext)
629         throws IOException JavaDoc
630     {
631         if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
632         {
633             writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext),null);
634         }
635     }
636
637     public static class LinkParameter {
638         private String JavaDoc _name;
639
640         private Object JavaDoc _value;
641
642         public String JavaDoc getName() {
643             return _name;
644         }
645
646         public void setName(String JavaDoc name) {
647             _name = name;
648         }
649
650         public Object JavaDoc getValue() {
651             return _value;
652         }
653
654         public void setValue(Object JavaDoc value) {
655             _value = value;
656         }
657
658     }
659
660     public static void renderHiddenCommandFormParams(ResponseWriter writer,
661             Set JavaDoc dummyFormParams) throws IOException JavaDoc {
662         for (Iterator JavaDoc it = dummyFormParams.iterator(); it.hasNext();) {
663             writer.startElement(HTML.INPUT_ELEM, null);
664             writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
665             writer.writeAttribute(HTML.NAME_ATTR, it.next(), null);
666             writer.endElement(HTML.INPUT_ELEM);
667         }
668     }
669
670     /**
671      * Render the javascript function that is called on a click on a commandLink
672      * to clear the hidden inputs. This is necessary because on a browser back,
673      * each hidden input still has it's old value (browser cache!) and therefore
674      * a new submit would cause the according action once more!
675      *
676      * @param writer
677      * @param formName
678      * @param dummyFormParams
679      * @param formTarget
680      * @throws IOException
681      */

682     public static void renderClearHiddenCommandFormParamsFunction(
683             ResponseWriter writer, String JavaDoc formName, Set JavaDoc dummyFormParams,
684             String JavaDoc formTarget) throws IOException JavaDoc {
685         //render the clear hidden inputs javascript function
686
String JavaDoc functionName = getClearHiddenCommandFormParamsFunctionName(formName);
687         writer.startElement(HTML.SCRIPT_ELEM, null);
688         writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", null);
689         writer.write("\n<!--");
690         writer.write("\nfunction ");
691         writer.write(functionName);
692         writer.write("() {");
693         if (dummyFormParams != null) {
694             writer.write("\n var f = document.forms['");
695             writer.write(formName);
696             writer.write("'];");
697             for (Iterator JavaDoc it = dummyFormParams.iterator(); it.hasNext();) {
698                 writer.write("\n f.elements['");
699                 writer.write((String JavaDoc) it.next());
700                 writer.write("'].value=null;");
701             }
702         }
703         // clear form target
704
writer.write("\n f.target=");
705         if (formTarget == null || formTarget.length() == 0) {
706             //Normally one would think that setting target to null has the
707
//desired effect, but once again IE is different...
708
//Setting target to null causes IE to open a new window!
709
writer.write("'';");
710         } else {
711             writer.write("'");
712             writer.write(formTarget);
713             writer.write("';");
714         }
715         writer.write("\n}");
716
717         //Just to be sure we call this clear method on each load.
718
//Otherwise in the case, that someone submits a form by pressing Enter
719
//within a text input, the hidden inputs won't be cleared!
720
writer.write("\n");
721         writer.write(functionName);
722         writer.write("();");
723
724         writer.write("\n//-->\n");
725         writer.endElement(HTML.SCRIPT_ELEM);
726     }
727
728     /**
729      * Prefixes the given String with "clear_" and removes special characters
730      *
731      * @param formName
732      * @return
733      */

734     public static String JavaDoc getClearHiddenCommandFormParamsFunctionName(
735             String JavaDoc formName) {
736         return "clear_"
737                 + JavascriptUtils.getValidJavascriptName(formName, false);
738     }
739
740     public static String JavaDoc getFormName(UIComponent component, FacesContext context) {
741         //Find form
742
UIComponent parent = component.getParent();
743         while (parent != null && !(parent instanceof UIForm)) {
744             parent = parent.getParent();
745         }
746
747         if (parent != null) {
748             //link is nested inside a form
749
return ((UIForm) parent).getClientId(context);
750         }
751         //not nested in form, we must add a dummy form at the end of the
752
// document
753
return DummyFormUtils.DUMMY_FORM_NAME;
754     }
755
756     public static String JavaDoc getHiddenCommandLinkFieldName(String JavaDoc formName) {
757         return formName + NamingContainer.SEPARATOR_CHAR
758                 + HIDDEN_COMMANDLINK_FIELD_NAME;
759     }
760
761 }
Popular Tags