You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/03/18 17:59:55 UTC
svn commit: r1082972 - in
/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces:
custom/radio/ custom/radio/AbstractHtmlRadio.java
renderkit/html/ext/HtmlRadioRenderer.java
Author: lu4242
Date: Fri Mar 18 16:59:55 2011
New Revision: 1082972
URL: http://svn.apache.org/viewvc?rev=1082972&view=rev
Log:
TOMAHAWK-1551 f:ajax doesn't work in t:selectOneRadio layout="spread"
Added:
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/AbstractHtmlRadio.java
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlRadioRenderer.java
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/AbstractHtmlRadio.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/AbstractHtmlRadio.java?rev=1082972&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/AbstractHtmlRadio.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/radio/AbstractHtmlRadio.java Fri Mar 18 16:59:55 2011
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.radio;
+
+import javax.faces.component.UIComponentBase;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
+import org.apache.myfaces.component.UserRoleAware;
+
+/**
+ * This tag is used in conjunction with the extended selectOneRadio
+ * tag when the "spread" layout is selected. It specifies the
+ * position within the document that the radio button corresponding
+ * to a specific SelectItem should be rendered. All HTML pass-through
+ * attributes for this input are taken from the associated
+ * selectOneRadio.
+ *
+ * Unless otherwise specified, all attributes accept static values or EL expressions.
+ *
+ * @JSFComponent
+ * name = "t:radio"
+ * class = "org.apache.myfaces.custom.radio.HtmlRadio"
+ * tagClass = "org.apache.myfaces.custom.radio.HtmlRadioTag"
+ * @since 1.1.7
+ * @author Thomas Spiegl (latest modification by $Author: lu4242 $)
+ * @version $Revision: 691856 $ $Date: 2008-09-03 21:40:30 -0500 (mié, 03 sep 2008) $
+ */
+public abstract class AbstractHtmlRadio
+ extends UIComponentBase implements UserRoleAware
+{
+ //private static final Log log = LogFactory.getLog(HtmlRadio.class);
+
+ public static final String FOR_ATTR = "for".intern();
+ public static final String INDEX_ATTR = "index".intern();
+
+
+ public static final String COMPONENT_TYPE = "org.apache.myfaces.HtmlRadio";
+ public static final String COMPONENT_FAMILY = "org.apache.myfaces.Radio";
+ private static final String DEFAULT_RENDERER_TYPE = "org.apache.myfaces.Radio";
+
+ /**
+ * The id of the referenced extended selectOneRadio component.
+ * This value is resolved to the particular component using
+ * the standard UIComponent.findComponent() searching algorithm.
+ *
+ * @JSFProperty
+ * required="true"
+ */
+ public abstract String getFor();
+
+ /**
+ * The index of the corresponding SelectItem, where 0 represents the first SelectItem.
+ *
+ * @JSFProperty
+ * defaultValue = "Integer.MIN_VALUE"
+ * required="true"
+ */
+ public abstract int getIndex();
+
+ /**
+ * If this property is set to true, the id generated for the input html markup
+ * will be the logical id composed from the clientId of the associated
+ * selectOneRadio and the index of this component (for example 'myComp:2').
+ *
+ * <p>
+ * NOTE: This is provided only for backward compatibility with tomahawk 1.2.
+ * Activate this behavior will make client behaviors added to
+ * t:selectOneRadio like f:ajax or others fail, because the logical id
+ * has no counterpart in the component tree.
+ * </p>
+ *
+ * @return
+ */
+ @JSFProperty(defaultValue="false")
+ public abstract boolean isRenderLogicalId();
+}
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlRadioRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlRadioRenderer.java?rev=1082972&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlRadioRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/renderkit/html/ext/HtmlRadioRenderer.java Fri Mar 18 16:59:55 2011
@@ -0,0 +1,325 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.renderkit.html.ext;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.FacesException;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.component.UINamingContainer;
+import javax.faces.component.UISelectOne;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+import javax.faces.model.SelectItem;
+
+import org.apache.myfaces.component.UserRoleUtils;
+import org.apache.myfaces.custom.radio.HtmlRadio;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRadioRendererBase;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
+
+
+/**
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "org.apache.myfaces.Radio"
+ * type = "org.apache.myfaces.Radio"
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.SelectOne"
+ * type = "org.apache.myfaces.Radio"
+ *
+ * @author Manfred Geiler (latest modification by $Author: lu4242 $)
+ * @author Thomas Spiegl
+ * @version $Revision: 685654 $ $Date: 2008-08-13 14:57:50 -0500 (mié, 13 ago 2008) $
+ */
+public class HtmlRadioRenderer
+ extends HtmlRadioRendererBase
+{
+ //private static final Log log = LogFactory.getLog(HtmlRadioRenderer.class);
+
+ private static final String LAYOUT_SPREAD = "spread";
+
+ public void encodeEnd(FacesContext context, UIComponent component) throws IOException
+ {
+ if (context == null) throw new NullPointerException("context");
+ if (component == null) throw new NullPointerException("component");
+
+ if (component instanceof HtmlRadio)
+ {
+ renderRadio(context, (HtmlRadio)component);
+ }
+ else if (HtmlRendererUtils.isDisplayValueOnly(component))
+ {
+ HtmlRendererUtils.renderDisplayValueOnlyForSelects(context, component);
+ }
+ else if (component instanceof UISelectOne)
+ {
+ String layout = getLayout(component);
+ if (layout != null && layout.equals(LAYOUT_SPREAD))
+ {
+ return; //radio inputs are rendered by spread radio components
+ }
+ else
+ {
+ super.encodeEnd(context, component);
+ }
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unsupported component class " + component.getClass().getName());
+ }
+ }
+
+ protected void renderRadio(FacesContext facesContext, HtmlRadio radio) throws IOException
+ {
+ String forAttr = radio.getFor();
+ if (forAttr == null)
+ {
+ throw new IllegalStateException("mandatory attribute 'for'");
+ }
+ int index = radio.getIndex();
+ if (index < 0)
+ {
+ throw new IllegalStateException("positive index must be given");
+ }
+
+ UIComponent uiComponent = radio.findComponent(forAttr);
+ if (uiComponent == null)
+ {
+ throw new IllegalStateException("Could not find component '" + forAttr + "' (calling findComponent on component '" + radio.getClientId(facesContext) + "')");
+ }
+ if (!(uiComponent instanceof UISelectOne))
+ {
+ throw new IllegalStateException("UISelectOne expected");
+ }
+
+ UISelectOne uiSelectOne = (UISelectOne)uiComponent;
+ Converter converter;
+ List selectItemList = RendererUtils.getSelectItemList(uiSelectOne);
+ if (index >= selectItemList.size())
+ {
+ throw new IndexOutOfBoundsException("index " + index + " >= " + selectItemList.size());
+ }
+
+ try
+ {
+ converter = RendererUtils.findUIOutputConverter(facesContext, uiSelectOne);
+ }
+ catch (FacesException e)
+ {
+ converter = null;
+ }
+
+ Object currentValue = RendererUtils.getObjectValue(uiSelectOne);
+ currentValue
+ = RendererUtils.getConvertedStringValue(facesContext, uiSelectOne,
+ converter, currentValue);
+ SelectItem selectItem = (SelectItem)selectItemList.get(index);
+ String itemStrValue
+ = RendererUtils.getConvertedStringValue(facesContext, uiSelectOne,
+ converter,
+ selectItem.getValue());
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ //writer.startElement(HTML.LABEL_ELEM, uiSelectOne);
+
+ //renderRadio(facesContext,
+ // uiSelectOne,
+ // itemStrValue,
+ // selectItem.getLabel(),
+ // selectItem.isDisabled(),
+ // itemStrValue.equals(currentValue), false);
+ //writer.endElement(HTML.LABEL_ELEM);
+
+ //Render the radio component
+ String itemId = renderRadio(
+ facesContext,
+ uiSelectOne,
+ radio,
+ itemStrValue,
+ selectItem.isDisabled(),
+ itemStrValue.equals(currentValue),
+ false,
+ index);
+
+ //Render the
+ // label element after the input
+ boolean componentDisabled = isDisabled(facesContext, uiSelectOne);
+ boolean itemDisabled = selectItem.isDisabled();
+ boolean disabled = (componentDisabled || itemDisabled);
+
+ HtmlRendererUtils.renderLabel(writer, uiSelectOne, itemId, selectItem, disabled);
+ }
+
+ protected String renderRadio(
+ FacesContext facesContext,
+ UISelectOne uiComponent, HtmlRadio radio,
+ String value, boolean disabled,
+ boolean checked, boolean renderId, Integer itemNum)
+ throws IOException
+ {
+ String clientId = uiComponent.getClientId(facesContext);
+
+ String itemId = radio.isRenderLogicalId() ?
+ clientId + UINamingContainer.getSeparatorChar(facesContext) + itemNum :
+ radio.getClientId(facesContext);
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+
+ writer.startElement(HTML.INPUT_ELEM, uiComponent);
+
+ // Force id rendering because it is necessary for the label
+ // and for @this work correctly
+ writer.writeAttribute(HTML.ID_ATTR, itemId, null);
+
+ writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
+ writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
+
+
+ if (disabled)
+ {
+ writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
+ }
+
+ if (checked)
+ {
+ writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
+ }
+
+ if (value != null)
+ {
+ writer.writeAttribute(HTML.VALUE_ATTR, value, null);
+ }
+
+ Map<String, List<ClientBehavior>> behaviors = null;
+ if (uiComponent instanceof ClientBehaviorHolder
+ && JavascriptUtils.isJavascriptAllowed(facesContext
+ .getExternalContext()))
+ {
+ behaviors = ((ClientBehaviorHolder) uiComponent)
+ .getClientBehaviors();
+
+ HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, itemId, behaviors);
+ HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext,writer, uiComponent, itemId, behaviors);
+ HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, itemId, behaviors);
+ HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
+ }
+ else
+ {
+ HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
+ }
+
+ if (isDisabled(facesContext, uiComponent))
+ {
+ writer.writeAttribute(
+ org.apache.myfaces.shared_tomahawk.renderkit.html.HTML.DISABLED_ATTR,
+ Boolean.TRUE, null);
+ }
+
+ writer.endElement(HTML.INPUT_ELEM);
+
+ return itemId;
+ }
+
+ protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
+ {
+ if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
+ {
+ return true;
+ }
+ else
+ {
+ return super.isDisabled(facesContext, uiComponent);
+ }
+ }
+
+
+ public void decode(FacesContext facesContext, UIComponent uiComponent)
+ {
+ if (uiComponent instanceof HtmlRadio)
+ {
+ HtmlRadio radio = (HtmlRadio) uiComponent;
+ String forAttr = radio.getFor();
+ if (forAttr == null)
+ {
+ throw new IllegalStateException("mandatory attribute 'for'");
+ }
+ int index = radio.getIndex();
+ if (index < 0)
+ {
+ throw new IllegalStateException("positive index must be given");
+ }
+
+ UIComponent uiSelectOne = radio.findComponent(forAttr);
+ if (uiSelectOne == null)
+ {
+ throw new IllegalStateException("Could not find component '" + forAttr + "' (calling findComponent on component '" + radio.getClientId(facesContext) + "')");
+ }
+ if (!(uiSelectOne instanceof UISelectOne))
+ {
+ throw new IllegalStateException("UISelectOne expected");
+ }
+
+ if (uiSelectOne instanceof ClientBehaviorHolder) {
+ ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) uiSelectOne;
+
+ Map<String, List<ClientBehavior>> clientBehaviors =
+ clientBehaviorHolder.getClientBehaviors();
+
+ if (clientBehaviors != null && !clientBehaviors.isEmpty()) {
+ Map<String, String> paramMap = facesContext.getExternalContext().
+ getRequestParameterMap();
+
+ String behaviorEventName = paramMap.get("javax.faces.behavior.event");
+
+ if (behaviorEventName != null) {
+ List<ClientBehavior> clientBehaviorList = clientBehaviors.get(behaviorEventName);
+
+ if (clientBehaviorList != null && !clientBehaviorList.isEmpty()) {
+ String clientId = paramMap.get("javax.faces.source");
+
+ if (radio.getClientId().equals(clientId)) {
+ for (ClientBehavior clientBehavior : clientBehaviorList) {
+ clientBehavior.decode(facesContext, radio);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ super.decode(facesContext, uiComponent);
+ }
+ }
+
+}