Reputation: 2728
Is there anyway to make chosen look at more than just an options text for the search functionality?
for instance:
<select>
<option data-keywords="circle,ball,sphere">Circle</option>
<option data-keywords="rectangle,square">Rectangle</option>
</select>
It wouldn't have to do the match underlining on keywords, it would only do the result match underlining if it matched text like it does by default.
If its not native how would I add this in javascript if it has not already been done before.
Upvotes: 1
Views: 2514
Reputation: 513
Thanks SquareCat for your great solution! I wanted to have the ability to search using multiple keywords (including partial keywords) so I developed some crude code that does the job.
Adding onto SquareCats solution:
Instead of using:
keywordMatch=(option.keywords && option.keywords.indexOf(searchText) > -1);
Use this instead:
keywordMatch=this.keyword_string_match(option.keywords,searchText);
And add this function:
AbstractChosen.prototype.keyword_string_match = function(keyword_array, searchtextstring) {
var value, searchlength, searchterm;
var continuetonext = "";
var searchstring = searchtextstring;
var wordmatchcounter = 0;
if (searchstring !== ""){
searchstring = searchstring.split(' ');
for (searchterm = 0 ; searchterm < searchstring.length; searchterm++ ){
if (continuetonext == "" || continuetonext == true){
continuetonext = false;
searchtext = searchstring[searchterm];
for (var i = 0; i < keyword_array.length; ++i) {
value = keyword_array[i];
searchlength = searchtext.length;
if (value.substring(0, searchlength) === searchtext) {
continuetonext = true;
wordmatchcounter++;
}else{
continuetonext = false;
};
};
};
};
if (wordmatchcounter == searchterm){return true}else{return false};
}else{return false};
};
Upvotes: 2
Reputation: 5840
A fairly down-to-earth, quick solution can be applied as follows.
Please note
This solution requires/assumes:
data-keywords
attribute for each option
tagdata-keywords
attributeOk, so let's get to it.
Open your jquery.chosen.js file.
(You will not be able to use the minified version).
1. Assure storage of data attribute in local options
Location => add_option()
Full Definition
SelectParser.prototype.add_option = function(option, group_position, group_disabled) {}
Edit
Look for this.parsed.push()
and at the bottom of the definition, just below style
, add this code:
keywords: ($(option).data().keywords!==undefined
? $(option).data().keywords.split(',')
: false)
2. Make sure the keywords are parsed by the search function
Location => winnow_results()
Full Definition
AbstractChosen.prototype.winnow_results = function() {}
Edit
2.1 Add a new variable keywordMatch
to top declaration:
var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
Becomes:
var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref, keywordMatch;
2.2 Find this condition: if (!(option.group && !this.group_search)){}
and after the second line (where option.search_match
is set), add this code:
keywordMatch=(option.keywords && option.keywords.indexOf(searchText) > -1);
if(keywordMatch)
option.search_match=true;
2.3 Find this assignment:
option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
And replace it with this code:
option.search_text = keywordMatch ? text : (text.substr(0, startpos) + '<em>' + text.substr(startpos));
These modifications come in the form of a quick implementation. If you need more options (for instance that the keywords are not case-sensitive), you need to implement these parts yourself.
Let me know if there are problems or if i forgot anything.
Upvotes: 5
Reputation: 25682
I believe something like that will work:
JavaScript
document.getElementById('filter-input').onkeyup = function () {
filter(this.value, document.getElementById('select-input'));
};
function filter(value, input) {
var children = input.children,
found = false,
keywords;
children = Array.prototype.slice.call(children);
children.forEach(function (c) {
c.removeAttribute('selected');
});
children.forEach(function (c) {
keywords = c.getAttribute('data-keywords').split(',');
keywords.forEach(function (k) {
if (k === value) {
found = true;
c.setAttribute('selected', true);
return;
}
});
if (found) return;
});
}
Upvotes: 0