001/* 002 * (C) Copyright 2014 JBoss RichFaces and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Anahide Tchertchian 016 */ 017 018package org.nuxeo.ecm.platform.ui.web.component.radio; 019 020import java.io.IOException; 021 022import javax.faces.component.UIComponent; 023import javax.faces.component.html.HtmlSelectOneRadio; 024import javax.faces.context.FacesContext; 025import javax.faces.context.ResponseWriter; 026 027import org.richfaces.component.util.InputUtils; 028import org.richfaces.renderkit.RenderKitUtils; 029import org.richfaces.renderkit.RendererBase; 030 031/** 032 * Renderer for a single radio button, given a target original radio component and index for original button attributes 033 * retrieval. 034 * 035 * @since 6.0 036 */ 037public class SingleRadioRenderer extends RendererBase { 038 039 public static final String RENDERER_TYPE = SingleRadioRenderer.class.getName(); 040 041 private String convertToString(Object obj) { 042 return (obj == null ? "" : obj.toString()); 043 } 044 045 @Override 046 protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent _component) throws IOException { 047 UIRadio component = (UIRadio) _component; 048 java.lang.String clientId = component.getClientId(context); 049 final UIComponent targetComponent = getUtils().findComponentFor(component, component.getFor()); 050 final javax.faces.model.SelectItem item = component.getSelectItem(context, targetComponent); 051 boolean checked = false; 052 if (targetComponent instanceof javax.faces.component.UIOutput) { 053 final Object currentValue = ((javax.faces.component.UIOutput) targetComponent).getValue(); 054 final Object itemValue = item.getValue(); 055 checked = itemValue == null ? currentValue == null : itemValue.equals(currentValue); 056 } 057 058 writer.startElement("input", component); 059 writer.writeAttribute("id", clientId, "id"); 060 writer.writeAttribute("name", getUtils().clientId(context, targetComponent), "name"); 061 writer.writeAttribute("type", "radio", "type"); 062 writer.writeAttribute("value", InputUtils.getConvertedStringValue(context, targetComponent, item.getValue()), 063 "value"); 064 if (checked) { 065 writer.writeAttribute("checked", "checked", "checked"); 066 } 067 if (isDisabled(targetComponent) || isReadonly(targetComponent)) { 068 writer.writeAttribute("disabled", "disabled", "disabled"); 069 } 070 071 String targetOnchange = null; 072 if (targetComponent != null) { 073 targetOnchange = convertToString(RenderKitUtils.getAttributeAndBehaviorsValue(context, targetComponent, 074 RenderKitUtils.attributes().generic("onchange", "onchange", "change", "valueChange").first())); 075 } 076 String onchange = convertToString(RenderKitUtils.getAttributeAndBehaviorsValue(context, component, 077 RenderKitUtils.attributes().generic("onchange", "onchange", "change", "valueChange").first())); 078 if (targetOnchange != null && !targetOnchange.trim().isEmpty()) { 079 onchange = onchange == null ? targetOnchange : targetOnchange + ";" + onchange; 080 } 081 if (onchange != null && onchange.trim().length() > 0) { 082 writer.writeAttribute("onchange", onchange, "onchange"); 083 } 084 getUtils().encodeAttributesFromArray( 085 context, 086 component, 087 new String[] { "accept", "accesskey", "align", "alt", "checked", "dir", "disabled", "lang", 088 "maxlength", "onblur", "onclick", "ondblclick", "onfocus", "onkeydown", "onkeypress", 089 "onkeyup", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onselect", 090 "readonly", "size", "src", "style", "tabindex", "title", "usemap", "xml:lang" }); 091 092 writer.endElement("input"); 093 writer.startElement("label", component); 094 writer.writeAttribute("for", clientId, "for"); 095 writer.writeText(convertToString(item.getLabel()), null); 096 writer.endElement("label"); 097 } 098 099 @Override 100 protected Class<? extends UIComponent> getComponentClass() { 101 return UIRadio.class; 102 } 103 104 private boolean isDisabled(UIComponent targetComponent) { 105 if (targetComponent instanceof HtmlSelectOneRadio) { 106 return ((HtmlSelectOneRadio) targetComponent).isDisabled(); 107 } else { 108 final Object disabled = targetComponent.getAttributes().get("disabled"); 109 return Boolean.TRUE.equals(disabled); 110 } 111 } 112 113 private boolean isReadonly(UIComponent targetComponent) { 114 if (targetComponent instanceof HtmlSelectOneRadio) { 115 return ((HtmlSelectOneRadio) targetComponent).isReadonly(); 116 } else { 117 final Object readonly = targetComponent.getAttributes().get("readonly"); 118 return Boolean.TRUE.equals(readonly); 119 } 120 } 121}