[
https://issues.apache.org/jira/browse/MYFACES-4430?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17504459#comment-17504459
]
glynn leininiger commented on MYFACES-4430:
-------------------------------------------
[https://github.com/apache/myfaces/pull/233]
Here is a PR for this. I can also create PRs for other branches if this is
approved.
> Separate "begin tag" code from "end tag" code for HtmlCheckboxRendererBase
> --------------------------------------------------------------------------
>
> Key: MYFACES-4430
> URL: https://issues.apache.org/jira/browse/MYFACES-4430
> Project: MyFaces Core
> Issue Type: Improvement
> Components: General
> Affects Versions: 2.3.9
> Reporter: glynn leininiger
> Priority: Major
>
> This ticket is very similar to MYFACES-4428, except it applies to
> HtmlSelectBooleanCheckbox.
> We're trying to implement a few JSF components that extend from the generic
> JSF components/renderers. This particular component is extending
> javax.faces.component.html.HtmlSelectBooleanCheckbox.
> On the renderer side, we're grabbing a handle to the default renderer of the
> component:
> {code:java}
> private static final String PARENT_FAMILY = "javax.faces.Checkbox";
> private static final String PARENT_RENDERER =
> "javax.faces.SelectBoolean";
> static final Renderer getWrappedRenderer(FacesContext context) {
> Renderer baseRenderer =
> context.getRenderKit().getRenderer(PARENT_FAMILY, PARENT_RENDERER);
> return baseRenderer;
> }{code}
> Then we're going to attempt to write out some new CSS classes for the
> component and leave the rest of everything alone:
> {code:java}
> @Override
> public void encodeBegin(FacesContext context, UIComponent component)
> throws IOException {
> Renderer baseRenderer = getWrappedRenderer(context);
> baseRenderer.encodeBegin(context, component);
> XXFaces.writeClasses(context, null, SF_FORM_CONTROL,
> BS_FORM_CONTROL);
> }
> @Override
> public void encodeEnd(FacesContext context, UIComponent component)
> throws IOException {
> Renderer baseRenderer = getWrappedRenderer(context);
> baseRenderer.encodeEnd(context, component);
> } {code}
>
> The problem is HtmlCheckboxRendererBase does not have an encodeBegin()
> method, instead it does all of the "Start tag" encoding in the encodeEnd()
> method. This makes it impossible to create custom components that wrap the
> functionality of the default render kit without extending myfaces renderers
> and breaks any chance cross-platform components.
> I propose adding this method in HtmlCheckboxRendererBase:
> {code:java}
> @Override
> public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
> throws IOException
> {
>
> org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext,
> uiComponent, null);
>
> Map<String, List<ClientBehavior>> behaviors = null;
> if (uiComponent instanceof ClientBehaviorHolder)
> {
> behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
> if (!behaviors.isEmpty())
> {
> ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext,
> facesContext.getResponseWriter());
> }
> }
>
> if (uiComponent instanceof UISelectBoolean)
> {
> Boolean value =
> org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanValue(
> uiComponent );
> boolean isChecked = value != null ? value.booleanValue() : false;
> renderCheckbox(facesContext, uiComponent, EXTERNAL_TRUE_VALUE,
> false,isChecked, true, null);
> //TODO: the selectBoolean is never disabled
> }
> else if (uiComponent instanceof UISelectMany)
> {
> // let the current impl do what it does in encodeEnd do nothing here
> just don't want exception
> // throw if it is this case
> log.finest("encodeBegin() doing nothing intentionally for
> UISelectMany");
> }
> else
> {
> throw new IllegalArgumentException("Unsupported component class "
> + uiComponent.getClass().getName());
> }
> }{code}
> and changing encodeEnd() to this following:
> {code:keyword}
> public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
> throws IOException
> {
> if (uiComponent instanceof UISelectBoolean)
> {
> ResponseWriter writer = facesContext.getResponseWriter();
> writer.endElement(HTML.INPUT_ELEM);
> }
> else if (uiComponent instanceof UISelectMany)
> {
> renderCheckboxList(facesContext, (UISelectMany) uiComponent);
> }
> else
> {
> throw new IllegalArgumentException("Unsupported component class " +
> uiComponent.getClass().getName());
> }
> }{code}
> and add this to the end of renderCheckbox()
> {code:java}
> if (uiComponent instanceof UISelectMany)
> {
> writer.endElement(HTML.INPUT_ELEM);
> }{code}
> These changes split the logic for encode end and begin for renderCheckbox()
> and leaves the rendering logic alone for renderCheckboxList(). Encode begin
> calls renderCheckbox and encodeEnd writes the end element. Encode begin does
> nothing for UISelectMany elements as it is implemented in encodeEnd.
> Im open to any feedback on this proposed change.
--
This message was sent by Atlassian Jira
(v8.20.1#820001)