Last active
August 19, 2022 18:53
-
-
Save zdk123/f22b96a6a5d71c642927e7b5954d6c85 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { checkbox, search } from "@jashkenas/inputs" | |
export function searchCheckbox( | |
opts, | |
options = { | |
value: [], | |
optionsCheckboxes: undefined, // use this if you want to pass specific options to the checkboxes or the search | |
optionsSearch: undefined | |
} | |
) { | |
opts = Array.from(opts); | |
options.value = options.value === undefined ? [] : options.value; | |
let checkboxes = checkbox(opts, options.optionsCheckboxes || options); | |
let searchOpts = options.optionsSearch || options; | |
searchOpts['filter'] = searchFilter2; // override default filter | |
const search = search(opts, searchOpts); | |
const btnAll = html`<button class="check">All</button>`; | |
const btnNone = html`<button class="check">None</button>`; | |
let selected = new Map(Array.from(options.value).map((d) => [d, true])); | |
//console.log(selected); | |
function selectedToArray() { | |
return Array.from(selected.entries()) | |
.filter(([k, v]) => v) | |
.map(([k, v]) => k); | |
} | |
function changeSome(sel, changeTo) { | |
for (let o of sel) selected.set(o, changeTo); | |
} | |
function selectedFromArray(sel) { | |
changeSome(opts, false); | |
changeSome(sel, true); | |
} | |
let output = html`<output>`; | |
const component = html`${search} | |
${btnAll} | |
${btnNone} | |
${output} | |
${checkboxes}`; | |
// Update the display whenever the value changes | |
Object.defineProperty(component, "value", { | |
get() { | |
return selectedToArray(); | |
}, | |
set(v) { | |
selectedFromArray(v); | |
} | |
}); | |
btnAll.addEventListener("click", () => { | |
changeSome(search.value, true); | |
checkboxes.value = selectedToArray(); | |
component.dispatchEvent(new Event("input", { bubbles: true })); | |
}); | |
btnNone.addEventListener("click", () => { | |
changeSome(search.value, false); | |
checkboxes.value = selectedToArray(); | |
component.dispatchEvent(new Event("input", { bubbles: true })); | |
}); | |
component.value = selectedToArray(); | |
search.addEventListener("input", () => { | |
// Hide all the checkboxes that aren't in the searchbox result | |
console.log(search.value); | |
for (let check of checkboxes.querySelectorAll("input")) { | |
if (search.value.includes(opts[+check.value])) { | |
check.parentElement.style.display = "inline-block"; | |
// auto-select search matches | |
changeSome([options.value[check.value]], true); | |
check.checked = true; | |
} else { | |
check.parentElement.style.display = "none"; | |
// auto-disselect search non-matches | |
changeSome([options.value[check.value]], false); | |
check.checked = false; | |
} | |
} | |
component.dispatchEvent(new Event("input")); | |
}); | |
checkboxes.addEventListener("input", () => { | |
component.value = checkboxes.value; | |
component.dispatchEvent(new Event("input")); | |
}); | |
return component; | |
} | |
function* valuesof(d) { | |
for (const key in d) { | |
yield d[key]; | |
} | |
} | |
// removes beginning anchor of the default regex filter | |
function escapeRegExp(text) { | |
return text.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&"); | |
} | |
function termFilter(term) { | |
let regex = new RegExp(`(?:|[^\\p{L}-])${escapeRegExp(term)}`, "iu"); | |
console.log(regex) | |
return regex; | |
} | |
function searchFilter2(query) { | |
const filters = `${query}`.split(/\s+/g).filter(t => t).map(termFilter); | |
return d => { | |
if (d == null) return false; | |
if (typeof d === "object") { | |
out: for (const filter of filters) { | |
for (const value of valuesof(d)) { | |
if (filter.test(value)) { | |
continue out; | |
} | |
} | |
return false; | |
} | |
} else { | |
for (const filter of filters) { | |
if (!filter.test(d)) { | |
return false; | |
} | |
} | |
} | |
return true; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment