Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double-escaped label in SelectOneMenu in PrimeFaces 12

In PrimeFaces’ SelectOneMenu, I use options (often placeholders) like <please select>, loaded from controller via f:selectItems and escaped automatically by the SelectOneMenu component. After updating PrimeFaces 11 to version 12, the component started to double-escape the characters <, >, & in its label, while the option list is still rendered as expected. (When I click <please select>, the label shows &lt;please select&gt;.)

I tried all combinations of these settings:

  • view: f:selectItems.itemLabelEscaped = "true"/"false"
  • controller: SelectItem.escape = "true"/"false"
  • controller: SelectItem.label is/isn’t escaped manually

The attribute itemLabelEscaped has no effect. Other combinations work as follows:

No. SelectItem.escape SelectItem.label Option in dropdown Shown label in PF 11 Shown label in PF 12
1 false < <i>italics</i> < italics italics italics
2 false &lt; &lt;i&gt;italics&lt;/i&gt; < <i>italics</i> < italics < <i>italics</i>
3 true < <i>italics</i> < <i>italics</i> < <i>italics</i> &lt; &lt;i&gt;italics&lt;/i&gt;
4 true &lt; &lt;i&gt;italics&lt;/i&gt; &lt; &lt;i&gt;italics&lt;/i&gt; &lt; &lt;i&gt;italics&lt;/i&gt; (even more escaped)

In PrimeFaces 11, I used the setting No. 3, and the label was the same as the option in dropdown. After the update, the label gets broken and the only working setting seems to be No. 2, but I don’t want to update all occurrences of selectItems unless necessary.

As I did not find any relevant info in PrimeFaces’ release notes, I would consider it a bug, but I wonder nobody has reported it yet, so I’m not sure: is it a bug, or a feature? This old question seems to be relevant, but how come it worked in PrimeFaces 11?

like image 340
Josef Plch Avatar asked Nov 25 '25 03:11

Josef Plch


2 Answers

This is a known and fixed issue. Until PrimeFaces 13 is released, you can MonkeyPatch the workaround.

like image 121
Jasper de Vries Avatar answered Nov 27 '25 15:11

Jasper de Vries


OK it should be fixed for good in PF 13.0 and this MonkeyPatch should solve all your current issues.

if (PrimeFaces.widget.SelectOneMenu) {
    PrimeFaces.widget.SelectOneMenu.prototype.renderSelectItem = function(item, isGrouped) {
        var content = "";
        var $item = $(item);
        var label;
        var title = $item.data("title");
        var escape = $item.data("escape");
        var cssClass;

        if (item.tagName === "OPTGROUP") {
            label = $item.attr("label");
            if (escape) {
                label = $("<div>").text(label).html();
            }
            cssClass = "ui-selectonemenu-item-group ui-corner-all";
        } else { //OPTION
            if (escape) {
                label = $item.html();
                if ($item.text() === "&nbsp;") {
                    label = $item.text();
                }
            } else {
                label = $item.text();
            }
            
            cssClass = "ui-selectonemenu-item ui-selectonemenu-list-item ui-corner-all";
            if (isGrouped) {
                cssClass += " ui-selectonemenu-item-group-children";
            }
        }

        var dataLabel = escape ? label.replaceAll('"', '&quot;') : this.escapeHTMLIfNecessary(label);

        if ($item.data("noselection-option")) {
            cssClass += " ui-noselection-option";
        }

        content += '<li class="' + cssClass + '" tabindex="-1" role="option"';
        if (title) {
            content += ' title="' + title + '"';
        }
        if ($item.is(':disabled')) {
            content += ' disabled';
        }
        content += ' data-label="' + dataLabel + '"';
        content += '>';
        content += label;
        content += '</li>';

        if (item.tagName === "OPTGROUP") {
            content += this.renderSelectItems($item, true);
        }

        return content;
    };

    PrimeFaces.widget.SelectOneMenu.prototype.escapeHTMLIfNecessary = function(value) {
            return String(value).replace(/[<>"'`=\/]/g, function(s) {
                return PrimeFaces.entityMap[s];
            });
     };
}
like image 21
Melloware Avatar answered Nov 27 '25 15:11

Melloware