The request URL is constructed from filters that have a non default state.
The URL is used in the HTTP request to retrieve new data.
A ‘sticky’ Filter shown below is always serialized in request URL.
{
name: "sticky",
type: "text",
default: "svalue",
channels: ["_REQ"],
req: {
sticky: true
}
}
You can reset all filters by calling the reset function in fireman object.
Copy to clipboard
fireman.reset();
In order to build the containers and filters you can call the build function of the
fireman instance.
Copy to clipboard
fireman.build();
or
fireman.build(scopeElement); // scopeElement is the element selector in which the fireman will scan for configuration.
You can restore the filter’s state from browser’s URL using the restore function of fireman instance.
Copy to clipboard
fireman.restore();
Fireman can enter a state where user can interact with filters but no request is happening and the URL is
not refreshing.
Fireman will record all state changes and when commit() is called then all the changes
that are recorded are executed. The browser URL is refreshed and a new request is issued.
This case could be helpful for example when the user opens a modal with filter, changes various
filters but the changes are commited only when the user presses a save/update button of the modal.
If the user does not want the changes to be commited then the revert() function can be used .
In order to exit from this state and make Fireman operate as before the exitOnHold() function us used
Copy to clipboard
fireman.onHold();
The commit() function is used when the Fireman is under the ‘OnHold’ and makes a new
ajax request and refreshes the browser’s URL.
Copy to clipboard
fireman.commit();
In case the user wants to revert all changes made when in ‘OnHold’, the revert()
function can be used.
Copy to clipboard
fireman.revert()
When we want to exit the ‘OnHold’ we can call exitOnHold(). This has effect only if
we are already in onHold state.
Copy to clipboard
fireman.existOnHold();
This section contains most of the Filters used in the DEMO application. You can
click in each section to know how the particular Filter is configured.
The map Filter is an ArrayFilter of numbers of length 5.
It is binded to a google maps element using the adaptor ‘gmaps’
JSON
DOM
Copy to clipboard
{
name: "gmaps",
channels: ["_REQ", "_URL"],
sensitivity: "gmaps",
default: [37.98714531154326, 23.702719185180648, 37.997291713751025, 23.709070656127913, 15],
state: [
{
adaptor: "gmaps",
target: "#map",
params: {
zoom: 15,
center: { lat: 37.990832, lng: 23.70332 },
disableDefaultUI: true,
gestureHandling: 'greedy'
},
},
],
}
<div filter name="gmaps" id="gmaps" channels="_REQ, _URL"
default="[37.98714531154326, 23.702719185180648, 37.997291713751025, 23.709070656127913, 15]"
adaptor-params='{"zoom": 15, "center": { "lat": 37.990832, "lng": 23.70332 }, "disableDefaultUI": true, "gestureHandling": "greedy"}'
sensitivity="gmaps" filter-adaptor="gmaps">
<div adaptor-target id="map" style="height: 300px;">
</div>
</div>
The gmaps adaptor is
part of the Full Extensions Package
in documentation >
Packages .
JSON
DOM
Attribute
DOM
Element
{
id: "manufactured",
name: "manufactured",
...
{
id: "selected",
target: "#selected-manufactured",
text: "'from ' + $fs[0] | dt_to_str + ' to ' + $fs[1] | dt_to_str"
}
}
<input filter filter-id="manufactured" name="manufactured"
...
content-selected="'from ' + $fs[0] | dt_to_str + ' to ' + $fs[1] | dt_to_str">
<div>
<button content-id="selected" filter-id="manufactured" type="button">default content</button>
<div filter-reset filter-id="manufactured">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'asus',
name: 'asus',
...
{
id: 'selected',
text: "$fn | upper"
}
}
<div filter name="asus" filter-id="asus"
...
content-selected="$fn | upper">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="asus" type="button">default content</button>
<div filter-reset filter-id="asus">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'lenovo',
name: 'lenovo',
...
{
id: 'selected',
text: "$fn | upper"
}
}
<div filter name="lenovo" filter-id="lenovo"
...
content-selected="$fn | upper">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="lenovo" type="button">default content</button>
<div filter-reset filter-id="lenovo">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: '4GB',
name: '4GB',
...
content: [
{
id: 'selected',
text: "$fn"
}
]
}
<div filter name="4GB" filter-id="4GB"
...
content-selected="$fn">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="4GB" type="button">default content</button>
<div filter-reset filter-id="4GB">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: '8GB',
name: '8GB',
...
content: [
{
id: 'selected',
text: "$fn"
}
]
}
<div filter name="8GB" filter-id="8GB"
...
content-selected="$fn">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="8GB" type="button">default content</button>
<div filter-reset filter-id="8GB">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: '16GB',
name: '16GB',
...
content: [
{
id: 'selected',
text: "$fn"
}
]
}
<div filter name="16GB" filter-id="16GB"
...
content-selected="$fn">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="16GB" type="button">default content</button>
<div filter-reset filter-id="16GB">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'HDD',
name: 'HDD',
...
content: [
{
id: 'selected',
text: "$fn"
}
]
}
<div filter name="HDD" filter-id="HDD"
...
content-selected="$fn">
<input type="radio" name="diskType">
</div>
<div>
<button content-id="selected" filter-id="HDD" type="button">default content</button>
<div filter-reset filter-id="HDD">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'SSD',
name: 'SSD',
...
content: [
{
id: 'selected',
text: "$fn"
}
]
}
<div filter name="SSD" filter-id="SSD"
...
content-selected="$fn">
<input type="radio" name="diskType">
</div>
<div>
<button content-id="selected" filter-id="SSD" type="button">default content</button>
<div filter-reset filter-id="SSD">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'over500GB',
name: 'over500GB',
...
content: [
{
id: 'selected',
text: "'Over 500GB of disk'"
}
]
}
<div filter name="over500GB" filter-id="over500GB"
...
content-selected="'Over 500GB of disk'" class="form-check">
<input type="checkbox">
</div>
<div>
<button content-id="selected" filter-id="over500GB" type="button">default content</button>
<div filter-reset filter-id="over500GB">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'availability',
name: 'availability',
...
content: [
{
id: 'selected',
text: "$fs | upper"
}
]
}
<div filter name="availability" filter-id="availability"
...
content-selected="$fs | upper">
</div>
<div>
<button content-id="selected" filter-id="availability" type="button">default content</button>
<div filter-reset filter-id="availability">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'sku',
name: 'sku',
...
content: [
{
id: 'selected',
text: "sku:$fs"
}
]
}
<input filter name="sku" filter-id="sku"
...
content-selected="sku:$fs">
<div>
<button content-id="selected" filter-id="sku" type="button">default content</button>
<div filter-reset filter-id="sku">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'gpu',
name: 'gpu',
...
content: [
{
id: "selected",
text: "$fs | upper"
}
]
}
<div filter name="gpu" filter-id="gpu"
content-selected="$fs | upper">
...
<select>
...
</select>
</div>
<div>
<button content-id="selected" filter-id="gpu" type="button">default content</button>
<div filter-reset filter-id="gpu">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'reviews',
name: 'reviews',
...
content: [
{
id: "selected",
text: "over $fs + ' ' + $fn"
}
]
}
<div filter id="reviews" name="reviews"
...
content-selected="over $fs + ' ' + $fn">
</div>
<div>
<button content-id="selected" filter-id="reviews" type="button">default content</button>
<div filter-reset filter-id="reviews">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'price',
name: 'price',
...
content: [
{
id: 'selected',
text: "{'from ' + !!$fs[0]eur} + ' ' + {'to ' + !!$fs[1]eur}"
}
]
}
<div filter name="price" filter-id="price"
content-selected="{'from ' + !!$fs[0]eur} + ' ' + {'to ' + !!$fs[1]eur}">
...
<input type="number" class="form-control">
...
<input type="number" class="form-control">
...
</div>
<div>
<button content-id="selected" filter-id="price" type="button">default content</button>
<div filter-reset filter-id="price">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'screen',
name: 'screen',
...
content: [
{
id: 'selected',
text: "{'from ' + !!$fs[0]inch} + ' ' + {'to ' + !!$fs[1]inch}"
}
]
}
<div filter name="screen" filter-id="screen"
content-selected="{'from ' + !!$fs[0]inch} + ' ' + {'to ' + !!$fs[1]inch}"
...>
<input>
</div>
<div>
<button content-id="selected" filter-id="screen" type="button">default content</button>
<div filter-reset filter-id="screen">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'weight',
name: 'weight',
...
content: [
{
id: 'selected',
text: "{'from ' + !!$fs[0]inch} + ' ' + {'to ' + !!$fs[1]inch}"
}
]
}
<div filter filter-id="weight" name="weight"
content-selected="{'from ' + !$fs[0]gr} + ' ' + { 'to ' + !$fs[1]gr}">
</div>
<div>
<button content-id="selected" filter-id="weight" type="button">default content</button>
<div filter-reset filter-id="weight">x</div>
</div>
JSON
DOM
Attribute
DOM
Element
{
id: 'quantity',
name: 'quantity',
...
content: [
{
id: 'selected',
text: "in stock:$fs",
}
]
}
<input filter name="quantity" filter-id="quantity"
content-selected="in stock:$fs">
<div>
<button content-id="selected" filter-id="quantity" type="button">default content</button>
<div filter-reset filter-id="quantity">x</div>
</div>
The quantity Filter is a number Filter binded to an element controlled by the ‘knob’ jquery library.
JSON
DOM
Copy to clipboard
{
id: "quantity",
name: "quantity",
default: 5,
channels: ["selected", "_REQ", "_URL"],
state: [
{
adaptor: "knob",
target: ".dial",
params: {
min: 0,
max: 10,
width: 100,
height: 100,
cursor: true,
thickness: .4
},
},
],
filtering: {
type: 'greaterthan',
key: 'quantity',
},
content: [
{
id: 'selected',
text: "in stock:$fs",
},
]
}
<input filter name="quantity" filter-id="quantity" channels="_REQ, _URL, selected"
default="5" filter-adaptor="knob" type="text" value="5" filtering="greaterthan"
content-selected="in stock:$fs" reset='{ "target": "#reseter-quantity" }'
adaptor-params='{ "min": 0, "max": 10, "width": 100, "height": 100, "cursor": true, "thickness": 0.4}'>
The knob adaptor is
part of the Full Extensions Package
in documentation >
Packages .
The weight Filter is an Array Filter of numbers of length 2.
It is binded to an element controlled by the ‘nouislider’ jquery library
JSON
DOM
Copy to clipboard
{
id: "weight",
name: "weight",
default: [100, 1000],
channels: ["selected", "_REQ", "_URL"],
url: {
type: "split",
postfix: ["From", "To"],
},
req: {
type: "split",
postfix: ["From", "To"],
},
filtering: {
type: "between"
},
state: [
{
target: "#slider",
adaptor: "nouislider",
params: {
start: [300, 800],
connect: true,
tooltips: [true, true],
range: {
min: 50,
max: 2000
}
},
}
],
content: [
{
id: 'selected',
text: "{'from ' + !$fs[0]gr} + ' ' + { 'to ' + !$fs[1]gr}",
}
]
}
<div filter filter-id="weight" name="weight" default="[100, 1000]"
channels="_REQ, _URL, selected" filtering="between"
filter-adaptor="nouislider" reset='{ "target": "#reseter-weight" }'
adaptor-params='{"start": [300, 800], "connect": true, "tooltips": [true, true], "range": { "min": 50, "max": 2000 } }'
url='{"type" : "split", "postfix" : ["From", "To"]}'
req='{"type" : "split", "postfix" : ["From", "To"]}' adaptor-target
content-selected="{'from ' + !$fs[0]gr} + ' ' + { 'to ' + !$fs[1]gr}" id="slider">
</div>
The nouislider adaptor is
part of the Full Extensions Package
in documentation >
Packages .
The screen Filter is an Array Filter of numbers of length 2.
It binds to an element controlled by the ‘bootstrap-slider’ jquery library.
JSON
DOM
Copy to clipboard
{
id: "screen",
name: "screen",
channels: ["selected", "_REQ", "_URL"],
default: [15, 20],
state: [
{
adaptor: "bootstrap-slider",
target: "#screenRange",
params: {
range: true,
tooltip_split: true,
min: 10,
max: 24,
step: 1,
value: [15, 20],
tooltip: 'always'
}
},
],
url: {
infix: "-",
},
filtering: {
type: "between"
},
content: [
{
id: 'selected',
text: "{'from ' + !!$fs[0]inch} + ' ' + {'to ' + !!$fs[1]inch}"
},
{
target: "#screenLbl",
text: "{'From ' + !$fs[0]inch + ' to ' + !$fs[1]inch}?{Select Screen Size}"
},
]
}
<label content="{'From ' + !$FS['screen'][0]inch + ' to ' + !$FS['screen'][1]inch}?{Select Screen Size}"
filter-id="screen" id="screenLbl" for="priceRange">Screen size</label>
...
<div class="row mb-3">
<div filter name="screen" filter-id="screen" channels="_REQ, _URL, selected"
default="[15,20]" url='{ "infix": "-" }' filtering="between"
content-selected="{'from ' + !!$fs[0]inch} + ' ' + {'to ' + !!$fs[1]inch}"
filter-adaptor="bootstrap-slider" reset='{ "target": "#reseter-screen" }'
adaptor-params='{"range": true, "tooltip_split": true, "min": 10, "max": 24, "step": 1, "value": [15, 20], "tooltip": "always"}'>
<input type="range" id="screenRange">
</div>
</div>
The bootstrap-slider adaptor is
part of the Full Extensions Package
in documentation >
Packages .
The price Filter is an ArrayFilter of numbers of length 2. It is binded to two input elements.
JSON
DOM
Copy to clipboard
{
id: "price",
name: "price",
default: [0, 0],
channels: ["selected", "_REQ", "_URL"],
url: {
type: "split",
postfix: ["From", "To"],
},
req: {
type: "split",
postfix: ["From", "To"],
},
filtering: {
type: "between"
},
state: [
{ targets: ["#minPriceInput", "#maxPriceInput"] },
],
content: [
{
id: 'selected',
text: "{'from ' + !!$fs[0]eur} + ' ' + {'to ' + !!$fs[1]eur}"
}
]
}
<div filter name="price" filter-id="price" channels="_REQ, _URL, selected"
default="[0,0]" url='{"type" : "split", "postfix" : ["From", "To"]}'
req='{"type" : "split", "postfix" : ["From", "To"]}' filtering="between"
content-selected="{'from ' + !!$fs[0]eur} + ' ' + {'to ' + !!$fs[1]eur}"
reset='{ "target": "#reseter-price" }'>
<input type="number" id="minPriceInput">
<input type="number"id="maxPriceInput">
</div>
The content of this button is automatically updated from the binded content on it.
JSON
DOM
Copy to clipboard
...
content: [
{
id: 'selected',
text: "{'from ' + !$fs[0]gr} + ' ' + { 'to ' + !$fs[1]gr}",
}
]
<button fireman-content="{'weight ' + !!$FS['weight']}?{'weight'}"></button>
The content of this button is automatically updated from the binded content on it.
DOM
Copy to clipboard
<button type="button" >Reviews <span class="badge badge-light" fireman-content="{!$FS['reviews']}?{0}"></span></button>
The reviews Filter is a number Filter that binds to an element controlled by a jquery library (dialer
adaptor).
JSON
DOM
Adaptor
Copy to clipboard
{
id: "reviews",
name: "reviews",
default: 2,
channels: ["selected", "_REQ", "_URL"],
state: [
{
adaptor: "dialer",
target: "#reviews-adaptor-target",
params: {
min: 0,
max: 20
}
},
],
filtering: {
type: 'greaterthan'
},
content: [
{
id: "selected",
text: "over $fs + ' ' + $fn"
},
]
}
<div filter default="2" filter-params='{"min" : 0, "max" : 20}'
filter-adaptor="dialer" id="reviews" name="reviews" filtering="greaterthan"
reset='{ "target": "#reseter-reviews" }' channels="_REQ, _URL, selected"
content-selected="over $fs + ' ' + $fn" dialer-watch>
<div adaptor-target id="reviews-adaptor-target" dialer dialer-min="0"
dialer-max="20">
<input />
</div>
</div>
class DialerAdaptor extends StateAdaptor {
encoderType() {
return 'number';
}
identifier() {
return 'dialer';
}
sync(value, defaultValue) {
let dialer = $(this.target).data('dialer');
dialer.val(value);
}
bind() {
$(this.target).on('dialer-change', function (ev) {
let value = $(ev.currentTarget).find('input').val();
this.listener.changeStateRequested(this, value);
}.bind(this));
}
}
The sortby Filter is binded to a select element. It has also a _SORTING role. That means
when we filter the data on the client (‘client’ configuration) this Filter will sort the data.
JSON
DOM
Copy to clipboard
{
name: "sortby",
type: "text",
role: {
type: "_SORTING",
precedence: 0,
rules: [
{
value: "price-low-to-high",
key: "price",
order: "asc"
},
{
value: "price-high-to-low",
key: "price",
order: "desc"
},
{
value: "weight-low-to-high",
key: "weight",
order: "asc"
},
{
value: "weight-high-to-low",
key: "weight",
order: "desc"
}
]
},
default: "none",
channels: ["_REQ", "_URL"],
state: [
{ target: "#sortBySelect" }
]
}
<select filter name="sortby" channels="_REQ, _URL" default="none" filter-role='{"type": "_SORTING", "precedence": 0, "rules": [
{"value": "price-low-to-high", "key": "price", "order": "asc" },
{"value": "price-high-to-low", "key": "price", "order": "desc"},
{"value": "weight-low-to-high", "key": "weight", "order": "asc"},
{"value": "weight-high-to-low", "key": "weight", "order": "desc"}]}' id="sortBySelect">
<option value="none">none</option>
<option value="price-low-to-high">price (low to high)</option>
<option value="price-high-to-low">price (high to low)</option>
<option value="weight-low-to-high">weight (low to high)</option>
<option value="weight-high-to-low">weight (high to low)</option>
</select>
The gpu Filter is binded to a select element. It also updates the text of label with id ‘gpuLabel’ to
‘GPU’
JSON
DOM
Copy to clipboard
{
id: "gpu",
name: "gpu",
default: "all",
channels: ["selected", "_REQ", "_URL"],
state: [
{ target: "#gpuSelect" },
],
reset: [
{ target: "#reseter-gpu" }
],
content: [
{
id: "selected",
text: "$fs | upper"
},
{ target: "#gpuLabel", text: "GPU" },
]
}
<div filter name="gpu" filter-id="gpu" default="all" channels="_REQ, _URL, selected"
reset='{ "target": "#reseter-gpu" }' content-selected="$fs | upper">
<div class="card-body">
<div>
<select id="gpuSelect">
<option value="all">all</option>
<option value="nvidia">nvidia</option>
<option value="intel">intel</option>
<option value="amd">AMD</option>
</select>
</div>
</div>
</div>
Page Filter is a number filter with a _PAGE role. The _PAGE role applies
only when data are filtered on the client.
It also has a ‘pagenator’ adaptor.
JSON
DOM
Adaptor
Copy to clipboard
{
name: "page",
role: {
type: "_PAGE",
},
default: 0,
channels: ["_REQ"],
state: [
{ adaptor: "pagenator", target: ".pagination" }
]
}
<ul filter name="page" filter-id="page" filter-role="_PAGE"
filter-adaptor="pagenator" default="0" adaptor-target class="pagination"
channels="_REQ">
<li class="page-item">
<a class="page-link" href="#" pageno="pre" aria-label="Previous">
<span aria-hidden="true">«</span>
<span class="sr-only">Previous</span>
</a>
</li>
<li class="page-item"><a class="page-link" pageno="0" href="#">1</a></li>
<li class="page-item"><a class="page-link" pageno="1" href="#">2</a></li>
<li class="page-item"><a class="page-link" pageno="2" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#" pageno="next" aria-label="Next">
<span class="sr-only">Next</span>
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
class PagenatorAdaptor extends StateAdaptor {
encoderType() {
return 'number';
}
identifier() { return 'pagenator'; }
pageNo = 0;
sync(value, defaultValue) {
$(this.target).find('li').removeClass('active');
let el = $(this.target).find('li a[pageno="' + value + '"]');
el.closest('li').addClass('active');
}
bind() {
const self = this;
$(this.target).find(' li a').on('click', (event, target) => {
let pageNoAttr = $(event.currentTarget).attr('pageno');
if (pageNoAttr === 'next') {
this.pageNo++;
} else if (pageNoAttr === 'pre') {
if (this.pageNo <= 0)
return;
this.pageNo--;
} else
this.pageNo = parseInt(pageNoAttr);
self.listener.changeStateRequested(self, this.pageNo, true);
});
}
}
The sku Filter is a simple text Filter that binds to two different input text elements. When
one input is changed it synchronizes automatically the other.
JSON
DOM
Copy to clipboard
{
id: "sku",
name: "sku",
type: "text",
default: "",
channels: ["selected", "_REQ", "_URL"],
state: [
{ target: "#skuInput" },
{ target: "#skuInput2" },
],
reset: [
{ target: "#reseter-sku" }
],
content: [
{
id: 'selected',
text: "sku:$fs"
}
],
}
<div>
<input filter name="sku" filter-id="sku" reset='{ "target": "#reseter-sku" }'
content-selected="sku:$fs" default="" channels="_REQ, _URL, selected"
type="text" id="skuInput">
</div>
<div>
<label>duplicated</label>
<input type="text" filter-id="sku" filter-state id="skuInput2">
</div>
The gift Filter is binded to two button elements. It is included in the request URL but does not
trigger a request when its state is changed (req=false).
JSON
DOM
Copy to clipboard
{
name: "gift",
channels: ["_REQ", "_URL"],
state: [
{
adaptor: "buttons",
req: false,
targets: [
"#giftBtn1",
"#giftBtn2"
]
},
],
reset: [
{ target: "#reseter-gift" }
]
}
<div filter name="gift" channels="_REQ, _URL" reset='{ "target": "#reseter-gift" }'
filter-adaptor='{ "type" : "buttons", "req" : false }'>
<button id="giftBtn1" value="0">its not a gift</button>
<br>
<button id="giftBtn2" value="1">wrap it</button>
</div>
The buttons adaptor is part of the core library.
The availability Filter is binded to two buttons and one a element.
JSON
DOM
Copy to clipboard
{
id: "availability",
name: "availability",
channels: ["selected", "_REQ", "_URL"],
state: [
{
adaptor: "buttons",
targets: [
"#availabilityBtn1",
"#availabilityBtn2",
"#availabilityBtn3"
]
},
],
content: [
{
id: 'selected',
text: "$fs | upper"
}
]
}
<div filter name="availability" filter-id="availability" channels="selected, _REQ, _URL"
reset='{ "target": "#reseter-availability" }' content-selected="$fs | upper"
filter-adaptor="buttons">
<button value="immediately" id="availabilityBtn1">immediately</button>
<button value="2_3days" id="availabilityBtn2">Within 2-3 days</button>
<br>
<a value="1week" id="availabilityBtn3" >1 week</a>
</div>
The buttons adaptor is part of the core library.
We use the model FilterContainer in order to group two boolean
Filters together (named 'asus' and 'lenovo').
JSON
DOM
Copy to clipboard
{
name: "model",
filters: [
{
id: 'asus',
name: 'asus',
channels: ["selected", "_REQ", "_URL"],
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
state: [
{
target: "#asusCheck"
}
],
filtering: {
mode: 1
},
content: [
{
id: 'selected',
text: "$fn | upper"
},
{
target: "#asusLabel",
text: "{$fn | upper} + ' state: ' + $fs"
}
]
},
{
id: 'lenovo',
name: 'lenovo',
channels: ["selected", "_REQ", "_URL"],
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
filtering: {
mode: 1
},
state: [
{
target: "#lenovoCheck"
}
],
content: [
{
target: "#lenovoCheckLabel",
text: "$fn | upper"
},
{
id: 'selected',
text: "$fn | upper"
}
]
}
]
}
<div container name="model">
<div filter name="asus" filter-id="asus"
channels="selected, _REQ, _URL" req='{ "type": "container-filter"}'
url='{ "type": "container-filter"}' filtering='{ "mode": 1 }'
content-selected="$fn | upper" reset='{ "target": "#reseter-asus" }'>
<input type="checkbox" class="form-check-input" id="asusCheck">
<label id="asusLabel" class="form-check-label" for="asusCheck"
content="{$fn | upper} + ' state: ' + $fs"></label>
</div>
<div filter filter-id="lenovo" filter-name="lenovo"
channels="selected, _REQ, _URL" req='{ "type": "container-filter"}'
url='{ "type": "container-filter"}' filtering='{ "mode": 1 }'
content-selected="$fn | upper" reset='{ "target": "#reseter-lenovo" }'>
<input type="checkbox" class="form-check-input" id="lenovoCheck">
<label id="lenovoCheckLabel" content="$fn | upper" class="form-check-label"
for="lenovoCheck"></label>
</div>
</div>
We use a FilterContainer named 'ram' in order to group three boolean Filters, named '4GB',
'8GB' and '16GB'.
JSON
DOM
Copy to clipboard
{
name: "ram",
filters: [
{
id: '4GB',
name: '4GB',
channels: ["selected", "_REQ", "_URL"],
state: [
{
target: "#gb4Check"
}
],
filtering: {
mode: 1
},
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
content: [
{
target: "#gb4CheckLabel",
text: "4GB"
},
{
id: 'selected',
text: "$fn"
}
],
reset: [
{ target: "#reseter-4GB" }
]
},
{
id: '8GB',
name: '8GB',
channels: ["selected", "_REQ", "_URL"],
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
filtering: {
mode: 1
},
content: [
{
id: 'selected',
text: "$fn"
}
],
state: [
{
target: "#gb8Check"
}
],
reset: [
{ target: "#reseter-8GB" }
]
},
{
id: '16GB',
name: '16GB',
channels: ["selected", "_REQ", "_URL"],
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
filtering: {
mode: 1
},
state: [
{
target: "#gb16Check"
}
],
content: [
{
id: 'selected',
text: "$fn"
}
],
reset: [
{ target: "#reseter-16GB" }
]
}
]
}
<div container name="ram">
<div filter name="4GB" filter-id="4GB" channels="selected,_REQ,_URL"
filtering='{ "mode": 1 }' req='{ "type": "container-filter"}'
url='{ "type": "container-filter"}' content-selected="$fn"
reset='{ "target": "#reseter-4GB" }' class="form-check">
<input type="checkbox" id="gb4Check">
<label content="$fn" id="gb4CheckLabel" for="gb4Check"></label>
</div>
<div filter name="8GB" filter-id="8GB" channels="selected,_REQ,_URL"
filtering='{ "mode": 1 }' req='{ "type": "container-filter"}'
url='{ "type": "container-filter"}' reset='{ "target": "#reseter-8GB" }'
content-selected="$fn" >
<input type="checkbox" id="gb8Check">
<label for="gb8Check">8 GB</label>
</div>
<div filter name="16GB" filter-id="16GB" channels="selected,_REQ,_URL"
filtering='{ "mode": 1 }' req='{ "type": "container-filter"}'
url='{ "type": "container-filter"}' reset='{ "target": "#reseter-16GB" }'
content-selected="$fn">
<input type="checkbox" id="gb16Check">
<label for="gb16Check">16 GB</label>
</div>
</div>
The 'disk' FilterContainer has two filters. They are bind to radio buttons. In order to make
the radio button filters to reset each other we add an
additional 'group' property.
The other is a boolean Filter named 'over500GB' and has its own FilterContainer
JSON
DOM
Copy to clipboard
{
name: "disk",
filters: [
{
id: 'HDD',
name: 'HDD',
channels: ["selected", "_REQ", "_URL"],
group: 'disk_type',
state: [
{
target: "#hdd"
}
],
filtering: {
mode: 1
},
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
content: [
{
target: "#hddLabel",
text: "$fn"
},
{
id: 'selected',
text: "$fn"
}
]
},
{
id: 'SSD',
name: 'SSD',
channels: ["selected", "_REQ", "_URL"],
group: 'disk_type',
url: {
type: "container-filter"
},
req: {
type: "container-filter"
},
filtering: {
mode: 1
},
state: [
{
target: "#ssd"
}
],
content: [
{
id: 'selected',
text: "$fn"
}
]
}
]
}
{
id: 'over500GB',
name: 'over500GB',
channels: ["selected", "_REQ", "_URL"],
state: [
{
target: "#over500GB"
}
],
reset: [
{ target: "#reseter-over500GB" }
],
content: [
{
id: 'selected',
text: "'Over 500GB of disk'"
}
],
}
<div container name="disk">
<div filter name="HDD" filter-id="HDD" channels="selected,_REQ,_URL"
filtering='{ "mode": 1 }' reset='{ "target": "#reseter-HDD" }'
url='{ "type": "container-filter"}' content-selected="$fn">
<input type="radio" name="diskType" id="hdd">
<label content="$fn" id="hddLabel" for="hdd"></label>
</div>
<div filter name="SSD" filter-id="SSD" channels="selected,_REQ,_URL"
filtering='{ "mode": 1 }' reset='{ "target": "#reseter-SSD" }'
url='{ "type": "container-filter"}' content-selected="$fn">
<input type="radio" name="diskType" id="ssd">
<label for="ssd">SSD</label>
</div>
</div>
<div filter name="over500GB" filter-id="over500GB"
reset='{ "target": "#reseter-over500GB" }' channels="selected,_REQ,_URL"
content-selected="'Over 500GB of disk'" class="form-check">
<input type="checkbox" id="over500GB">
<label for="over500GB">over 500GB</label>
</div>
You can update multiple filter states bypassing the desired values in json format in a 'fireman-state'
attribute
Copy to clipboard
<button fireman-state='{"price" :[800,2000], "screen" :[15,20], "reviews":10, "16GB":true, "8GB":true, "gpu":"nvidia"}'
class="btn btn-primary btn-sm">HighEnd Laptops</button>
The Filter identifier/key can be either its id or name.
You can update multiple filter states bypassing the desired values in json format in a 'fireman-state'
attribute
Copy to clipboard
<button fireman-state='{"price": [0,800], "4GB":true, "screen":[11,16], "reviews":4, "gpu":"intel", "weight":[800, 1500]}'
class="btn btn-primary btn-sm">LowEnd Laptops</button>
The Filter identifier/key can be either its id or name.
All the rules that are applied in fireman:
1. Reset Paging every time a filter is changed
fireman.rule('pageResetRule')
.whenStateChangesOfAll(x => x.getFiltersWithNoRole())
.thenResetFor(x => x.getFilterByRole("_PAGE"));
Optionaly you can add a listener to this rule
fireman.subscribe('pageResetRule', new PageRuleListener());
class PageRuleListener extends RuleListener {
onExecuteBeforeStateChange(filter) {
console.log('onExecuteBeforeStateChange', filter);
};
onExecuteAfterStateChange(filter) {
console.log('onExecuteAfterStateChange', filter);
};
onExecuteBeforeReset(filter) {
console.log('onExecuteBeforeReset', filter);
};
onExecuteAfterReset(filter) {
console.log('onExecuteAfterReset', filter);
};
}
In order to access the results from the HTTP request you register a ResultsListener
to Fireman instance
Copy to clipboard
class ResultsComponent extends ResultsListener {
onBeforeHandler(url) {
document.getElementById('urlContainer').textContent = url;
$.blockUI({ message: '', css: { backgroundColor: 'transparent' } });
}
onErrorHandler(err) {
$.unblockUI();
}
resultsReceivedHandler(data) {
let container = $($('[item-container]')[0]);
container.empty();
let template = $($('[item-template]')[0]);
let html = template.html();
data.forEach(item => {
let resolved = html.replace('{{name}}', item.name)
.replace('{{description}}', item.description)
.replace('{{ram}}', item.ram)
.replace('{{model}}', item.model)
.replace('{{weight}}', item.weight)
.replace('{{sku}}', item.sku)
.replace('{{quantity}}', item.quantity)
.replace('{{disk}}', item.disk)
.replace('{{manufactured}}', item.manufactured)
.replace('{{price}}', item.price)
.replace('{{gpu}}', item.gpu)
.replace('{{reviews}}', item.reviews)
.replace('{{screen}}', item.screen)
.replace('{{availability}}', item.availability);
if (item.over500GB) {
resolved = resolved.replace('{{over500GB}}', `over 500GB `);
} else
resolved = resolved.replace('{{over500GB}}', "");
let el = $(resolved);
container.append(el);
});
}
onCompletedHandler() {
$.unblockUI();
}
}
fireman.subscribeResultsListener(new ResultsComponent());
Manufactured is a datetime Array Filter that has two adaptors.
JSON
DOM
Copy to clipboard
{
id: "manufactured",
name: "manufactured",
default: ['01/11/2021', '02/11/2021'],
channels: ["selected", "_REQ", "_URL"],
url: {
infix: '_to_'
},
req: {
infix: '_to_'
},
filtering: {
type: "between"
},
state: [
{
adaptor: "daterangepicker",
target: "#manufacturedInput",
params: {
locale: { format: 'DD/MM/YYYY' },
format: 'DD/MM/YYYY'
},
},
{
adaptor: "jquery-date-range-picker-int",
target: "#date-range-id",
params: {
format: 'DD/MM/YYYY',
inline: true,
container: '#date-range-id',
alwaysOpen: true
},
},
],
content: [
{
id: "selected",
target: "#selected-manufactured",
text: "'from ' + $fs[0] | dt_to_str + ' to ' + $fs[1] | dt_to_str"
},
]
}
<input filter filter-id="manufactured" name="manufactured" url='{"infix" : "_to_"}'
req='{"infix" : "_to_"}' filtering='{ "type": "between" }'
channels="selected, _REQ, _URL" default='["01/11/2021", "02/11/2021"]'
filter-adaptor="daterangepicker"
content-selected="'from ' + $fs[0] | dt_to_str + ' to ' + $fs[1] | dt_to_str"
adaptor-params='{ "locale": { "format": "DD/MM/YYYY" }, "format": "DD/MM/YYYY"}'>
...
<div filter-state filter-id="manufactured"
filter-adaptor="jquery-date-range-picker-int"
adaptor-params='{ "format": "DD/MM/YYYY", "inline": true, "container": "#date-range-id", "alwaysOpen": true }'
adaptor-target id="date-range-id">
</div>
The daterangepicker and jquery-date-range-picker adaptors are
part of the Full Extensions Package
in documentation >
Packages .