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.
+1, it's a matter of elementary logic. "Uni Sta" should find "United States".
+1 Absolutly, this need to be merged ind
Added this as a proper pull request: https://github.com/harvesthq/chosen/pull/867
+1
This plugin desperately needs fuzzy search.
+1
+1 This would be extremely helpful, what's the status on merging the pull request #867
I forked the repo to do just this, figured I would search for an issue first - +1 this needs to be merged!!
+1 thx for the quick patch YANOUSHek
+1
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
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?
@eliasdorneles yes please. It makes the review far easier
@stof ok, done!
+1 Using the patch to good effect.
+1 a must have!
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
@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
@eliasdorneles , thank you very much. your version worked :)
i was looking for that, it's a must for the original.
thx @eliasdorneles seems it works great
+1 a must!
+1
+1 saves tons of time
+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!
:+1:
Most helpful comment
+1, it's a matter of elementary logic. "Uni Sta" should find "United States".