1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.custom.ajaxchildcombobox;
20
21 import java.io.IOException;
22
23 import javax.el.MethodExpression;
24 import javax.faces.context.FacesContext;
25 import javax.faces.render.Renderer;
26
27 import org.apache.myfaces.component.html.ext.HtmlSelectOneMenu;
28 import org.apache.myfaces.custom.ajax.api.AjaxComponent;
29 import org.apache.myfaces.custom.ajax.api.AjaxRenderer;
30
31 /**
32 * Refreshes contents through an ajax call when the parent combo box's value is changed.
33 *
34 * This component is to be used in conjunction with a regular combo box or list box.
35 * When the selected value of the latter changes, it executes an ajax call to the
36 * specified method to refresh its contents based on the new selected value.
37 *
38 * @JSFComponent
39 * name = "s:ajaxChildComboBox"
40 * class = "org.apache.myfaces.custom.ajaxchildcombobox.AjaxChildComboBox"
41 * superClass = "org.apache.myfaces.custom.ajaxchildcombobox.AbstractAjaxChildComboBox"
42 * tagClass = "org.apache.myfaces.custom.ajaxchildcombobox.AjaxChildComboBoxTag"
43 * tagHandler = "org.apache.myfaces.custom.ajaxchildcombobox.AjaxChildComboBoxTagHandler"
44 *
45 * @author Sharath Reddy
46 */
47 public abstract class AbstractAjaxChildComboBox extends HtmlSelectOneMenu implements AjaxComponent
48 {
49 public static final String COMPONENT_TYPE = "org.apache.myfaces.AjaxChildComboBox";
50 public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.AjaxChildComboBox";
51
52 public AbstractAjaxChildComboBox()
53 {
54 super();
55 setRendererType(AbstractAjaxChildComboBox.DEFAULT_RENDERER_TYPE);
56 }
57
58 public void encodeAjax(FacesContext context)
59 throws IOException
60 {
61
62 if (context == null) throw new NullPointerException("context");
63 if (!isRendered()) return;
64 Renderer renderer = getRenderer(context);
65 if (renderer != null && renderer instanceof AjaxRenderer)
66 {
67 ((AjaxRenderer) renderer).encodeAjax(context, this);
68 }
69 }
70
71 public void decodeAjax(FacesContext context)
72 {
73 //Do Nothing
74 }
75
76 /**
77 * Method to call via ajax to reload the combo box
78 *
79 * @JSFProperty
80 * methodSignature = "java.lang.String"
81 * returnSignature = "javax.faces.model.SelectItem []"
82 * stateHolder = "true"
83 */
84 public abstract MethodExpression getAjaxSelectItemsMethod();
85
86 //
87
88 /**
89 * id of the parent combo box
90 *
91 * This is not a 'Parent' in terms of the component heirarchy;
92 * This is the component whose 'onchange' event triggers a refresh.
93 *
94 * @JSFProperty
95 * literalOnly="true"
96 */
97 public abstract String getParentComboBox();
98
99
100 /**
101 * We cannot verify that the result of converting the newly submitted value
102 * is <i>equal</i> to the value property of one of the child SelectItem
103 * objects. This is because the contents of the child combo box could have
104 * been reloaded by a change in the parent combo box.
105 *
106 * @see javax.faces.component.UIInput#validateValue(javax.faces.context.FacesContext, java.lang.Object)
107 */
108 protected void validateValue(FacesContext context, Object value)
109 {
110 return;
111 // selected value must match to one of the available options
112 /* if (!_SelectItemsUtil.matchValue(context, value, new _SelectItemsIterator(this), converter))
113 {
114 _MessageUtils.addErrorMessage(context, this, INVALID_MESSAGE_ID,
115 new Object[] {getId()});
116 setValid(false);
117 }*/
118 }
119 }