@gramex/filters
v2.0.0
Published
Populate filter inputs/dropdowns from data
Downloads
1
Maintainers
Readme
@gramex/filters
filters renders data as filters using <select>
/ <input>
elements, or frameworks like
Bootstrap,
bootstrap-select,
etc.
Sample usage:
gramex.filters.render({
container: "form",
data: {
city: [
{ label: "London", value: "LON" },
{ label: "Oslo", value: "OSL" },
{ label: "Paris", value: "PAR" },
],
channel: [
{ label: "Direct", value: "DIR" },
{ label: "Indirect", value: "IND" },
],
},
});
Installation
Run npm install @gramex/filters
To use filters on the browser, include the script in your HTML:
<script src="https://cdn.jsdelivr.net/npm/@gramex/filters/filters.min.js"></script>
<!-- OR src="node_modules/@gramex/filters/filters.min.js"></script -->
<script>
gramex.filters.render({...})
</script>
For use with ES6 modules, use:
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js"
// OR { render } from "https://cdn.skypack.dev/@gramex/filters"
// OR { render } from "https://esm.sh/@gramex/filters"
render({...})
</script>
Usage
<form id="basic-usage"></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form#basic-usage",
data: {
product: ["Alpha", "Beta", "Gamma"],
city: ["London", "Oslo", "Paris"],
channel: ["Direct", "Indirect"],
},
});
</script>
This renders:
<form id="basic-usage">
<select name="product">
<option value="Alpha">Alpha</option>
<option value="Beta">Beta</option>
<option value="Gamma">Gamma</option>
</select>
<select name="city">
<option value="London">London</option>
<option value="Oslo">Oslo</option>
<option value="Paris">Paris</option>
</select>
<select name="channel">
<option value="Direct">Direct</option>
<option value="Indirect">Indirect</option>
</select>
</form>
Options
container
: CSS selector or Element into which filter is renderedtype
: type of HTML to generate. Can beselect
: renders<select>
and<option>
elements in a HTML formbs5
: renders Bootstrap 5 dropdownsbootstrap-select
select2
selectize
data
: object with filter data. Keys are the filter names. Values are arrays of filter values.- Filter values can be a string:
{"choice": ["X", "Y", "Z"]}
- Filter values can be an object:
{"choice": [{label: "X", value: "x"}, {label: "Y", value: "y"}]}
- Filter names (like
choice
) map to field names (like<select name="choice">
)
- Filter values can be a string:
url
: a URL that returns thedata
above.- At least one of
data
orurl
is required data
overridesurl
- If
url
is used,gramex.filters.render()
returns a Promise that resolves to the JSON response ofurl
- At least one of
- field: filter-specific field attributes. Keys are the filter names. Values are field attribute scalars or functions
{"city": {"multiple": true}, "product": {"multiple": false}}
makes thecity
filter a multiple-select, but notproduct
{"city": {"class": "form-select"}}
adds aclass="form-select"
to thecity
select
- fields: common field attributes
{"multiple": true}
makes all filters multiple-selects{"class": "form-select"}
adds aclass="form-select"
to all selects
- value: filter-specific value attributes. Keys are the filter names. Values are value attribute scalars or functions
{"city": {"class": "small"}}
addsclass="small"
to all options in thecity
filter
- values: common value attributes
{"class": "small"}
addsclass="small"
to all options in all filters
Depending on the type
, field and value attributes are treated specially, as below.
type="select"
field
/fields
attributes:
name
: sets<select name="${name}">
. E.g.name: "city"
value
: currently selected value. Setsselected
attribute on matching items. E.g.value: "LON"
label
: sets<label>${label} ...</label>
. E.g.label: "City"
default
: avalue
object to use as default, if it's missing invalues
. E.g.default: "-"
ordefault: {label: "All", value: ""}
multiple: true
: setsmultiple
on<select>
. E.g.multiple: true
values
: list of values to render as options. Defaults todata[name]
selector
: renders existing<select>
elements if found. E.g.selector: "select[data-name="${name}]"
renders matching<select data-name="...">
if they exist, else creates new onesrender
: function to render HTML if no<select>
is found. Defaults roughly to({label, name}) => `<label>${label} <select name="${name}"></select></label>`;
value
/values
attributes:
value
: sets<option value="${value}">
label
: sets<option>${label}</option>
. Defaults tovalue
render
: function to render HTML if no<option>
is found. Defaults roughly to({label, value}) => `<option value="${value}">${label}</option>`;
type="bs5"
field
/fields
attributes:
name
: sets<div class="dropdown ${name}">
. E.g.name: "city"
value
: currently selected value. Setsclass="active"
on matching items. E.g.value: "LON"
label
: sets<button>${label}</button>
. Defaults toname
. E.g.label: "City"
multiple
: TODO: not implemented yetdefault
: avalue
object to use as default, if it's missing invalues
E.g.default: "-"
ordefault: {label: "All", value: ""}
buttonClass
: sets<button class="dropdown-toggle ${buttonClass}">
dropdownClass
: sets<div class="dropdown ${dropdownClass}">
menuClass
: sets<ul class="dropdown-menu ${menuClass}"></ul>
values
: list of values to render as options. Defaults todata[name]
selector
: renders existing.dropdown
elements if found.render
: function to render HTML if no.dropdown
is found
value
/values
attributes:
value
: setsactive
class on.dropdown-item
ifvalue
matches the current valuelabel
: sets<li><a class="dropdown-item"}>${label}</a></li>
. Defaults tovalue
render
: function to render HTML if no<option>
is found. Defaults roughly to({label}) => <li><a class="dropdown-item">${label}</a></li>
Examples
Fetch data from URL
This loads data from data-sales.json
and renders it as filters into the <form>
.
<form></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form",
url: "data-sales.json",
});
</script>
Sample data-sales.json
:
{
"product": ["Alpha", "Beta", "Gamma"],
"city": ["London", "Oslo", "Paris"],
"channel": ["Direct", "Indirect"]
}
This renders:
Add classes to field
Add fields.class
to specify classes for all fields:
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<form class="d-flex"></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form",
url: "data-sales.json",
fields: { class: "form-select me-2" },
});
</script>
This renders:
Use existing HTML
To apply the filters to existing (styled) HTML, the <select>
elements should have a name=
,
class=
or id=
that matches the field name.
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<form class="row">
<div class="col"><select name="city" class="form-select"></select></div>
<div class="col"><select name="product" class="form-select"></select></div>
<div class="col"><select name="channel" class="form-select"></select></div>
</form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form",
url: "data-sales.json",
});
</script>
This re-uses the existing <select>
elements in the same order and style as in the HTML:
Set selected values
Add fields.value
to set selected values:
<form class="d-flex"></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form",
url: "data-sales.json",
fields: { value: { product: "Beta", city: "Oslo", channel: "Direct" } },
});
</script>
This renders:
Set custom labels
Add value.[name].label
to set custom labels:
<form></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
const productDetails = {
Alpha: "Version Alpha: $100",
Beta: "Version Beta: $400",
Gamma: "Version Gamma: $1,000",
};
render({
container: "form",
url: "data-sales.json",
value: {
product: { label: ({ value }) => productDetails[value] },
},
});
</script>
This renders:
Add default value
Add fields.default.[name]
to add a default value:
<form></form>
<script type="module">
import { render } from "node_modules/@gramex/filters/filters.js";
render({
container: "form",
url: "data-sales.json",
fields: {
default: {
product: { label: "Any product", value: "" },
city: { label: "Any city", value: "" },
channel: { label: "Any channel", value: "" },
},
},
});
</script>
This renders: