When using the SelectOneMenu from Primefaces (6.1.1) and adding some SelectItems having HTML formatted labels, the selected item of the Component displays the escaped HTML, even though the 'SelectItem.escape' property is set to false (and, in addition, the 'itemLabelEscaped'-Attribute is false as well). The dropdown holding the selectable items is rendered correctly.
Backing bean sample:
public List<SelectItem> formattedSelectItems() {
List<SelectItem> items = new ArrayList<>();
for (int i = 100; i < 103; i++) {
items.add(new SelectItem(i, "<u>" + i + "</u>", "", false, false));
}
return items;
}
JSF:
<p:selectOneMenu>
<f:selectItems value="#{selectOneTestController.formattedSelectItems()}" itemLabelEscaped="false"/>
</p:selectOneMenu>
Is this a bug or am I doing something wrong? Thanks for help.
This is not a bug.
You are probably confusing SelectItem's Label with Selected Label (see image below)
Rendered HTML looks something like this:
<div class="ui-selectonemenu ui-widget ui-state-default ui-corner-all"
id="form:oneMenu" style="min-width: 47px;">
<div class="ui-helper-hidden-accessible">
<input name="form:oneMenu_focus" class="mb-user-select-none"
id="form:oneMenu_focus" role="combobox" aria-disabled="false"
aria-expanded="false" aria-haspopup="true"
aria-describedby="form:oneMenu_2"
aria-activedescendant="form:oneMenu_2"
aria-owns="form:oneMenu_items" aria-autocomplete="list"
onfocus="changeSelectedLabel()" onblur="changeSelectedLabel()" type="text"
autocomplete="off">
</div>
<div class="ui-helper-hidden-accessible">
<select name="form:oneMenu_input" tabindex="-1"
id="form:oneMenu_input" data-p-hl="onemenu">
<option value="100">100</option>
<option value="101">101</option>
<option value="102">102</option></select>
</div>
<label class="ui-selectonemenu-label ui-inputfield ui-corner-all" id="form:oneMenu_label"><u>102</u></label>
<div
class="ui-selectonemenu-trigger ui-state-default ui-corner-right">
<span class="ui-icon ui-icon-triangle-1-s ui-c"></span>
</div>
</div>
A label
is rendered for the Selected Label. (see SelectOneMenuRenderer#encodeLabel)
So even if you set SelectItem.escape
property to false
or add itemLabelEscaped="false"
attribute of f:selectItems
,
Selected Label will still be escaped.
In order to escape Selected Label, refer to the following codes bellow:
Script
<script type="text/javascript">
function changeSelectedLabel() {
console.log('change!!');
var label = $("label[id='form:oneMenu_label']");
var text = label.text();
label.text("");
label.append(text);
}
$(window).bind("load", function() {
changeSelectedLabel();
});
</script>
selectOneMenu
<p:selectOneMenu id="oneMenu" onfocus="changeSelectedLabel()" onblur="changeSelectedLabel()">
<f:selectItems value="#{selectOneTestController.formattedSelectItems()}" itemLabelEscaped="false"/>
</p:selectOneMenu>
This will change the Selected Label in window load and selectOneMenu's onfocus
and onblur
events.
Why I used onfocus
and onblur
instead of onchange
?
Using onchange
will return the Selected Label to it's escaped value when the selectOneMenu is expanded if you didn't changed/selected an item.
Feel free to play with this to what fits your requirement.
Regards,