This awkward behavior is confirmed by SelectOneMenuRenderer
source code (line numbers match 5.2):
260 if(itemValue instanceof String) {
261 writer.startElement("td", null);
262 writer.writeAttribute("colspan", columns.size(), null);
263 writer.writeText(selectItem.getLabel(), null);
264 writer.endElement("td");
265 }
266 else {
267 for(Column column : columns) {
268 writer.startElement("td", null);
269 renderChildren(context, column);
270 writer.endElement("td");
271 }
272 }
So, if the item value is an instance of String
, custom content via <p:column>
is totally ignored. This does indeed not make any sense. The intuitive expectation is that the custom content is toggled by presence of var
attribute and/or <p:column>
children. You'd best report an issue to PrimeFaces guys to explain/improve this.
The work around, apart from providing non-String
-typed item values, is to override the SelectOneMenuRenderer
with a custom renderer which wraps the String
in another object which happens to return exactly the same value in its toString()
, such as StringBuilder
. This way the renderer will be fooled that the values aren't an instance of String
. Glad they didn't check for instanceof CharSequence
.
public class YourSelectOneMenuRenderer extends SelectOneMenuRenderer {
@Override
protected void encodeOptionsAsTable(FacesContext context, SelectOneMenu menu, List<SelectItem> selectItems) throws IOException {
List<SelectItem> wrappedSelectItems = new ArrayList<>();
for (SelectItem selectItem : selectItems) {
Object value = selectItem.getValue();
if (value instanceof String) {
value = new StringBuilder((String) value);
}
wrappedSelectItems.add(new SelectItem(value, selectItem.getLabel()));
}
super.encodeOptionsAsTable(context, menu, wrappedSelectItems);
}
}
In order to get it to run, register it as below in faces-config.xml
:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.SelectOneMenuRenderer</renderer-type>
<renderer-class>com.example.YourSelectOneMenuRenderer</renderer-class>
</renderer>
</render-kit>
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…