1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.toggle;
20
21 import java.io.IOException;
22 import java.lang.reflect.Method;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javax.faces.component.UIComponent;
27 import javax.faces.context.FacesContext;
28 import javax.faces.context.ResponseWriter;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.myfaces.renderkit.html.util.AddResource;
33 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
34 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
35 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
36 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlGroupRendererBase;
37
38
39
40
41
42
43
44
45
46 public class TogglePanelRenderer extends HtmlGroupRendererBase {
47
48 private static Log log = LogFactory.getLog(TogglePanelRenderer.class);
49
50 public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
51 RendererUtils.checkParamValidity(context, component, TogglePanel.class);
52 addToggleLinkJavascript(context);
53
54 TogglePanel togglePanel = (TogglePanel) component;
55 boolean toggleMode = togglePanel.isToggled();
56 toggleVisibility(togglePanel.getChildren(), toggleMode);
57
58
59 ResponseWriter writer = context.getResponseWriter();
60
61 String hiddenFieldId = getHiddenFieldId(context, togglePanel);
62
63 writer.startElement(HTML.INPUT_ELEM, component);
64 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
65 writer.writeAttribute(HTML.ID_ATTR, hiddenFieldId, null);
66 writer.writeAttribute(HTML.NAME_ATTR, hiddenFieldId, null);
67
68 writer.writeAttribute(HTML.VALUE_ATTR, toggleMode ? "1" : "", null);
69
70 writer.endElement(HTML.INPUT_ELEM);
71
72 super.encodeEnd(context, togglePanel);
73 }
74
75 private void toggleVisibility(List children, boolean toggleMode) {
76 for(Iterator it = children.iterator(); it.hasNext(); ) {
77 UIComponent component = (UIComponent) it.next();
78 setComponentVisibility( component, toggleMode );
79 }
80 }
81
82
83 public static boolean hasStyleAttribute(UIComponent component) {
84 Method[] methods = component.getClass().getMethods();
85
86 for (int i = 0; i < methods.length; i++) {
87 Method method = methods[i];
88 if (method.getName().equals("getStyle")) {
89 return true;
90 }
91 }
92 return false;
93 }
94
95
96 public static void setComponentVisibility(UIComponent component, boolean toggleMode) {
97 FacesContext context = FacesContext.getCurrentInstance();
98
99 if (!hasStyleAttribute(component)) {
100 log.info("style attribute expected, not found for component " + component.getClientId(context));
101 return;
102 }
103
104 try {
105 Class c = component.getClass();
106 Method getStyle = c.getMethod("getStyle", new Class[] {});
107 Method setStyle = c.getMethod("setStyle", new Class[] { String.class });
108
109 String style = (String) getStyle.invoke(component, new Object[] {});
110
111 boolean display = toggleMode != isHiddenWhenToggled(component);
112 if( display ){
113 if (style == null || style.length() == 0) {
114 return;
115 } else {
116 int index = style.indexOf(";display:none;");
117 if (index == -1)
118 return;
119
120 if (index == 0) {
121 style = null;
122 } else {
123 style = style.substring(0, index);
124 }
125 }
126 }else{
127 if (style == null) {
128 style = ";display:none;";
129 } else if (style.indexOf("display:none;") == -1) {
130 style = style.concat(";display:none;");
131 }
132 }
133
134 setStyle.invoke(component, new Object[] { style });
135 } catch (Throwable e) {
136 log.error("unable to set style attribute on component " + component.getClientId(context));
137 }
138 }
139
140 public static boolean isHiddenWhenToggled(UIComponent component){
141 return component instanceof ToggleLink || component instanceof ToggleGroup;
142 }
143
144 private String getHiddenFieldId(FacesContext context, TogglePanel togglePanel){
145 return togglePanel.getClientId(context) + "_hidden";
146 }
147
148 static public String getToggleJavascriptFunctionName(FacesContext context, TogglePanel togglePanel) {
149 return "MyFacesToggleLinkUtils.toggle";
150 }
151
152 public void addToggleLinkJavascript(FacesContext context)throws IOException {
153 AddResource addResource = AddResourceFactory.getInstance(context);
154
155 addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN, AbstractTogglePanel.class, "MyFacesToggleLink.js");
156 }
157 }