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

"Fuzzy" word search #858

Open
YANOUSHek opened this issue Oct 12, 2012 · 25 comments
Open

"Fuzzy" word search #858

YANOUSHek opened this issue Oct 12, 2012 · 25 comments

Comments

@YANOUSHek
Copy link

Hi,

I'm a fellow developer who recently found chosen and I'm amazed by you solution. I did run into a couple problems with the filtering text which I managed to work out and change a couple lines in your code. I don't know if this is something that might interest you and you'd like to have it merged with your code. Let me describe the problem and show you a diff of my changes.

The problem I had was searching for more than word. For example, if you go to your demo site, insert the text "bosnia herz" into the country select and you'll see that nothing matches because you're searching for the exact string I've typed. Also you can't type words in wrong order or just parts of the words ("uni sta").

I'd really like the option to have such a "fuzzy" filter and I've managed to change the jquery version of chosen to just do that. The diff:

diff --git a/chosen/chosen.jquery.js b/chosen/chosen.jquery.js
index 3e559e2..3799d41 100644
--- a/chosen/chosen.jquery.js
+++ b/chosen/chosen.jquery.js
@@ -792,6 +792,7 @@ Copyright (c) 2011 by Harvest
       this.no_results_clear();
       results = 0;
       searchText = this.search_field.val() === this.default_text ? "" : $('<div/>').text($.trim(this.search_field.val())).html();
+      var words = searchText.toLowerCase().split(' ');
       regexAnchor = this.search_contains ? "" : "^";
       regex = new RegExp(regexAnchor + searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
       zregex = new RegExp(searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'i');
@@ -802,32 +803,20 @@ Copyright (c) 2011 by Harvest
           if (option.group) {
             $('#' + option.dom_id).css('display', 'none');
           } else if (!(this.is_multiple && option.selected)) {
-            found = false;
             result_id = option.dom_id;
             result = $("#" + result_id);
-            if (regex.test(option.html)) {
-              found = true;
-              results += 1;
-            } else if (option.html.indexOf(" ") >= 0 || option.html.indexOf("[") === 0) {
-              parts = option.html.replace(/\[|\]/g, "").split(" ");
-              if (parts.length) {
-                for (_j = 0, _len2 = parts.length; _j < _len2; _j++) {
-                  part = parts[_j];
-                  if (regex.test(part)) {
-                    found = true;
-                    results += 1;
-                  }
-                }
+            found = true;
+            for (var i_word = 0; i_word < words.length; ++i_word) {
+              if (option.html.toLowerCase().indexOf(words[i_word]) < 0) {
+                found = false;
+                break;
               }
             }
             if (found) {
-              if (searchText.length) {
-                startpos = option.html.search(zregex);
-                text = option.html.substr(0, startpos + searchText.length) + '</em>' + option.html.substr(startpos + searchText.length);
-                text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
-              } else {
-                text = option.html;
-              }
+              results += 1;
+            }
+            if (found) {
+              text = option.html;
               result.html(text);
               this.result_activate(result);
               if (option.group_array_index != null) {

This was just me hacking at the jQuery version to have it running on my site. I've lost the option to highlight the text that matched the filter but I didn't really care about that.

If this is something that might interest you I'll make a fork and submit a pull request. I'll even bring back the <em> highlights.

@andrejsverza
Copy link

+1, it's a matter of elementary logic. "Uni Sta" should find "United States".

@darxmac
Copy link

darxmac commented Oct 16, 2012

+1 Absolutly, this need to be merged ind

@YANOUSHek
Copy link
Author

Added this as a proper pull request: #867

@sihingkk
Copy link

+1

@GRAgmLauncher
Copy link

This plugin desperately needs fuzzy search.

@number8pie
Copy link

+1

@mattsmith
Copy link

+1 This would be extremely helpful, what's the status on merging the pull request #867

@ixmatus
Copy link

ixmatus commented Jan 2, 2013

I forked the repo to do just this, figured I would search for an issue first - +1 this needs to be merged!!

@lethak
Copy link

lethak commented Jan 4, 2013

+1 thx for the quick patch YANOUSHek

@Nerian
Copy link

Nerian commented Feb 9, 2013

+1

@eliasdorneles
Copy link

I've ported the jQuery code proposed to the current CoffeScript code and made some changes to make the highlighting to work: https://github.com/eliasdorneles/chosen
Regarding the highlight of results, I did the simplest thing who could possibly work, but it needs a bit more tweaking.

Please give a try and let me know if you have any suggestions! :)
Elias

@eliasdorneles
Copy link

I fixed the highlight issues I was having, it looks alright now, please check it out at: https://github.com/eliasdorneles/chosen
Should I open a pull request?

@stof
Copy link
Collaborator

stof commented Feb 12, 2013

@eliasdorneles yes please. It makes the review far easier

@eliasdorneles
Copy link

@stof ok, done!

@dacc
Copy link

dacc commented Feb 28, 2013

+1 Using the patch to good effect.

@bbuchalter
Copy link

+1 a must have!

@saulob
Copy link

saulob commented Jun 25, 2013

How does it works? I'm unable to make it work. I type "ted" from United and no results on the demo.

What I'm doing wrong?

Thanks

@eliasdorneles
Copy link

@saulob Try the chosen version in my repository that I've ported from this and added other fixes -- several people are using it without problems: https://github.com/eliasdorneles/chosen

@saulob
Copy link

saulob commented Jun 25, 2013

@eliasdorneles , thank you very much. your version worked :)

@didacrios
Copy link

i was looking for that, it's a must for the original.

thx @eliasdorneles seems it works great

@GreenTrafficCone
Copy link

+1 a must!

@j15e
Copy link

j15e commented Aug 15, 2013

+1

@obojdi
Copy link

obojdi commented Jan 13, 2014

+1 saves tons of time

@deigote
Copy link

deigote commented Apr 2, 2014

+1 I had the same need and I ended up reducing the scope of my solution to avoid maintaining a complex patch:

-      escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+      escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
+         .split('\\ ').filter(function(e) { return e.length > 0 }).join('(.)+');

This just tokenizes the search by spaces, so it doesn't allow to change the order. It would be awesome to have behavior / solution proposed by @YANOUSHek integrated in chosen core!

@nlsrchtr
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests