1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.ajaxchildcombobox;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.myfaces.custom.ajax.api.AjaxRenderer;
24 import org.apache.myfaces.custom.dojo.DojoConfig;
25 import org.apache.myfaces.custom.dojo.DojoUtils;
26 import org.apache.myfaces.renderkit.html.ext.HtmlMenuRenderer;
27 import org.apache.myfaces.renderkit.html.util.AddResource;
28 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
29 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
30 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
31 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
32 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
33
34 import javax.faces.component.UIComponent;
35 import javax.faces.component.UINamingContainer;
36 import javax.faces.context.FacesContext;
37 import javax.faces.context.ResponseWriter;
38 import javax.faces.el.MethodBinding;
39 import javax.faces.model.SelectItem;
40 import javax.servlet.ServletResponse;
41 import java.io.IOException;
42 import java.io.PrintWriter;
43
44
45
46
47
48
49
50
51
52
53
54 public class HtmlAjaxChildComboBoxRenderer extends HtmlMenuRenderer implements AjaxRenderer
55 {
56 private static final String BEGIN_OPTION = "<option>";
57 private static final String END_OPTION = "</option>";
58 private static final String BEGIN_OPTION_TEXT = "<optionText>";
59 private static final String END_OPTION_TEXT = "</optionText>";
60 private static final String BEGIN_OPTION_VALUE = "<optionValue>";
61 private static final String END_OPTION_VALUE = "</optionValue>";
62
63 public static final int DEFAULT_MAX_SUGGESTED_ITEMS = 200;
64
65 private static Log log = LogFactory.getLog(HtmlAjaxChildComboBoxRenderer.class);
66
67
68
69
70 private void encodeJavascript(FacesContext context, UIComponent component)
71 throws IOException
72 {
73 String javascriptLocation = (String) component.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
74 DojoUtils.addMainInclude(context, component, javascriptLocation, new DojoConfig());
75 DojoUtils.addRequire(context, component, "dojo.event.*");
76
77
78
79 AddResource addResource = AddResourceFactory.getInstance(context);
80
81 addResource.addJavaScriptAtPosition(context,
82 AddResource.HEADER_BEGIN, AjaxChildComboBox.class, "javascript/ajaxChildComboBox.js");
83 }
84
85 public void encodeEnd(FacesContext context, UIComponent component) throws IOException
86 {
87 RendererUtils.checkParamValidity(context, component, AjaxChildComboBox.class);
88
89 AjaxChildComboBox childComboBox = (AjaxChildComboBox) component;
90
91 super.encodeEnd(context, component);
92
93 String clientId = component.getClientId(context);
94
95 UIComponent parentComboBox = this.getParentComboBox(childComboBox);
96 if (parentComboBox == null)
97 {
98 log.error("Could not find parent combo box for AjaxChildComboBox " +
99 childComboBox.getClientId(context));
100 return;
101 }
102
103 encodeJavascript(context, component);
104
105 ResponseWriter writer = context.getResponseWriter();
106
107
108
109 writer.startElement(HTML.SCRIPT_ELEM, component);
110 writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
111
112 writer.write("var parentCombo = document.getElementById('" +
113 parentComboBox.getClientId(context) + "');");
114 HtmlRendererUtils.writePrettyLineSeparator(context);
115 writer.write("dojo.event.connect(parentCombo, 'onchange', function(evt) { ");
116 HtmlRendererUtils.writePrettyLineSeparator(context);
117 writer.write("var targetElement = evt.target;");
118 writer.write("var targetValue = targetElement.options[targetElement.selectedIndex].value;");
119 HtmlRendererUtils.writePrettyLineSeparator(context);
120 writer.write("reloadChildComboBox('" + clientId + "', targetValue);");
121 HtmlRendererUtils.writePrettyLineSeparator(context);
122 writer.write("});");
123 writer.endElement(HTML.SCRIPT_ELEM);
124
125 }
126
127
128
129 public void encodeAjax(FacesContext context, UIComponent uiComponent)
130 throws IOException
131 {
132
133 String parentValue = (String) context.getExternalContext().
134 getRequestParameterMap().get("parentValue");
135
136 ServletResponse response = (ServletResponse) context.getExternalContext().getResponse();
137 PrintWriter writer = response.getWriter();
138
139 StringBuffer xml = new StringBuffer();
140
141 MethodBinding mb = ((AjaxChildComboBox) uiComponent).getAjaxSelectItemsMethod();
142 SelectItem[] options = (SelectItem[])
143 mb.invoke(context, new Object[]{parentValue});
144
145 xml.append("<?xml version=\"1.0\"?>\n");
146 xml.append("<response>\n");
147 for (int i = 0; i < options.length; i++)
148 {
149 xml.append(BEGIN_OPTION);
150 xml.append(BEGIN_OPTION_TEXT).append(options[i].getLabel()).append(END_OPTION_TEXT);
151 xml.append(BEGIN_OPTION_VALUE).append(options[i].getValue()).append(END_OPTION_VALUE);
152 xml.append(END_OPTION);
153 }
154 xml.append("</response>");
155
156 writer.write(xml.toString());
157
158 }
159
160 private UIComponent getParentComboBox(AjaxChildComboBox comboBox)
161 {
162 String parentId = comboBox.getParentComboBox();
163
164 UIComponent parentComboBox = comboBox.findComponent(parentId);
165 if (parentComboBox != null)
166 {
167 return parentComboBox;
168 }
169
170
171 return comboBox.findComponent(UINamingContainer.SEPARATOR_CHAR + parentId);
172 }
173 }