3

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?

Josef Plch
  • 33
  • 6

2 Answers2

3

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

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102
  • Great, I have been looking for some report for several days. However, the _MonkeyPatch_ is problematic. It truly fixes the handling of `<>&` which I asked for, but at the same time – regardless of any settings – it removes all characters after the first double quote, so that `some "quoted" value` becomes `some`. For this reason, I’m afraid the patch is not applicable in my case, but at least I know it’s a bug. – Josef Plch Jan 05 '23 at 16:18
  • @JosefPlch it worked incorrectly in PF11 as well it needs to be escaped and HTML needs to be handled. if you read starting here we even have integration tests for this and its because it has to be able to render HTML: https://github.com/primefaces/primefaces/issues/9336#issuecomment-1294057217 – Melloware Jan 05 '23 at 19:05
  • 1
    @JasperdeVries OK, I reported the problem and the proposed solution [at GitHub](https://github.com/primefaces/primefaces/issues/9336#issuecomment-1373500919). After the fix, the settings No. 2 and 3 listed above behave the same way. – Josef Plch Jan 06 '23 at 11:34
2

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];
            });
     };
}
Melloware
  • 10,435
  • 2
  • 32
  • 62
  • This makes the label in PrimeFaces 12 work the same way as it did in version 11. The question is: would’t it be better to leave the label unchanged and keep `< italics` for both No. 2 and 3? This is the behaviour of [my fix](https://github.com/primefaces/primefaces/issues/9336#issuecomment-1373500919). It is up to the individual developer to decide which solution is better. – Josef Plch Jan 09 '23 at 09:10
  • I answered in the PF ticket. Looks like yours misses one of your use cases. – Melloware Jan 09 '23 at 13:51