Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

p:selectOneMenu filter not working with accented characters

I use PrimeFaces SelectOneMenu advanced. Filter is wrong working when I input the i and ı character.
For example http://www.primefaces.org/showcase/ui/input/oneMenu.xhtml demo advanced one menu I search arI and arİ strings and it finds Aristo element.

In my application, my menu contains Isparta element. I input Isp and İsp and filter finds Isparta.

How can I solve this problem?

like image 541
Gökhan Memiş Avatar asked Sep 11 '25 22:09

Gökhan Memiş


2 Answers

I resolve this problem with autocomplete component. Primefaces autocomplete component with dropdown="true" property works like one menu and this component don't have Turkish character problem.

like image 124
Gökhan Memiş Avatar answered Sep 14 '25 17:09

Gökhan Memiş


Reported to PrimeFaces Team: https://github.com/primefaces/primefaces/issues/9629

Fixed for 13.0.0 but MonkeyPatch provided here:

if (PrimeFaces.widget.SelectOneMenu) {

    PrimeFaces.widget.SelectOneMenu.prototype.normalize = function(string, lowercase) {
        if (!string) return string;
        var result = string.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
        return lowercase ? result.toLowerCase() : result;
    }

    PrimeFaces.widget.SelectOneMenu.prototype.filter = function(value) {
        this.cfg.initialHeight = this.cfg.initialHeight || this.itemsWrapper.height();
        var filterValue = this.normalize(PrimeFaces.trim(value), !this.cfg.caseSensitive);

        if (filterValue === '') {
            this.items.filter(':hidden').show();
            this.itemsContainer.children('.ui-selectonemenu-item-group').show();
        } else {
            var hide = [];
            var show = [];

            for (var i = 0; i < this.options.length; i++) {
                var option = this.options.eq(i),
                    itemLabel = this.normalize(option.text(), !this.cfg.caseSensitive),
                    item = this.items.eq(i);

                if (item.hasClass('ui-noselection-option')) {
                    hide.push(item);
                } else {
                    if (this.filterMatcher(itemLabel, filterValue)) {
                        show.push(item);
                    } else if (!item.is('.ui-selectonemenu-item-group-children')) {
                        hide.push(item);
                    } else {
                        itemLabel = this.normalize(option.parent().attr('label'), !this.cfg.caseSensitive);
                        if (this.filterMatcher(itemLabel, filterValue)) {
                            show.push(item);
                        } else {
                            hide.push(item);
                        }
                    }
                }
            }

            $.each(hide, function(i, o) {
                o.hide();
            });
            $.each(show, function(i, o) {
                o.show();
            });
            hide = [];
            show = [];

            //Toggle groups
            var groups = this.itemsContainer.children('.ui-selectonemenu-item-group');
            for (var g = 0; g < groups.length; g++) {
                var group = groups.eq(g);

                if (g === (groups.length - 1)) {
                    if (group.nextAll().filter('.ui-selectonemenu-item-group-children:visible').length === 0)
                        hide.push(group);
                    else
                        show.push(group);
                } else {
                    if (group.nextUntil('.ui-selectonemenu-item-group').filter('.ui-selectonemenu-item-group-children:visible').length === 0)
                        hide.push(group);
                    else
                        show.push(group);
                }
            }

            $.each(hide, function(i, o) {
                o.hide();
            });
            $.each(show, function(i, o) {
                o.show();
            });
        }

        var firstVisibleItem = this.items.filter(':visible:not(.ui-state-disabled):first');
        if (firstVisibleItem.length) {
            this.highlightItem(firstVisibleItem);
            PrimeFaces.scrollInView(this.itemsWrapper, firstVisibleItem);
        }

        if (this.itemsContainer.height() < this.cfg.initialHeight) {
            this.itemsWrapper.css('height', 'auto');
        } else {
            this.itemsWrapper.height(this.cfg.initialHeight);
        }

        this.alignPanel();
    }
};
like image 32
Melloware Avatar answered Sep 14 '25 17:09

Melloware