Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

possibility to search test (with diacritics) as **starts with** #642

Closed
hidegh opened this issue Dec 5, 2014 · 9 comments · Fixed by #1905
Closed

possibility to search test (with diacritics) as **starts with** #642

hidegh opened this issue Dec 5, 2014 · 9 comments · Fixed by #1905

Comments

@hidegh
Copy link

hidegh commented Dec 5, 2014

brianreavis/sifter.js#15

searching inside text is cool, but if you have to narrow down the possibilities, sometimes it's necessary to match only items, where item starts with the search text...

also it'd be nice, if only that part of the items would be highlighted inside the combo.

@hidegh
Copy link
Author

hidegh commented Dec 5, 2014

first i had to replace special chars to an 'ascii' (latin) equivalent

        (function() {

            var DIACRITICS = {
                'a': '[aÀÁÂÃÄÅàáâãäå]',
                'c': '[cÇçćĆčČ]',
                'd': '[dđĐďĎ]',
                'e': '[eÈÉÊËèéêëěĚ]',
                'i': '[iÌÍÎÏìíîï]',
                'n': '[nÑñňŇ]',
                'o': '[oÒÓÔÕÕÖØòóôõöø]',
                'r': '[rřŘ]',
                's': '[sŠš]',
                't': '[tťŤ]',
                'u': '[uÙÚÛÜùúûüůŮ]',
                'y': '[yŸÿýÝ]',
                'z': '[zŽž]'
            };

            var escape_regex = function(str) {
                return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
            };

            String.prototype.replaceDiacritics = function(remove) {
                if (remove === undefined)
                    remove = true;

                if (remove === true) {

                    var regex = escape_regex(this);

                    $.each(DIACRITICS, function(key, value) {
                        regex = regex.replace(new RegExp(value, 'g'), key);
                    });

                    return regex.toString();
                }

                return this;
            };

        }());

i wanted to preserve the original scoring, but even so i had to ensure scoring is not 0 in case when we had a match...so that +1 is mandatory...

                score: function(search) {

                    var score = this.getScoreFunction(search);
                    var modifiedSearchText = search.replaceDiacritics().toUpperCase();

                    return function(item) {

                        var modifiedItemText = item.value.replaceDiacritics().toUpperCase();
                        var indexOf = modifiedItemText.indexOf(modifiedSearchText);

                        if (indexOf == 0) {
                            var itemScore = score(item);
                            return 1 + itemScore;
                        }

                        return 0;
                    };
                }

@hidegh
Copy link
Author

hidegh commented Dec 10, 2014

To add: the only drawback is that highlighting isn't correct.
@brianreavis adviced to "just adjust tokenize to not split on spaces and add a ^ to the beginning of the regexp that it produces."

but that would not allow us to have 2 selectize.js component, one that matches starts and other one that matches anything (contains).

so the only real solution is to have a match parameter inside selectize (this could be some regex) that is later passed to sifter.js (as a parameter). this would be quiet flexibe and possibly even highlighting would work with it 😄

please if anyone finds this improvement usefull, give a +1 vote to it. thanx.

@sophiedeziel
Copy link

I'd really need that starts with search, so I give 💯 👍

@falkenhawk
Copy link

+1 !

1 similar comment
@davidrevoledo
Copy link

+1 !

@kashpatel
Copy link

+1

@RagazziMoscow
Copy link

+1 !

@RudeySH
Copy link

RudeySH commented May 22, 2020

It looks like sifter v0.6.0 has implemented the option respect_word_boundaries, see brianreavis/sifter.js#51. This is effectively the same as a "starts with" search. Now all that's left to do is for someone to add an option to selectize that sets respect_word_boundaries to true. For now, you could (temporarily) modify the prototype of selectize like so:

var getSearchOptions = Selectize.prototype.getSearchOptions;
Selectize.prototype.getSearchOptions = function () {
	var options = getSearchOptions.apply(this, arguments);
	options.respect_word_boundaries = true;
	return options;
};

This sets respect_word_boundaries to true every time selectize calls sifter internally. Alternatively, you could modify the prototype of sifter itself to make respect_word_boundaries true.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 7, 2021

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days

@risadams risadams added pending review This issue was closed as stale; since then additional review has been requested. and removed no-issue-activity labels Jan 7, 2021
@risadams risadams added enhancement adds an option and removed pending review This issue was closed as stale; since then additional review has been requested. labels Nov 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants