JSF selectOneMenu: extending MenuRenderer for displaying a plain text when there is one item -
i want display like
<span ...>an item</span>
instead of
<select ...> <option ...>an item</option> </select>
when menu's plaintext option set true , there 1 selectitem inside:
<h:selectonemenu plaintext="true" ...> <f:selectitems ... /> <!-- contains 1 item --> </h:selectonemenu>
i've tried creating custom renderer extended menurenderer, code not appendable. can it? thanks.
we need extend com.sun.faces.renderkit.html_basic.menurenderer , override renderselect , renderoption methods. code copied parent. private boolean plaintext true when need display element span. @ begginning of renderselect add this:
plaintext = "true".equalsignorecase((string) component.getattributes().get("plaintext")); if (plaintext) { selectitemsiterator<selectitem> items = renderkitutils.getselectitems(context, component); items.next(); plaintext = !items.hasnext(); }
it first checks if plaintext option set true, checks if there selectitem. think part can optimised. instead of
writer.startelement("select", component);
we should write
if (plaintext) { writer.startelement("span", component); } else { writer.startelement("select", component); }
and same writer.endelement.
in middle of renderoption add code print out option without tags , leave.
if (plaintext) { if (curitem.isescape()) { string label = curitem.getlabel(); if (label == null) { label = valuestring; } writer.writetext(label, component, "label"); } else { writer.write(curitem.getlabel()); } writer.writetext("\n", component, null); return true; }
all code:
import com.sun.faces.io.faststringwriter; import com.sun.faces.renderkit.attribute; import com.sun.faces.renderkit.attributemanager; import com.sun.faces.renderkit.renderkitutils; import com.sun.faces.renderkit.selectitemsiterator; import com.sun.faces.renderkit.html_basic.menurenderer; import javax.faces.component.uicomponent; import javax.faces.context.facescontext; import javax.faces.context.responsewriter; import javax.faces.convert.converter; import javax.faces.model.selectitem; import java.io.ioexception; import java.util.logging.level; public class extendedmenurenderer extends menurenderer { private boolean plaintext; private static final attribute[] attributes = attributemanager.getattributes(attributemanager.key.selectmanymenu); @override protected void renderselect(facescontext context, uicomponent component) throws ioexception { plaintext = "true".equalsignorecase((string) component.getattributes().get("plaintext")); if (plaintext) { selectitemsiterator<selectitem> items = renderkitutils.getselectitems(context, component); items.next(); plaintext = !items.hasnext(); } responsewriter writer = context.getresponsewriter(); assert (writer != null); if (logger.isloggable(level.finer)) { logger.log(level.finer, "rendering 'select'"); } if (plaintext) { writer.startelement("span", component); } else { writer.startelement("select", component); } writeidattributeifnecessary(context, writer, component); writer.writeattribute("name", component.getclientid(context), "clientid"); // render styleclass attribute if present. string styleclass; if (null != (styleclass = (string) component.getattributes().get("styleclass"))) { writer.writeattribute("class", styleclass, "styleclass"); } if (!getmultipletext(component).equals("")) { writer.writeattribute("multiple", true, "multiple"); } // determine how many option(s) need render, , update // component's "size" attribute accordingly; "size" // attribute rendered 1 of "pass thru" attributes selectitemsiterator<selectitem> items = renderkitutils.getselectitems(context, component); // render options buffer can determine // size faststringwriter bufferedwriter = new faststringwriter(128); context.setresponsewriter(writer.clonewithwriter(bufferedwriter)); int count = renderoptions(context, component, items); context.setresponsewriter(writer); // if "size" *not* set explicitly, have default correctly integer size = (integer) component.getattributes().get("size"); if (size == null || size == integer.min_value) { size = count; } writedefaultsize(writer, size); renderkitutils.renderpassthruattributes(context, writer, component, attributes, getnononchangebehaviors(component)); renderkitutils.renderxhtmlstylebooleanattributes(writer, component); renderkitutils.renderonchange(context, component, false); // now, write buffered option content writer.write(bufferedwriter.tostring()); if (plaintext) { writer.endelement("span"); } else { writer.endelement("select"); } } @override protected boolean renderoption(facescontext context, uicomponent component, uicomponent selectcomponent, converter converter, selectitem curitem, object currentselections, object[] submittedvalues, optioncomponentinfo optioninfo) throws ioexception { object valuesarray; object itemvalue; string valuestring = getformattedvalue(context, component, curitem.getvalue(), converter); boolean containsvalue; if (submittedvalues != null) { containsvalue = containsavalue(submittedvalues); if (containsvalue) { valuesarray = submittedvalues; itemvalue = valuestring; } else { valuesarray = currentselections; itemvalue = curitem.getvalue(); } } else { valuesarray = currentselections; itemvalue = curitem.getvalue(); } boolean isselected = isselected(context, component, itemvalue, valuesarray, converter); if (optioninfo.ishidenoselection() && curitem.isnoselectionoption() && currentselections != null && !isselected) { return false; } responsewriter writer = context.getresponsewriter(); assert (writer != null); writer.writetext("\t", component, null); if (plaintext) { if (curitem.isescape()) { string label = curitem.getlabel(); if (label == null) { label = valuestring; } writer.writetext(label, component, "label"); } else { writer.write(curitem.getlabel()); } writer.writetext("\n", component, null); return true; } writer.startelement("option", (null != selectcomponent) ? selectcomponent : component); writer.writeattribute("value", valuestring, "value"); if (isselected) { writer.writeattribute("selected", true, "selected"); } // if component disabled, "disabled" attribute rendered // on "select" tag, don't render "disabled" on every option. if ((!optioninfo.isdisabled()) && curitem.isdisabled()) { writer.writeattribute("disabled", true, "disabled"); } string labelclass; if (optioninfo.isdisabled() || curitem.isdisabled()) { labelclass = optioninfo.getdisabledclass(); } else { labelclass = optioninfo.getenabledclass(); } if (labelclass != null) { writer.writeattribute("class", labelclass, "labelclass"); } if (curitem.isescape()) { string label = curitem.getlabel(); if (label == null) { label = valuestring; } writer.writetext(label, component, "label"); } else { writer.write(curitem.getlabel()); } writer.endelement("option"); writer.writetext("\n", component, null); return true; } }
in faces-config.xml add:
<render-kit> <renderer> <component-family>javax.faces.selectone</component-family> <renderer-type>javax.faces.menu</renderer-type> <renderer-class>ru.mycityseason.extentions.extendedmenurenderer</renderer-class> </renderer> </render-kit>
Comments
Post a Comment