在 JSF 中将单选按钮拆分为列

编程入门 行业动态 更新时间:2024-10-26 04:20:03
本文介绍了在 JSF 中将单选按钮拆分为列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

当我使用 h:selectOneRadio 并将列表中的值列表提供为整个单选按钮部分显示为一个完整的列表.我需要将它排列成 3 列.我试过给

When I am using h:selectOneRadio and supplying the list of values in a list as the entire radio button section is exposed as a single unbroken list. I need to arrange it in 3 columns. I have tried giving

<h:panelGrid id="radioGrid" columns="3"> <h:selectOneRadio id="radio1" value="#{bean.var}"> <f:selectItems id="rval" value="#{bean.list}"/> </h:selectOneRadio> </h:panelGrid>

但是渲染部分没有区别.它没有分解成列.我做错了什么?

But there is no difference in the rendered section. Its not broken up into columns. What am I doing wrong?

推荐答案

我已经修改了 Damo 给出的代码,以使用 h:selectOneRadio 而不是 h:selectManycheckbox.为了让它工作,你需要在你的 faces-config.xml 中注册它,使用:

I've adapted the code given by Damo, to work with h:selectOneRadio instead of h:selectManycheckbox. To get it working you will need to register it in your faces-config.xml, with:

<render-kit> <renderer> <component-family>javax.faces.SelectOne</component-family> <renderer-type>javax.faces.Radio</renderer-type> <renderer-class>testponents.SelectOneRadiobuttonListRenderer</renderer-class> </renderer> </render-kit>

要编译它,您还需要 JSF 实现(通常在您的应用服务器中的某种 jsf-impl.jar 中找到).

To compile it, you will also need the JSF implementation (typically found in some sort of jsf-impl.jar in you app server).

代码输出 div 中的单选按钮,而不是表格.然后,您可以使用 CSS 为它们设置任何您喜欢的样式.我建议为 checkboxDiv 和内部 div 提供固定宽度,然后让内部 div 显示为内联块:

The code outputs the radiobuttons in divs, instead of a table. You can then use CSS to style them however you would like. I would suggest giving a fixed width to the checkboxDiv and inner divs, and then having the inner divs display as inline blocks:

div.radioButtonDiv{ width: 300px; } div.radioButtonDiv div{ display: inline-block; width: 100px; }

这应该给出您正在寻找的 3 列

Which should give the 3 columns you are looking for

代码:

package testponents; import java.io.IOException; import java.lang.reflect.Array; import java.util.Collection; import java.util.Iterator; import javax.facesponent.NamingContainer; import javax.facesponent.UIComponent; import javax.facesponent.UISelectMany; import javax.facesponent.UISelectOne; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.model.SelectItem; import com.sun.faces.renderkit.RenderKitUtils; import com.sun.faces.renderkit.html_basic.MenuRenderer; import com.sun.faces.util.MessageUtils; import com.sun.faces.util.Util; /** * This component ensures that h:selectOneRadio doesn't get rendered using * tables. It is adapted from the code at: * www.blog.locuslive/?p=15 * * To register it for use, place the following in your faces config: * * <render-kit> * <renderer> * <component-family>javax.faces.SelectOne</component-family> * <renderer-type>javax.faces.Radio</renderer-type> * <renderer-class>testponents.SelectOneRadiobuttonListRenderer</renderer-class> * </renderer> * </render-kit> * * The original comment is below: * * ----------------------------------------------------------------------------- * * This is a custom renderer for the h:selectManycheckbox * It is intended to bypass the incredibly sucky table based layout used * by the standard component. * * This layout uses an enclosing div with divs for each input. * This gives a default layout similar to a vertical layout * The layout can then be controlled by css * * This renderer assigns an class of "checkboxDiv" to the enclosing div * The class and styleClass attributes are then applied to the internal * divs that house the inputs * * The following attributes are ignored as they are no longer required when using CSS: * - pageDirection * - border * * Note that I am not supporting optionGroups at this stage. They would be relatively * easy to implement with another enclosing div * * @author damianharvey * */ public class SelectOneRadiobuttonListRenderer extends MenuRenderer { public void encodeEnd(FacesContext context, UIComponent component) throws IOException { if (context == null) { throw new NullPointerException( MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "context")); } if (component == null) { throw new NullPointerException( MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "component")); } // suppress rendering if "rendered" property on the component is // false. if (!component.isRendered()) { return; } ResponseWriter writer = context.getResponseWriter(); assert(writer != null); writer.startElement("div", component); if (shouldWriteIdAttribute(component)) { writeIdAttributeIfNecessary(context, writer, component); } writer.writeAttribute("class", "radioButtonDiv", "class"); Iterator items = RenderKitUtils.getSelectItems(context, component).iterator(); SelectItem curItem = null; int idx = -1; while (items.hasNext()) { curItem = (SelectItem) items.next(); idx++; renderOption(context, component, curItem, idx); } writer.endElement("div"); } protected void renderOption(FacesContext context, UIComponent component, SelectItem curItem, int itemNumber) throws IOException { ResponseWriter writer = context.getResponseWriter(); assert(writer != null); // disable the check box if the attribute is set. String labelClass = null; boolean componentDisabled = UtilponentIsDisabled(component); if (componentDisabled || curItem.isDisabled()) { labelClass = (String) component. getAttributes().get("disabledClass"); } else { labelClass = (String) component. getAttributes().get("enabledClass"); } writer.startElement("div", component); //Added by DAMIAN String styleClass = (String) component.getAttributes().get("styleClass"); String style = (String) component.getAttributes().get("style"); if (styleClass != null) { writer.writeAttribute("class", styleClass, "class"); } if (style != null) { writer.writeAttribute("style", style, "style"); } writer.startElement("input", component); writer.writeAttribute("name", component.getClientId(context), "clientId"); String idString = component.getClientId(context) + NamingContainer.SEPARATOR_CHAR + Integer.toString(itemNumber); writer.writeAttribute("id", idString, "id"); String valueString = getFormattedValue(context, component, curItem.getValue()); writer.writeAttribute("value", valueString, "value"); writer.writeAttribute("type", "radio", null); Object submittedValues[] = getSubmittedSelectedValues(context, component); boolean isSelected; Class type = String.class; Object valuesArray = null; Object itemValue = null; if (submittedValues != null) { valuesArray = submittedValues; itemValue = valueString; } else { valuesArray = getCurrentSelectedValues(context, component); itemValue = curItem.getValue(); } if (valuesArray != null) { type = valuesArray.getClass().getComponentType(); } // I don't know what this does, but it doens't compile. Commenting it // out doesn't seem to hurt // Map<String, Object> requestMap = context.getExternalContext().getRequestMap(); // requestMap.put(ConverterPropertyEditorBase.TARGET_COMPONENT_ATTRIBUTE_NAME, // component); Object newValue = context.getApplication().getExpressionFactory(). coerceToType(itemValue, type); isSelected = isSelected(newValue, valuesArray); if (isSelected) { writer.writeAttribute(getSelectedTextString(), Boolean.TRUE, null); } // Don't render the disabled attribute twice if the 'parent' // component is already marked disabled. if (!UtilponentIsDisabled(component)) { if (curItem.isDisabled()) { writer.writeAttribute("disabled", true, "disabled"); } } // Apply HTML 4.x attributes specified on UISelectMany component to all // items in the list except styleClass and style which are rendered as // attributes of outer most table. RenderKitUtils.renderPassThruAttributes(writer, component, new String[] { "border", "style" }); RenderKitUtils.renderXHTMLStyleBooleanAttributes(writer, component); writer.endElement("input"); writer.startElement("label", component); writer.writeAttribute("for", idString, "for"); // if enabledClass or disabledClass attributes are specified, apply // it on the label. if (labelClass != null) { writer.writeAttribute("class", labelClass, "labelClass"); } String itemLabel = curItem.getLabel(); if (itemLabel != null) { writer.writeText(" ", component, null); if (!curItem.isEscape()) { // It seems the ResponseWriter API should // have a writeText() with a boolean property // to determine if it content written should // be escaped or not. writer.write(itemLabel); } else { writer.writeText(itemLabel, component, "label"); } } writer.endElement("label"); writer.endElement("div"); //Added by Damian } // ------------------------------------------------- Package Private Methods String getSelectedTextString() { return "checked"; } /** For some odd reason this is a private method in the MenuRenderer superclass * * @param context * @param component * @return */ private Object getCurrentSelectedValues(FacesContext context, UIComponent component) { if (component instanceof UISelectMany) { UISelectMany select = (UISelectMany) component; Object value = select.getValue(); if (value instanceof Collection) { Collection<?> list = (Collection) value; int size = list.size(); if (size > 0) { // get the type of the first element - Should // we assume that all elements of the List are // the same type? return list.toArray((Object[]) Array.newInstance(list.iterator().next().getClass(), size)); } else { return ((Collection) value).toArray(); } } else if (value != null && !value.getClass().isArray()) { logger.warning("The UISelectMany value should be an array or a collection type, the actual type is " + value.getClass().getName()); } return value; } UISelectOne select = (UISelectOne) component; Object returnObject; if (null != (returnObject = select.getValue())) { Object ret = Array.newInstance(returnObject.getClass(), 1); Array.set(ret, 0, returnObject); return ret; } return null; } /** For some odd reason this is a private method in the MenuRenderer superclass * * @param context * @param component * @return */ private Object[] getSubmittedSelectedValues(FacesContext context, UIComponent component) { if (component instanceof UISelectMany) { UISelectMany select = (UISelectMany) component; return (Object[]) select.getSubmittedValue(); } UISelectOne select = (UISelectOne) component; Object returnObject; if (null != (returnObject = select.getSubmittedValue())) { return new Object[] { returnObject }; } return null; } /** For some odd reason this is a private method in the MenuRenderer superclass * * @param itemValue * @param valueArray * @return */ private boolean isSelected(Object itemValue, Object valueArray) { if (null != valueArray) { if (!valueArray.getClass().isArray()) { logger.warning("valueArray is not an array, the actual type is " + valueArray.getClass()); return valueArray.equals(itemValue); } int len = Array.getLength(valueArray); for (int i = 0; i < len; i++) { Object value = Array.get(valueArray, i); if (value == null) { if (itemValue == null) { return true; } } else if (value.equals(itemValue)) { return true; } } } return false; } }

更多推荐

在 JSF 中将单选按钮拆分为列

本文发布于:2023-07-09 14:59:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1087148.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:中将   单选   按钮   JSF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!