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.inputAjax;
20
21 import java.io.IOException;
22 import java.util.Collection;
23 import java.util.Iterator;
24 import java.util.Map;
25
26 import javax.faces.context.FacesContext;
27 import javax.faces.render.Renderer;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.myfaces.component.html.ext.HtmlSelectManyCheckbox;
32 import org.apache.myfaces.custom.ajax.AjaxCallbacks;
33 import org.apache.myfaces.custom.ajax.api.AjaxRenderer;
34 import org.apache.myfaces.custom.ajax.api.DeprecatedAjaxComponent;
35
36 /**
37 * Extends standard selectManyCheckbox allowing for dynamic ajax submitting.
38 *
39 * Current limitations
40 * - Bound value must be a Collection of Strings!
41 *
42 * @JSFComponent
43 * name = "s:selectManyCheckboxAjax"
44 * class = "org.apache.myfaces.custom.inputAjax.HtmlSelectManyCheckboxAjax"
45 * tagClass = "org.apache.myfaces.custom.inputAjax.HtmlSelectManyCheckboxAjaxTag"
46 *
47 * @author Travis Reeder (latest modification by $Author: lu4242 $)
48 * @version $Revision: 663481 $ $Date: 2008-06-05 02:00:34 -0500 (Thu, 05 Jun 2008) $
49 */
50 public abstract class AbstractHtmlSelectManyCheckboxAjax extends HtmlSelectManyCheckbox implements DeprecatedAjaxComponent, AjaxCallbacks
51 {
52 private static final Log log = LogFactory.getLog(AbstractHtmlSelectManyCheckboxAjax.class);
53 public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlSelectManyCheckboxAjax";
54 public static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.CheckboxAjax";
55
56 public AbstractHtmlSelectManyCheckboxAjax()
57 {
58 super();
59 setRendererType(DEFAULT_RENDERER_TYPE);
60 }
61
62 /**
63 * Decode ajax request and apply value changes
64 *
65 * @param context
66 */
67 public void decodeAjax(FacesContext context)
68 {
69 log.debug("entering HtmlSelectManyCheckboxAjax.decodeAjax");
70
71 // this requires special handling
72 // should maybe put the end collection, "c" into the EditableValueHolder as request params: ((EditableValueHolder) component).setSubmittedValue(reqValues);
73 Map requestParams = context.getExternalContext().getRequestParameterMap();
74
75 String elname = (String) requestParams.get("elname");
76 String elvalue = (String) requestParams.get("elvalue");
77 String checkedStr = (String) requestParams.get("checked");
78 //System.out.println("checkedStr: " + checkedStr);
79 boolean checked = Boolean.valueOf(checkedStr).booleanValue();
80 //System.out.println("checked: " + checked);
81 // now apply this to the
82 Object valOb = this.getValue();
83 //System.out.println("valOb: " + valOb);
84 if(valOb instanceof Collection){
85 // then all good
86 //System.out.println("valob is collection");
87 log.debug("valOb is collection");
88 Collection c = (Collection) valOb;
89 updateChosenValue(c, elname, elvalue, checked);
90 } else {
91 log.error("Invalid chosen values type in HtmlSelectManyCheckbox");
92 }
93
94 // now the rest of the lifecycle
95 processValidators(context);
96 processUpdates(context);
97 //context.getViewRoot().processApplication(context);
98 }
99 /**
100 * Will find the chosen value in the chosenValues list and update set or unset accordingly.
101 *
102 * @param c
103 * @param elname
104 * @param elvalue
105 * @param checked
106 */
107 public void updateChosenValue(Collection c, String elname, String elvalue, boolean checked) {
108 boolean found = false;
109 if (c != null) {
110 Iterator iter = c.iterator();
111 while (iter.hasNext())
112 {
113 String value = (String) iter.next();
114 if (value.equals(elvalue)) {
115 found = true;
116 if (!checked) {
117 // then remove
118 log.debug("Removing elvalue: " + elvalue);
119 iter.remove();
120 } else {
121 // would this ever happen?
122 }
123 break;
124 }
125 }
126 if (!found && checked) {
127 // then add it
128 log.debug("Adding elvalue: " + elvalue);
129 c.add(elvalue);
130 }
131 } else {
132 log.error("LIST IS NULL!!!");
133 }
134 }
135
136 public void encodeAjax(FacesContext context) throws IOException
137 {
138 //log.debug("encodeAjax in HtmlSelectManyCheckbox");
139 if (context == null) throw new NullPointerException("context");
140 if (!isRendered()) return;
141 Renderer renderer = getRenderer(context);
142
143 if (renderer != null && renderer instanceof AjaxRenderer)
144 {
145 ((AjaxRenderer) renderer).encodeAjax(context, this);
146
147 }
148 }
149
150 /**
151 * Javascript method to call on successful ajax update
152 *
153 * @JSFProperty
154 */
155 public abstract String getOnSuccess();
156
157 /**
158 * Javascript method to call on failed ajax update
159 *
160 * @JSFProperty
161 */
162 public abstract String getOnFailure();
163
164 /**
165 * Javascript method to call on start of ajax update
166 *
167 * @JSFProperty
168 */
169 public abstract String getOnStart();
170
171 }