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.util.Iterator;
23
24 import javax.faces.component.UIComponent;
25 import javax.faces.component.UIOutput;
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.myfaces.component.UserRoleUtils;
32 import org.apache.myfaces.renderkit.html.ext.HtmlLinkRenderer;
33 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
34 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
35 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
36
37
38
39
40
41
42
43
44
45
46
47
48 public class ToggleLinkRenderer extends HtmlLinkRenderer {
49 public static final int DEFAULT_MAX_SUGGESTED_ITEMS = 200;
50
51 protected void renderOutputLinkStart(FacesContext facesContext,
52 UIOutput output) throws IOException
53 {
54 ResponseWriter writer = facesContext.getResponseWriter();
55
56 String clientId = output.getClientId(facesContext);
57
58
59 writer.startElement(HTML.ANCHOR_ELEM, output);
60 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
61 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
62 writer.writeURIAttribute(HTML.HREF_ATTR, "javascript:void(0);", null);
63
64 HtmlRendererUtils
65 .renderHTMLAttributes(
66 writer,
67 output,
68 org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.ANCHOR_PASSTHROUGH_ATTRIBUTES_WITHOUT_ONCLICK_WITHOUT_STYLE);
69 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_ATTR, HTML.STYLE_ATTR,
70 output.getAttributes().get(HTML.STYLE_ATTR));
71 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.STYLE_CLASS_ATTR, HTML.STYLE_CLASS_ATTR,
72 output.getAttributes().get(HTML.STYLE_CLASS_ATTR));
73
74 HtmlRendererUtils.renderHTMLAttribute(writer, HTML.ONCLICK_ATTR, HTML.ONCLICK_ATTR,
75 buildOnclickToggleFunction(facesContext,output));
76
77 writer.flush();
78 }
79
80 protected void renderOutputLinkEnd(FacesContext facesContext, UIComponent component)
81 throws IOException
82 {
83 ResponseWriter writer = facesContext.getResponseWriter();
84
85 writer.writeText("", null);
86 writer.endElement(HTML.ANCHOR_ELEM);
87 }
88
89 private String buildOnclickToggleFunction(FacesContext facesContext,
90 UIOutput output) throws IOException
91 {
92 ToggleLink toggleLink = (ToggleLink) output;
93 TogglePanel togglePanel = getParentTogglePanel(facesContext, toggleLink);
94 String[] componentsToToggle = toggleLink.getFor().split(",");
95 String idsToHide = getIdsToHide(facesContext, togglePanel);
96 StringBuffer idsToShow = new StringBuffer();
97 for (int i = 0; i < componentsToToggle.length; i++) {
98 String componentId = componentsToToggle[i].trim();
99 UIComponent componentToShow = toggleLink.findComponent(componentId);
100 if (componentToShow == null) {
101 Log log = LogFactory.getLog(ToggleLinkRenderer.class);
102 log.error("Unable to find component with id " + componentId);
103 continue;
104 }
105 if( idsToShow.length() > 0 )
106 idsToShow.append( ',' );
107 idsToShow.append( componentToShow.getClientId(facesContext) );
108 }
109
110 String outputOnclick = toggleLink.getOnclick();
111 StringBuffer onClick = new StringBuffer();
112 if(outputOnclick != null)
113 {
114 onClick.append("var cf = function(){");
115 onClick.append(outputOnclick);
116 onClick.append('}');
117 onClick.append(';');
118 onClick.append("var oamSF = function(){");
119 }
120
121 String onClickFocusClientId = toggleLink.getOnClickFocusId() != null ? toggleLink.findComponent(toggleLink.getOnClickFocusId()).getClientId(facesContext) : "";
122 onClick.append(getToggleJavascriptFunctionName(facesContext, toggleLink) + "('"+idsToShow+"','" + idsToHide + "','" + getHiddenFieldId(facesContext, togglePanel) + "','" + onClickFocusClientId + "');");
123
124 if (outputOnclick != null)
125 {
126 onClick.append('}');
127 onClick.append(';');
128 onClick.append("return (cf()==false)? false : oamSF();");
129 }
130
131 return onClick.toString();
132 }
133
134 public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
135 RendererUtils.checkParamValidity(context, component, ToggleLink.class);
136
137 ToggleLink toggleLink = (ToggleLink) component;
138 if(isDisabled(context, toggleLink))
139 return;
140
141 super.encodeEnd(context, component);
142 }
143
144 public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
145 RendererUtils.checkParamValidity(context, component, ToggleLink.class);
146
147 ToggleLink toggleLink = (ToggleLink) component;
148 if(isDisabled(context, toggleLink))
149 return;
150
151
152 super.encodeBegin(context, component);
153 }
154
155 private String getToggleJavascriptFunctionName(FacesContext context,ToggleLink toggleLink){
156 for(UIComponent component = toggleLink.getParent(); component != null; component = component.getParent())
157 if( component instanceof TogglePanel )
158 return TogglePanelRenderer.getToggleJavascriptFunctionName( context, (TogglePanel)component );
159
160 Log log = LogFactory.getLog(ToggleLinkRenderer.class);
161 log.error("The ToggleLink component with id " + toggleLink.getClientId( context )+" isn't enclosed in a togglePanel.");
162 return null;
163 }
164
165 private String getIdsToHide(FacesContext facesContext, TogglePanel togglePanel) {
166 StringBuffer idsToHide = new StringBuffer();
167 int idsToHideCount = 0;
168 for(Iterator it = togglePanel.getChildren().iterator(); it.hasNext(); ) {
169 UIComponent component = (UIComponent) it.next();
170 if ( TogglePanelRenderer.isHiddenWhenToggled( component ) ) {
171 if( idsToHideCount > 0 )
172 idsToHide.append( ',' );
173
174 idsToHide.append( component.getClientId( facesContext ) );
175 idsToHideCount++;
176 }
177 }
178
179 return idsToHide.toString();
180 }
181
182 private TogglePanel getParentTogglePanel(FacesContext facesContext, ToggleLink toggleLink) {
183 for(UIComponent component = toggleLink.getParent(); component != null; component = component.getParent()) {
184 if( component instanceof TogglePanel )
185 return (TogglePanel) component;
186 }
187
188 return null;
189 }
190
191 private String getHiddenFieldId(FacesContext context, TogglePanel togglePanel){
192 return togglePanel.getClientId(context) + "_hidden";
193 }
194
195 private boolean isDisabled(FacesContext facesContext, ToggleLink link) {
196 TogglePanel panel = getParentTogglePanel(facesContext, link);
197
198 return panel.isDisabled() || link.isDisabled() || !UserRoleUtils.isEnabledOnUserRole(link);
199 }
200 }