<hr>
From a set of items with string values, given a query string, mark the matching items.
<hr>
<input id="query" type="search" placeholder="type query string here..."><br>
<details open><summary>Options...</summary>
<div>
<label>
<input type="checkbox" data-optionkey="literal_match">
basic literal match
<small>(ignores other options, but still allows case insensitive)</small>
</label><br>
<label>
<input type="checkbox" data-optionkey="case_sensitive">
case sensitive
</label><br>
<label>
<input type="checkbox" data-optionkey="or_enabled" checked>
OR enabled <small>("a,b" matches "a" or "b")</small>
</label>
--
<label>
separator:
<input type="text" data-optionkey="or_separator" value=","
style="width: 1em;">
</label><br>
<label>
<input type="checkbox" data-optionkey="and_enabled" checked>
AND enabled <small>("a b" matches "a ... b")</small>
</label>
--
<label>
separator:
<input type="text" data-optionkey="and_separator" value=" "
style="width: 1em;">
</label><br>
<label>
<input type="checkbox" data-optionkey="order_matters" checked>
AND order matters <small>("a b" matches "a b" but not "b a")</small>
</label><br>
</div>
</details>
<hr>
example data, match by row:<br>
<table>
<tbody>
<tr><td>aa</td><td>bb</td><td>cc</td></tr>
<tr><td>dd</td><td>ee</td><td>ff</td></tr>
<tr><td>ab</td><td>bc</td><td>cd</td></tr>
<tr><td>aa</td><td>ee</td><td>zz</td></tr>
<tr><td>a b</td><td>c d</td><td>e f</td></tr>
<tr><td>xx</td><td>yy</td><td>zz</td></tr>
</tbody>
</table>
<hr>
features:
<ul>
<li>Optionally case sensitive.</li>
<li>OR support: Can match multiple queries at once by separating with comma.<br>
e.g. "A , B" will match any item with either "A" or "B" in it.</li>
<li>AND support: Any whitespace is a wildcard.<br>
e.g. "A*B*C" will match "A*B*C" ("ABC","AxxBC","xxAxxBxxCxx", ...)</li>
<li>query AND order optionally matters.<br>
e.g. "A B C" could match "Aaa Bbb Ccc" but not "Bbb Aaa Ccc"</li>
<li>Can work on just a list of...
// https://jsfiddle.net/ElMoonLite/6zgnu27e/
class Matcher {
items = [];
options = {};
options_default = {
// literal_match : disable features like whitespace wildcards,
// but still supports or_enabled and case_sensitive flags.
// Could also be quicker for very large data sets.
literal_match: false,
case_sensitive: false,
or_enabled: true,
or_separator: ',', // either a string or regexp
and_enabled: true,
and_separator: ' ', // either a string or regexp
parseItemValueFunction: null, // null, or a function returning null for default handling.
order_matters: true,
};
constructor() {
// super();
this.items = [];
this.resetOptions();
}
setItems(arr) {
this.items = [];
if (!arr) {
// this allows rebuilding items (e.g. updating values with new options)
arr = this.getItems();
}
arr.forEach((item) => {
let o = {
_ : item, // original value, could also be an object
value: '',
};
if (typeof item === 'string') {
o.value = item;
} else if (typeof item === 'object') {
if (typeof this.options.parseItemValueFunction === 'function') {
o.value = '' + this.options.parseItemValueFunction(item);
}
if (item.tagName === 'TR') {
// assume item is a HTMLTableRowElement (i.e. <tr>)
// add some "salt" between tablecells,
// prevent matching from one cell into another,
// e.g. "ab" matching on "<td>a</td><td>b</td>"
o.value = Array.from(item.childNodes).map((td) => {
return td.textContent;
}).join('|');
}
if (!o.value && item.value && typeof item.value === 'string') {
o.value = item.value;
}
if (!o.value && typeof item.textContent === 'string') {
o.value = item.textContent;
}
if (!o.value && typeof item.toString === 'function') {
o.value = item.toString();
}
if (!o.value && item.valueOf) {
o.value = ('' + item.valueOf());
}
}
o.value_lowercase =...
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.