Filter chips
Predicate editors
Click on the filter chips to see the predicate editor.
Lists of options
Multi select (with optional searchbar)
Single select
User inputs
Money
Number
Percent
String
Filter editor lists
Single select
Multi select
Filter editor inputs
Filter editor money
Filter editor number
Filter editor percent
Filter editor string
Filter predicate operator
type NUMERIC
type STRING_SHORT
type STRING_LONG
Description
Filter components are a set of helper components that are all used in the wui-filterbar
, but can also be used individually. The set includes various input UIs (predicate editors) such as single or multi select, numeric or text input.
Filter chips
Filter chips are labels that display the filters selected by the user. The labels automatically format the output for multiple filter options, depending on the value of numberVisibleValues
and operator
.
Example: Basic usage
<template>
<div>
<wui-filter-chip
label="Status"
:value="values"
@remove="handleRemoveEvent"
/>
</div>
</template>
<script>
export default {
data() {
return {
values: [
{
value: "PENDING",
text: "Pending",
},
{
value: "DRAFT",
text: "Draft",
},
{
value: "COMPLETED",
text: "Completed",
},
{
value: "REJECTED",
text: "Rejected",
},
],
};
},
methods: {
handleRemoveEvent() {
console.log("handleRemoveEvent");
},
},
};
</script>
<!-- wui-filter-chip.vue -->
Number of displayed values
To keep filter chips compact, they limit the number of options displayed (default numberVisibleValues
is 2
). If only a string is passed instead of an array of options, the string is not delimited. You can set the number of options displayed in detail using the numberVisibleValues
property.
<template>
<div>
<wui-filter-chip
label="Status"
:value="values"
:number-visible-values="4"
/>
</div>
</template>
<script>
export default {
data() {
return {
values: [
{
value: "PENDING",
text: "Pending",
},
{
value: "DRAFT",
text: "Draft",
},
{
value: "COMPLETED",
text: "Completed",
},
{
value: "REJECTED",
text: "Rejected",
},
],
};
},
};
</script>
<!-- wui-filter-chip-number-of-values.vue -->
Display of the comparison operator
WuiFilterChip also takes into account the passed comparison operator
in the output. The following comparison operators are supported for text output:
- GREATER_THAN
- GREATER_THAN_OR_EQUAL
- EQUAL
- UNEQUAL
- LESS_THAN
- LESS_THAN_OR_EQUAL
- CONTAINS
- CONTAINS_NOT
- CONTAINS_CASE_SENSITIVE
- CONTAINS_NOT_CASE_SENSITIVE
- EQUALS
- STARTS_WITH
<template>
<div>
<wui-filter-chip label="Price" :value="values" operator="GREATER_THAN" />
</div>
</template>
<script>
export default {
data() {
return {
values: [{ value: 3000, text: "3000 €" }],
};
},
};
</script>
<!-- wui-filter-chip-operator.vue -->
Custom texts using slots
For your own custom outputs you can use the default and icon slots.
<template>
<div>
<wui-filter-chip label="Price" :value="values" operator="GREATER_THAN">
<template #default="props"
>Custom output with scoped slot prop <code>computedValue</code>: {
props.data.computedValue }</template
>
<template #icon
><wui-fa-icon
:icon="['far', 'trash']"
title="Custom remove icon using 'icon' slot"
/></template>
</wui-filter-chip>
</div>
</template>
<script>
export default {
data() {
return {
values: [{ value: 3000, text: "3000 €" }],
};
},
};
</script>
<!-- wui-filter-chip-slots.vue -->
Predicate editors
Filter predicates are at the heart of the wui-filterbar
. They consist of a wui-filter-chip
and the actual predicate editor. All predicate editors can be associated with a comparison operator (options.operator
must be set to true
or to one of the available operator types) to give the user an advanced refinement of the search result.
In technical terms, a filter predicate is a filter expression (or function) that is applied as an assignment target to a search. The wui-filter-predicate-editor
is the associated user-friendly UI component that allows the user to create a filter expression.
Predicate editor types
There are two main categories of predicate editors
Options based editors
SINGLE_SELECT
- a list of options rendered as radio inputsMULTI_SELECT
- a list of options rendered as checkbox inputs
User input based editors
STRING
- renders a text input with string comparison operators selectboxNUMBER
- renders a text input with numeric comparison operators selectboxMONEY
- renders a text input with currency symbol at the end and a numeric comparison operators selectboxPERCENT
- renders a text input with percentage symbol at the end and a numeric comparison operators selectbox
The biggest difference between option-based editor types and user input types is that with type SINGLE_SELECT
or MULTI_SELECT
you also have to pass the filter options via the options.options
prop.
Filter options
There are two ways to provide filter options the user can choose from. Either by passing an array to the options.options
prop or by passing a function reference (see "Using options provider function" below). All WuiFilterEditorList
fields of the options
array are supported (see Filter editor list for more infos),
Example: options based filter using an Array
const options = {
options: [
{ value: "value_1", text: "Value 1" },
{ value: "value_2", text: "Value 2", disabled: true },
{ value: { v: "value_3" }, text: "Value 3" },
{ value: "value_4", html: "<strong>Value 4</strong>" },
],
// searchbar: true // optional
};
If searchbar
is set to true
, a search input field is rendered and the user will be able to search for options in your predioptionscate.options
Array.
Infinite scrolling
With SINGLE_SELECT
or MULTI_SELECT
a maximum of 20 options are displayed. If more than 20 options are passed through, the predicate editor automatically activates infinite scrolling.
Example 1 - providing an array with 50 options
You have an array with 50 options:
const options = {
options: [
{ value: "value_1", text: "Value 1" },
// ... all other 48 options go here
{ value: "value_50", text: "Value 50" },
],
};
Once the predicate editor opens, only the first 20 options are shown to the user (only 20 items are rendered in HTML). As soon as the user starts scrolling and gets to the end of the list, another 20 options from the already existing options array are rendered and displayed.
Example 2 - using a provider function
Instead of an array, you use a provider function, which returns an array of 1000 options.
const options = {
options: (ctx) => {
// Sample function that makes an API call and returns 1000 items
// return [...1000 items]
},
};
As in example 1, only the first 20 options are displayed here. As soon as the user starts scrolling and gets to the end of the list, another 20 options from the already existing array are revealed.
Note: the provider function is not called again on infinite scrolling as long as the predicate editor is open. The provider function is only called when the predicate editor opens or the user changes the search term.
Searching filter options
Filter options can be searched/filtered by the user if you set the prop options.searchbar
to true
. This will render a search input field in the predicate editor.
The built-in search has no effect if an options provider function is specified instead of an array of options. The entered query string by the user is passed to your provider function as a context parameter.
Optional placeholder text for searchbar
You can customize the value of the placeholder attribute by passing an Object instead of a Boolean via the searchbar
prop:
const options: {
options: [{ value: "val_1", text: "Val 1" }],
searchbar: {
placeholder: "My custom placeholder text"
}
}
Using options provider function
As mentioned, it is possible to use a function to provide the filter options, by specifying a function reference via the options.options
prop.
The provider function is called with the following signature:
provider(ctx, [callback]);
The ctx
is the context object associated with the editor's state, and contains the following properties:
Property | Type | Description |
---|---|---|
limit | String | The maximum number of items to load (default for initial call is 20 , for all subsequent calls 20 ) - optional (only available when options.optionsProviderPaging is set to true ) |
offset | Number | The number of how many items to skip from the record. Useful if you need API pagination with an offset parameter (only available when options.optionsProviderPaging is set to true ) |
query | String | The search term the user has entered in the search input field (options.searchbar must be set to true ) |
The second argument callback
is an optional parameter for when using the callback asynchronous method.
Example: returning an array of filter options (synchronous):
function myProvider() {
let items = [];
// Perform any items processing needed
// Must return an array
return items || [];
}
Example: Using a Promise to return data (asynchronous):
function myProvider(ctx) {
const promise = axios.get(`/some/url?query=${ctx.query}`);
// or with pagination
// const promise = axios.get(
// `/some/url?query=${ctx.query}&offset=${ctx.offset}&limit=${ctx.limit}`
// );
// Must return a promise that resolves to an array of filter options
return promise.then((data) => {
// Pluck the array of options off our axios response
const options = data.options;
// Must return an array of options or an empty array if an error occurred
return options || [];
});
}
Example: Using an async function (semi-synchronous):
async function myProvider(ctx) {
try {
const response = await axios.get(`/some/url?query=${ctx.query}`);
// or with pagination
// const response = await axios.get(`/some/url?query=${ctx.query}&offset=${ctx.offset}&limit=${ctx.limit});
return response.items;
} catch (error) {
return [];
}
}
Note: The options provider function is called every time the predicate editor opens.
Options provider paging and filtering
By default, the options provider function is responsible for paging and filtering the data, before passing it to the predicate editor for display.
The provider function is triggered as soon as:
- the predicate editor gets mounted (usually when displayed to the user)
- the user enters a term in the search field in the predicate editor (
options.searchbar
must be set totrue
). - the end of the list ist reached by scrolling down and there are no items left to reveal (
options.optionsProviderPaging
must be set totrue
)
Comparison operator types
With the prop operator
you can give users more options when filtering. If operator
is set to true
, a selectbox with pre-configured comparison operator choices for each filter type is displayed. The following comparison operators are available:
// Default for all numeric predicate editors ('NUMBER', 'MONEY', 'PERCENT')
const NUMERIC = [
"GREATER_THAN",
"GREATER_THAN_OR_EQUAL",
"EQUAL",
"UNEQUAL",
"LESS_THAN",
"LESS_THAN_OR_EQUAL",
];
// Default for 'STRING' predicate editor
const STRING_LONG = [
"CONTAINS",
"CONTAINS_NOT",
"CONTAINS_CASE_SENSITIVE",
"CONTAINS_NOT_CASE_SENSITIVE",
"EQUALS",
"STARTS_WITH",
];
// Onyl default for 'SINGLE_SELECT' and 'MULTI_SELECT' predicate editors when 'operator' is set to 'true', otherwhise no operator selectbox is rendered
const STRING_SHORT = ["CONTAINS", "CONTAINS_NOT"];
You can also specify one of the available operator categories to render a predefined set of operators.
Example filter configuration with a custom set comparison operator category
const options: {
options: [
{ value: "DRAFT", "Draft" },
{ value: "PENDING", "Pending" }
],
// Will render a selectbox with a list of string based comparison operators (6 in total, see above)
operator: "STRING_LONG"
};
For user-input-based predicate editors (type
is set to NUMBER
, MONEY
, PERCENT
and STRING
), the operator selection is shown by default. You can hide the selectbox by setting operator
to false
.
Custom predicate editor
A custom predicate editor for each filter category is possible using scoped slots.
Scoped predicate editor slots
Scoped predicate editor slots give you the opportunity to build your own custom predicate editor.
Example: Custom predicate editor rendering with scoped slots
<template>
<div>
<wui-filter-predicate-editor
v-bind="$props"
type="MULTI_SELECT"
filter-id="1234"
filter-key="status"
filter-name="Status"
:value="value"
:options="options"
>
<template #default="{ editor }">
<strong>Your custom predicate editor goes here.<strong><br />
<button @click="editor.updateModel([{ value: 'DRAFT_TEST', text: 'Draft Test' }])">
Submit
</button>
Scoped props: <pre>{ editor }</pre>
</template>
</wui-filterbar>
</div>
</template>
<script>
export default {
data() {
options: [
{ value: "DRAFT", text: "Draft" },
{ value: "PENDING", text: "Pending" },
],
value: [],
},
};
</script>
<!-- wui-filter-predicate-editor-slots.vue -->
Example 2: Custom predicate editor - filter by restrictions
<template>
<div class="display--flex">
<wui-filter-predicate-editor
type="MULTI_SELECT"
:filter-id="filterId"
:filter-key="restrictions_by_country"
:filter-name="Restrictions by country"
:value="value"
:options="options"
@update="handleUpdateEvent"
>
<template #editor-before-input="{ editor }">
<wui-form validated="state" class="border-b-1 p-x-10 p-y-10">
<wui-form-group v-slot="{ ariaDescribedby }" class="m-b-0">
<wui-form-radio-group
id="hasRestriction"
:aria-describedby="ariaDescribedby"
name="hasRestriction"
:checked="editor.value"
stacked
@input="handleRestrictonsInput($event, editor)"
>
<wui-form-radio
key="with_restrictions"
:value="[
{
value: 'with_restrictions',
text: 'Has country restrictions',
},
]"
class="m-t-0"
>Has country restrictions</wui-form-radio
>
<wui-form-radio
key="without_restrictions"
:value="[
{
value: 'without_restrictions',
text: 'Has no country restrictions',
},
]"
class="m-b-0"
>Has no country restrictions</wui-form-radio
>
</wui-form-radio-group>
</wui-form-group>
</wui-form>
</template>
<template #default="{ editor }">
<wui-filter-editor-list
ref="editor-input"
name="restrictions"
:options="getFilteredOptions(editor.filteredOptions)"
type="MULTI_SELECT"
:state="editor.validationState"
:error-message="editor.errorMessage"
:checked="editor.value"
@input="handleRestrictonsInput($event, editor)"
>
<template #before>
<p class="p-t-10">Or should match with:</p>
</template>
</wui-filter-editor-list>
</template>
</wui-filter-predicate-editor>
</div>
</template>
<script>
const isEmptyArray = (value) =>
!Boolean(Array.isArray(value) && value.length);
export default {
data() {
return {
options: {
options: this.countriesOptionsProvider,
value: [],
},
},
},
methods: {
// Our custom filter options provider function
// Is called everytime the predicate editor opens, or
// when the user enters a search term (only when `predicate.searchable` is set to `true`)
async countriesOptionsProvider() {
return await Promise.resolve(
[
{ count: 2, text: "BE", value: "BE" },
{ count: 13710, text: "CH", value: "CH" },
{ count: 31343, text: "DE", value: "DE" },
].map((res) => ({
value: res.value,
text: `${res.text} (${res.count})`,
}))
);
},
// Remove custom filter options "with_restrictions" and "without_restrictions"
// to prevent the rendering of an additional checkbox (because by default the predicate editor renders all selected options at the top of the list)
getFilteredOptions(filteredOptions) {
return filteredOptions.filter(
(option) =>
!["with_restrictions", "without_restrictions"].includes(
get(option, "value.value", "")
)
);
},
// Our custom logic to handle user inputs whether from our custom radios
// or from the checkbox list below
// @values: Array with the current selected options
// @predicate: the object from the scoped slot which contains the `updateModel` function we need to call
handleRestrictonsInput(values, predicate) {
if (isEmptyArray(values)) {
return;
}
// Store the custom value object from one of our radio options
const withOrWithoutRestrictionsObject = values.find(
(res) =>
res &&
(get(res, "value") === "with_restrictions" ||
get(res, "value") === "without_restrictions")
);
// Store the String "with_restrictions" or "without_restrictions"
const withOrWithoutRestrictionsValue = get(
withOrWithoutRestrictionsObject,
"value"
);
// If either "with_restrictions" or "without_restrictions" is set
// we update the model with the value from the radio button only.
// This will overwrite any existing selected options from the checkbox list and
// automatically uncheck all checkbox options.
if (values.length === 1 && withOrWithoutRestrictionsValue) {
predicate.updateModel([withOrWithoutRestrictionsObject]);
} else {
// The `values` Array contains at least one item from the checkbox list.
// We filter out any set values from our custom radio buttons which automatically
// makes them unselected.
predicate.updateModel(
values.filter(
(option) =>
!["with_restrictions", "without_restrictions"].includes(
get(option, "value", "")
)
)
);
}
},
},
};
</script>
<!-- wui-filter-predicate-editor-custom-editor.vue -->
The slot's scope variable (editor
in the above sample) will have the following properties:
Property | Type | Description |
---|---|---|
errorMessage | String | The error message from the filter-predicate-editor component |
filteredOptions | Array | A filtered list of your provided options (when type is set to MULTI_SELECT ) where all the selected options are put at the beginning of the list to display them first before all other options. |
filterId | String | The unique id of the filter given by the filterbar |
filterKey | String | The filter key from your configuration (status in the above example) |
filterName | String | The translated filter name you have passed via the filters config |
operator | String | The value of the current selected operator |
query | String | The user's text input of the search input field if you have set searchbar prop in your filter's config to true . In that case a search input is rendered above and outside of the slot content |
resetModel() | Function | Function which resets the model to [] |
type | String | The filter type |
updateModel([]) | Function | Function to update the v-model prop localModel . Function parameter musst be an Array of one or more values. If MULTI_SELECT or SINGLE_SELECT is set, the value must be an Array of objects in the form of [{ value: "DRAFT", text: "Draft" }] |
updateOperator({operator}) | Function | Function to update the operator prop. Must be one of the available comparison operator values |
updateQuery() | Function | Function to update the search query prop |
validationState() | Boolean or undefined | The current validation state of the predicate editor. If false , there is an error (e.g. user needs to choose at least one options), true if entered user data or chosen option is valid, or undefined (default state when predicate editor just opened for the first time with no set filter) |
value v-model | Array | The current selected options or the current entered value by the user. User the updateModel() scoped function to update the v-model |
Example: Custom predicate option items rendering with editor-option-item
scoped slot
<template>
<div>
<wui-filter-predicate-editor
v-bind="$props"
type="MULTI_SELECT"
filter-id="1234"
filter-key="creator"
filter-name="Creator"
:value="value"
:options="options"
>
<template #editor-option-item="{ optionItem }">
<div class="flex-shrink-0 m-l-10">
<img
v-if="optionItem.image"
class="img-circle"
:src="optionItem.image"
:alt="optionItem.text"
style="width: 30px; height: 30px"
/>
<user-image
v-else
:id="optionItem.value.value"
class="img-circle"
:alt="optionItem.text"
style="width: 30px; height: 30px"
/>
</div>
<div class="flex-grow-1 m-l-10">{ optionItem.text }</div>
</template>
</wui-filterbar>
</div>
</template>
<script>
export default {
data() {
options: [
{
value: "bb463b8b-b76c-4f6a-9726-65ab5730b69b",
text: "Ron Dare",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/104.jpg",
},
{
value: "8b86a4d7-bb95-4b65-a553-34fac1c60627",
text: "Jerry Hahn PhD",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/532.jpg",
},
{
value: "cebf8879-9145-476a-9e41-77f3869c17dc",
text: "Johnnie Kemmer",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/428.jpg",
},
{
value: "0456bade-487a-449d-94a8-d215ce323793",
text: "Miss Rochelle Cronin",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1148.jpg",
},
],
value: [],
},
};
</script>
<!-- wui-filter-predicate-editor-custom-option-items-scoped-slot.vue -->
The slot's scope variable (optionItem
in the above sample) will have the following properties:
Property | Type | Description |
---|---|---|
option | Object | the current option item (will have text value from the formatter function if provided) |
checked | Boolean | wheather or not the current item is checked) |
[... allOtherOptions] | All other options you have provided by the options.options array will be passed |
Filter editor list
This helper component renders stacked checkbox or radio lists with built-in infinite scrolling when the number of options exceeds 20.
Because WuiFilterEditorList
uses wui-form-checkbox
or wui-form-radio
under the hood, all fields of the options
array are supported:
value
The selected value which will be set onv-model
disabled
Disables item for selectiontext
Display text, orhtml
Display basic inline html
If both html
and text
are provided, html
will take precedence. Only basic/native HTML is supported in the html
field (components will not work, use the scoped default slot for that).
Example: Basic usage multi select
<template>
<div class="border-1 p-10" style="height: 200px; overflow-y: auto">
<wui-filter-editor-list
v-model="selected"
name="status"
:options="options"
type="MULTI_SELECT"
@intersect="handleIntersect"
></wui-filter-editor-list>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [
{ value: "value_1", text: "Value 1" },
{ value: "value_2", text: "Value 2" },
{ value: { v: "value_3" }, text: "Value 3" },
{ value: "value_4", html: "<strong>Value 4</strong>" },
],
};
},
methods: {
handleIntersect() {
// load more options with every intersect event ...
},
},
};
</script>
<!-- wui-filter-editor-list-example.vue -->
Changing the option field names
If you want to customize the field property names (for example using name
field for display text
) you can easily change them by setting the text-field
, html-field
, value-field
, and disabled-field
props to a string that contains the property name you would like to use:
<template>
<div class="border-1 p-10" style="height: 200px; overflow-y: auto">
<wui-filter-editor-list
v-model="selected"
name="status"
type="MULTI_SELECT"
:options="options"
value-field="item"
text-field="name"
disabled-field="notEnabled"
></wui-filter-editor-list>
<div class="m-t-15">Selected: <strong>{ selected }</strong></div>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [
{ item: "A", name: "Option A" },
{ item: "B", name: "Option B" },
{ item: "D", name: "Option C", notEnabled: true },
{ item: { d: 1 }, name: "Option D" },
],
};
},
};
</script>
<!-- wui-filter-editor-list-options-fields.vue -->
Custom list item rendering
Custom rendering for each list item is possible using either scoped slots or a formatter callback function, or a combination of both.
Scoped slot
The scoped default slot give you greater control over how the list items appears. You can use the default scoped slot to provided custom rendering for every item in the list.
Example: Custom list items using the default scoped slot
<template>
<div class="border-1 p-10" style="height: 200px; overflow-y: auto">
<wui-filter-editor-list
v-model="selected"
name="status"
:options="options"
type="MULTI_SELECT"
@intersect="handleIntersect"
>
<template #default="{ option, checked }">
<div
class="display--flex align-items-center w-full text--left p-x-10 p-y-5"
>
<div class="flex-shrink-0" style="width: 15px;">
<wui-fa-icon v-if="checked" :icon="['far', 'check']" />
</div>
<div class="flex-shrink-0 m-l-10">
<img
class="img-circle"
:src="option.image"
:alt="option.text"
style="width: 30px"
/>
</div>
<div class="flex-grow-1 m-l-10">{ option.text }</div>
</div>
</template>
</wui-filter-editor-list>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [
{
value: "bb463b8b-b76c-4f6a-9726-65ab5730b69b",
text: "Ron Dare",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/104.jpg",
},
{
value: "8b86a4d7-bb95-4b65-a553-34fac1c60627",
text: "Jerry Hahn PhD",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/532.jpg",
},
{
value: "cebf8879-9145-476a-9e41-77f3869c17dc",
text: "Johnnie Kemmer",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/428.jpg",
},
{
value: "0456bade-487a-449d-94a8-d215ce323793",
text: "Miss Rochelle Cronin",
image:
"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1148.jpg",
},
],
};
},
methods: {
handleIntersect() {
// load more options with every intersect event ...
},
},
};
</script>
<!-- wui-filter-editor-list-scoped-slot-example.vue -->
The default slot's scope will have the following properties:
Property | Type | Description |
---|---|---|
option | Object | the current option item (will have text value from the formatter function if provided) |
checked | Boolean | wheather or not the current item is checked) |
[... allOtherOptions] | All other options you have provided by the options array will be passed |
Formatter callback
Optionally, you can customize the list item output by using a formatter callback function. To enable this, the formatter
property is used. The value of this property may be String or function reference. In case of a String value, the function must be defined at the parent component's methods. When providing formatter
as a Function
, it must be declared at global scope (window or as global mixin at Vue, or as an anonymous function), unless it has been bound to a this
context.
The callback function accepts three arguments - text
, value
, and option
, and should return the formatted value as a string (HTML strings are not supported).
Example: Custom list items with formatter callback function
<template>
<div class="border-1 p-10" style="height: 200px; overflow-y: auto">
<wui-filter-editor-list
v-model="selected"
name="status"
:options="options"
:formatter="formatOption"
type="MULTI_SELECT"
@intersect="handleIntersect"
/>
</div>
</template>
<script>
export default {
data() {
return {
selected: [],
options: [
{
value: "PENDING",
text: "Pending",
},
{
value: "DRAFT",
text: "Draft",
},
{
value: "COMPLETED",
text: "Completed",
},
{
value: "REJECTED",
text: "Rejected",
// When `disable` is `true`, this option will be rendered in disabled state and cannot be selected by the user
disabled: true,
},
],
};
},
methods: {
handleIntersect() {
// load more options with every intersect event ...
},
formatOption(text, key, option) {
return `${text} (${Math.floor(Math.random() * 50)})`;
},
},
};
</script>
<!-- wui-filter-editor-list-scoped-slot-example.vue -->
Infinite scroll
In order for infinite scrolling to work, wui-filter-editor-list
must be placed in a fixed-height container and overflow-y
must be set to auto
or scroll
(see example above).
Filter editor inputs
These components all use a form text entry field with different formatting. There are 4 different editor input types available
wui-filter-editor-money
wui-filter-editor-number
wui-filter-editor-percent
wui-filter-editor-string
All of them have an error
slot for custom content. By default the slot renders your custom errorMessage
when the validation state
is set to false
.
wui-filter-editor-money
This component renders a text input field with a currency symbol at the end. Input value is right aligned.
<template>
<div>
<wui-filter-editor-money
currency-code="EUR"
currency-symbol="€"
:value="value"
></wui-filter-editor-money>
</div>
</template>
<script>
export default {
data() {
return {
value: [{ value: 3000, text: "3000 €" }],
};
},
};
</script>
<!-- wui-filter-editor-money-example.vue -->
wui-filter-editor-number
This component renders a text input field and accepts and emits only numeric values. Input value is left aligned.
<template>
<div>
<wui-filter-editor-number :value="value"></wui-filter-editor-number>
</div>
</template>
<script>
export default {
data() {
return {
value: [{ value: 3000, text: 3000 }],
};
},
};
</script>
<!-- wui-filter-editor-number-example.vue -->
wui-filter-editor-percent
This component renders a text input field with a '%' symbol at the end. Input value is right aligned.
<template>
<div>
<wui-filter-editor-percent :value="value"></wui-filter-editor-percent>
</div>
</template>
<script>
export default {
data() {
return {
value: [{ value: 80, text: "80 %" }],
};
},
};
</script>
<!-- wui-filter-editor-percent-example.vue -->
wui-filter-editor-string
This component renders a text input field for alphanumeric values. Input value is left aligned.
<template>
<div>
<wui-filter-editor-string :value="value"></wui-filter-editor-string>
</div>
</template>
<script>
export default {
data() {
return {
value: [{ value: "pencil", text: "pencil" }],
};
},
};
</script>
<!-- wui-filter-editor-percent-example.vue -->
Filter predicate operator
Comparison operator types
This heper component renders a selectbox with pre-configured comparison operator choices. There are three types of operators available:
// Default for all numeric predicate editors ('NUMBER', 'MONEY', 'PERCENT')
const NUMERIC = [
"GREATER_THAN",
"GREATER_THAN_OR_EQUAL",
"EQUAL",
"UNEQUAL",
"LESS_THAN",
"LESS_THAN_OR_EQUAL",
];
// Default for 'STRING' predicate editor
const STRING_LONG = [
"CONTAINS",
"CONTAINS_NOT",
"CONTAINS_CASE_SENSITIVE",
"CONTAINS_NOT_CASE_SENSITIVE",
"EQUALS",
"STARTS_WITH",
];
// Onyl default for 'SINGLE_SELECT' and 'MULTI_SELECT' predicate editors when 'operator' is set to 'true', otherwhise no operator selectbox is rendered
const STRING_SHORT = ["CONTAINS", "CONTAINS_NOT"];
Example: predicate operator of type STRING_LONG
<template>
<div class="display--flex">
<wui-filter-predicate-operator
v-model="selected"
type="STRING_LONG"
></wui-filter-predicate-operator>
</div>
</template>
<script>
export default {
data() {
return {
selected: "CONTAINS",
};
},
};
</script>
<!-- wui-filter-predicate-operator-numeric.vue -->
Note: The operator of type="NUMERIC"
is intended to line up horizontally with a text input field next to it. Please take this into account when using it.
Component reference
<wui-filter-chip>
Properties
Property | Type | Default | Description |
---|---|---|---|
label | String | The label or filter category. Will be displayed before the values | |
numberVisibleValues | Number or String | 2 | Number of displayed selected labels after which the component should show '## more' |
operator | String | undefined | The comparison operator to show between the filter category and the chosen value |
removeAriaLabel | String | null | aria-label for the 'x' remove button |
translations | String | see translations.js | The translation object to pass custom texts |
value | Object , Array or String | The values which should be displayed. Can be a string, an Object with must contain a text property { text: 'my value' } , or an Array of Objects which contain a text property [{ text: 'Value 1' }, { text: 'Value 2' } ...] |
Slots
Name | Description |
---|---|
default | Content to place in the filter |
icon | Content/icon to replace the 'x' remove icon with |
Events
Event | Arguments | Description |
---|---|---|
remove | Emitted when the user clicks on the 'x' remove button |
<wui-filter-predicate-editor>
<wui-filter-predicate-editor>
Properties<wui-filter-predicate-editor>
v-model
<wui-filter-predicate-editor>
Slots<wui-filter-predicate-editor>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
autoFocusButton | String | null | Specify which built-in button to focus once the popup opens: 'apply' or 'close' |
busy | Boolean | false | Places the built in default footer APPLY button in the disabled state |
filterId | String | The unique id of this filter. Should be also unique for every additional filter of the same filterKey | |
filterKey | String | The technical filter category key (e.g. buying_channel ) | |
filterName | String | The readable name of the filter which will be displayed | |
hidden | Boolean | false | Value for the filter-chip's aria-hidden and aria-disabled attribute |
isNew | Boolean | false | Whether or not this is a fresh new filter. The filter-chip will not be visible to the user, but is rendered in the HTML |
options | Object | {} | Options for the editor popup. See docs for more infos |
selectedOperator | String | "" | The current selected comparison operator |
showEditor | Boolean | false | Whether or not the editor popup should be open. Will be ignored if user clicks on the filter-chip to open the editor |
tag | String | "LI" | The HTML tag of the outer wrapper. |
translations | String | see translations.js | The translation object to pass custom texts |
type | String | "MULTI_SELECT" | The type of the editor. Possible values are SINGLE_SELECT , MULTI_SELECT , MONEY , NUMBER , PERCENT or STRING |
value | String , Array or Object | undefined | The v-model value. Will be an Array of one or more objects (depending on type ) in the format [{ value: 'value_1', text: 'Value #1' }] |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
editor-top | Content to place at the top of the editor body |
editor-before-input | Content to place before the input section in the editor body, but after the operator selectbox and searchbar |
default | Content to place inside the editor container. Will replace the input form elements with your custom content |
editor-after-input | Content to place after the input section in the editor body |
editor-option-item | Scoped slot for content to place for each list item. Includes optionItem as an additional scoped prop object with { value: 'option_item_value', text: 'Option item text', checked: true/false, ...allOtherOptionItemProps } . Only applicable if type is SINGLE_SELECT or MULTI_SELECT |
Events
Event | Arguments | Description |
---|---|---|
edit | Emitted when the user has clicked on the filter-chip and the popup opens to modify the filter | |
editor-show | Emitted before the editor popups opens, before the CSS transition | |
editor-shown | Emitted when the editor popup is open, after the CSS transition has finished | |
editor-hide | Emitted before the editor popup closes, before the CSS transition | |
editor-hidden | Emitted when the editor popup is hidden, after the CSS transition has finished | |
input | value - Object - Object with property either value or operator , depending on where the change occured { value: [ { value: 'val_1', text: 'Value #1' } ], operator: 'CONTAINS' } | Emitted when the value or comparison operator was changed by the user |
refreshed | Emitted after the options provider was called and the local modal was updated | |
remove | temporary-close - String - Argument is only emitted if it's a fresh new filter (isNew must be true ) and the user closes the editor popup without entering a value or chosing an option. Otherwhise undefined | Emitted when the filter is about to be removed |
update | value - Object - Object with value and operator (e.g. { value: [ { value: 'val_1', text: 'Value #1' } ], operator: 'CONTAINS' } ) | Emitted when the user clicked the 'APPLY' button and the form validation returned true |
<wui-filter-editor-list>
<wui-filter-editor-list>
Properties<wui-filter-editor-list>
v-model
<wui-filter-editor-list>
Slots<wui-filter-editor-list>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
checked | Array | null | The v-model value, either a String if type is SINGLE_SELECT or an Array if type is MULTI_SELECT |
disabled-field | String | 'disabled' | Field name in the options array that should be used for the disabled state |
formatter | String or Function | "" | A formatter callback function or name of a method in your component, can be used instead of (or in conjunction with) the default scoped slot. The formatter will be called with the syntax formatter(text, value, option) . Refer to 'Custom list item rendering' for more details. component |
html-field | String | 'html' | Field name in the options array that should be used for the html label instead of text field |
id | String | "" | ID which will be used to generate a unique HTML id attribute for the radio or checkbox group component |
name | String | The required name attribute for the radio or checkbox group component | |
observer-options | Object | { rootMargin: "100px" } | Properties to pass to the IntersectionObserver object which is used to emit an intersect events for infinite scrolling |
options | Array | [] | The options to display as a checkbox or radio list. Must be in Array of objects on the format [{ value: 'value_1', text: 'Value #1' }] |
state | Boolean or String | null | Your form validation state. If false an error message of type required will be shown |
text-field | String | 'text' | Field name in the options array that should be used for the text label |
translations | String | see translations.js | The translation object to pass custom texts |
type | String | "MULTI_SELECT" | The type of the editor list, either SINGLE_SELECT or MULTI_SELECT |
value-field | String | 'value' | Field name in the options array that should be used for the value |
v-model
Property | Event |
---|---|
checked | input |
Slots
Name | Scoped | Description |
---|---|---|
before | No | Content to place before the form group |
default | Yes | Scoped slot for content to place for each list item. See 'Custom list item rendering' or docs for scoped data |
error | No | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays an error message of type required if state is false |
Events
Event | Arguments | Description |
---|---|---|
input | checked - String or Array , The selected values by the user. Will be an Array when type is MULTI_SELECT or a String when type is SINGLE_SELECT | Emitted when the user makes a selection |
intersect | Emitted when theIntersectionObserver triggers isIntersecting which means the scroll end is about to be reached |
<wui-filter-editor-input>
<wui-filter-editor-input>
Properties<wui-filter-editor-input>
v-model
<wui-filter-editor-input>
Slots<wui-filter-editor-input>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
errorMessage | String | "" | A custom error message which will be shown when state is false |
state | Boolean or String | null | The result of your validation state |
trailingSymbol | String | null | The symbol which should be displayed at the end of the input field (eg. '€' or '%') |
type | String | "STRING" | One of the editor input types (MONEY , NUMBER , PERCENT or STRING ) |
value | String or Number | "" | The v-model value for the input field. Can be a number or string |
translations | String | see translations.js | The translation object to pass custom texts |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
error | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays the errorMessage if state is false |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
submit | value - String or Number , The value for the input field. Can be a number or string depending on the type | Emitted when the user hits the ENTER key |
<wui-filter-editor-money>
<wui-filter-editor-money>
Properties<wui-filter-editor-money>
v-model
<wui-filter-editor-money>
Slots<wui-filter-editor-money>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
currencyCode | String | "" | The ISO 4217 currency code |
currencySymbol | String | "" | The currency code to diplay at the end of the input field |
errorMessage | String | "" | A custom error message which will be shown when state is false |
state | Boolean or String | null | The result of your validation state |
value | Array | [] | The v-model value for the input field in the format e.g. [{ value: 1000, text: '1000 €' }] (child property value is Number ) |
translations | String | see translations.js | The translation object to pass custom texts |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
error | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays the errorMessage if state is false |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
submit | value - Array - The value for the input field in the format e.g. [{ value: 1000, text: '1000 €' }] | Emitted when the user hits the ENTER key |
<wui-filter-editor-number>
<wui-filter-editor-number>
Properties<wui-filter-editor-number>
v-model
<wui-filter-editor-number>
Slots<wui-filter-editor-number>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
errorMessage | String | "" | A custom error message which will be shown when state is false |
state | Boolean or String | null | The result of your validation state |
value | Array | [] | The v-model value for the input field in the format e.g. [{ value: 1000, text: 1000 }] (child property value is Number ) |
translations | String | see translations.js | The translation object to pass custom texts |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
error | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays the errorMessage if state is false |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
submit | value - Array - The value for the input field in the format e.g. [{ value: 1000, text: 1000 }] | Emitted when the user hits the ENTER key |
<wui-filter-editor-percent>
<wui-filter-editor-percent>
Properties<wui-filter-editor-percent>
v-model
<wui-filter-editor-percent>
Slots<wui-filter-editor-percent>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
errorMessage | String | "" | A custom error message which will be shown when state is false |
state | Boolean or String | null | The result of your validation state |
value | Array | [] | The v-model value for the input field in the format e.g. [{ value: 80, text: '80 %' }] (child property value is Number ) |
translations | String | see translations.js | The translation object to pass custom texts |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
error | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays the errorMessage if state is false |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
submit | value - Array - The value for the input field in the format e.g. [{ value: 80, text: '80 %' }] | Emitted when the user hits the ENTER key |
<wui-filter-editor-string>
<wui-filter-editor-string>
Properties<wui-filter-editor-string>
v-model
<wui-filter-editor-string>
Slots<wui-filter-editor-string>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
errorMessage | String | "" | A custom error message which will be shown when state is false |
state | Boolean or String | null | The result of your validation state |
value | Array | [] | The v-model value for the input field in the format e.g. [{ value: 'search term', text: 'search term' }] (child property value is String ) |
translations | String | see translations.js | The translation object to pass custom texts |
v-model
Property | Event |
---|---|
value | update |
Slots
Name | Description |
---|---|
error | Content to place in the error slot. Default content is the wui-form-invalid-feedback component which displays the errorMessage if state is false |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
submit | value - Array - The value for the input field in the format e.g. [{ value: 'search term', text: 'search term' }] | Emitted when the user hits the ENTER key |
<wui-filter-predicate-operator>
<wui-filter-predicate-operator>
Properties<wui-filter-predicate-operator>
v-model
<wui-filter-predicate-operator>
Events
Properties
Property | Type | Default | Description |
---|---|---|---|
selected | String | undefined | The 'v-model' value of the current selected operator |
translations | String | see translations.js | The translation object to pass custom texts |
type | String | "NUMERIC" | The operator type. Possible values are NUMERIC , STRING_SHORT or STRING_LONG |
v-model
Property | Event |
---|---|
selected | update |
Events
All other events will be forwarded to the child component wui-form-input
.
Event | Arguments | Description |
---|---|---|
update | selected - String - The selected operator | Emitted when the user has selected a new option |
Importing individual components
You can import individual components into your project via the following named exports:
Component | Named Export |
---|---|
<wui-filter-chip> | WuiFilterChip |
<wui-filter-editor-input> | WuiFilterEditorInput |
<wui-filter-editor-list> | WuiFilterEditorList |
<wui-filter-editor-money> | WuiFilterEditorMoney |
<wui-filter-editor-number> | WuiFilterEditorNumber |
<wui-filter-editor-percent> | WuiFilterEditorPercent |
<wui-filter-editor-string> | WuiFilterEditorString |
<wui-filter-predicate-editor> | WuiFilterEditorEditor |
<wui-filter-predicate-operator> | WuiFilterEditorOperator |
Example
import { WuiFilterChip } from "@wui/wui-vue/lib/filter-chip";
Vue.component("wui-filter-chip", WuiFilterChip);
Importing as a Vue.js plugin
This plugin includes all of the above listed individual components. Plugins also include any component aliases.
Named Export | Import Path |
---|---|
FiltersPlugin | @wui/wui-vue/lib/filter |
Example
import { FiltersPlugin } from "@wui/wui-vue/lib/filter";
Vue.use(FiltersPlugin);