Skip to content

Commit

Permalink
Feature/add multiselect filter (#587)
Browse files Browse the repository at this point in the history
* Added multiselect to VGT
* update docs
* add dependancy to package-lock
* allow multiselect to use array of objects
  • Loading branch information
cassmbautista authored Feb 20, 2020
1 parent b05092e commit 1cba945
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 3 deletions.
41 changes: 41 additions & 0 deletions dev/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,30 @@ export default {
],
},
},
{
label: 'Multiselect',
field: 'multiselect',
filterOptions: {
enabled: true,
filterMultiselectDropdownItems: [
{ id: 1, label: 'hello'},
'oh no'
],
},
},
{
label: 'Average age',
field: 'average',
type: 'number',
filterOptions: {
enabled: true,
filterMultiselectDropdownItems: [
1,
1.5,
2
],
},
},
],
rows: [
// { id:1, name:"John", age: 20, createdAt: '2018-02-18T00:00:43-05:00',score: 0.03343 },
Expand All @@ -146,6 +170,8 @@ export default {
score: 0.03343,
bool: true,
exact: 'match',
multiselect: 'hello',
average: 1
},
{
id: 3,
Expand All @@ -155,6 +181,8 @@ export default {
score: 0.03343,
bool: true,
exact: 'match',
multiselect: 'oh no',
average: null
},
{
id: 4,
Expand All @@ -164,6 +192,7 @@ export default {
score: 0.03343,
bool: false,
exact: null,
multiselect: null
},
{
id: 5,
Expand All @@ -173,6 +202,8 @@ export default {
score: 0.03343,
bool: null,
exact: 'rematch',
multiselect: 'hello world',
average: 2
},
{
id: 5,
Expand All @@ -182,6 +213,8 @@ export default {
score: 0.03343,
bool: null,
exact: 'rematch',
multiselect: 'hello',
average: 3
},
{
id: 5,
Expand All @@ -191,6 +224,8 @@ export default {
score: 0.03343,
bool: null,
exact: null,
multiselect: 'hello',
average: 2
},
{
id: 6,
Expand All @@ -200,6 +235,8 @@ export default {
score: 0.03343,
bool: true,
exact: 'match',
multiselect: 'hello',
average: 1.5
},
{
id: 7,
Expand All @@ -209,6 +246,8 @@ export default {
score: null,
bool: 'false',
exact: null,
multiselect: 'hello',
average: 1
},
{
id: 8,
Expand All @@ -218,6 +257,8 @@ export default {
score: 0.03343,
bool: true,
exact: 'rematch',
multiselect: 'hello',
average: 1
},
],
};
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
"lodash.clonedeep": "^4.5.0",
"lodash.filter": "^4.6.0",
"lodash.foreach": "^4.5.0",
"lodash.isequal": "^4.5.0"
"lodash.isequal": "^4.5.0",
"vue-select": "^3.1.0"
},
"devDependencies": {
"@vuepress/plugin-google-analytics": "^1.0.0-rc.1",
Expand Down
33 changes: 33 additions & 0 deletions src/components/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,33 @@ export default {
return classes;
},
filterMultiselectItems(column, row) {
const columnFieldName = column.field;
const columnFilters = this.columnFilters[columnFieldName];
if (column.filterOptions && column.filterOptions.filterMultiselectDropdownItems) {
if (columnFilters.length === 0) {
return true;
}
// Otherwise Use default filters
const typeDef = column.typeDef;
for (let filter of columnFilters) {
let filterLabel = filter;
if (typeof filter === 'object') {
filterLabel = filter.label;
}
if (typeDef.filterPredicate(
this.collect(row, columnFieldName),
filterLabel
)) {
return true;
}
}
return false;
}
return undefined;
},
// method to filter rows
filterRows(columnFilters, fromFilter = true) {
// if (!this.rows.length) return;
Expand Down Expand Up @@ -1228,6 +1255,12 @@ export default {
this.columnFilters[col.field]
);
}
const filterMultiselect = this.filterMultiselectItems(col, row);
if (filterMultiselect !== undefined) {
return filterMultiselect;
}
// Otherwise Use default filters
const { typeDef } = col;
return typeDef.filterPredicate(
Expand Down
26 changes: 25 additions & 1 deletion src/components/VgtFilterRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<div
v-if="isFilterable(column)">
<input v-if="!isDropdown(column)"
<input v-if="!isDropdown(column) && !isMultiselectDropdown(column)"
type="text"
class="vgt-input"
:placeholder="getPlaceholder(column)"
Expand Down Expand Up @@ -41,6 +41,16 @@
:key="i"
:value="option.value">{{ option.text }}</option>
</select>

<v-select v-if="isMultiselectDropdown(column)"
:options="column.filterOptions.filterMultiselectDropdownItems"
:loading="column.filterOptions.loading"
:placeholder="getPlaceholder(column)"
multiple
@input="(selectedItems) => updateFiltersOnKeyup(column, selectedItems)"
ref="vgt-multiselect"
/>

</div>
</th>
</tr>
Expand Down Expand Up @@ -93,6 +103,12 @@ export default {
methods: {
reset(emitEvent = false) {
this.columnFilters = {};
// Clear the selection in the multiselect
this.$refs['vgt-multiselect'].forEach((ref) => {
ref.clearSelection();
});
if (emitEvent) {
this.$emit('filter-changed', this.columnFilters);
}
Expand All @@ -119,6 +135,14 @@ export default {
&& typeof column.filterOptions.filterDropdownItems[0] !== 'object';
},
isMultiselectDropdown(column) {
return (
this.isFilterable(column) &&
column.filterOptions &&
column.filterOptions.filterMultiselectDropdownItems
);
},
// get column's defined placeholder or default one
getPlaceholder(column) {
const placeholder = (this.isFilterable(column) && column.filterOptions.placeholder) || `Filter ${column.label}`;
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import VueGoodTable from './components/Table.vue';
import vSelect from 'vue-select';

const VueGoodTablePlugin = {
install(Vue, options) {
Vue.component('v-select', vSelect);
Vue.component(VueGoodTable.name, VueGoodTable);
},
};
Expand Down
21 changes: 20 additions & 1 deletion src/styles/_input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,23 @@
outline: none;
border-color: $link-color;
}
}
}

.v-select {
border-radius: 4px;
color: $text-color;
&::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: $text-color;
opacity: 0.3; /* Firefox */
}
&:focus {
outline: none;
border-color: $link-color;
}
input {
color: $text-color
}
.vs__open-indicator {
fill: $text-color
}
}
10 changes: 10 additions & 0 deletions src/styles/black-rhino/black-rhino.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@
opacity: 0.3; /* Firefox */
}
}

.v-select {
background-color: $input-bg;
input {
color: $text-color;
}
.vs__open-indicator {
fill: $text-color
}
}
}

.vgt-wrap.black-rhino{
Expand Down
10 changes: 10 additions & 0 deletions src/styles/nocturnal/nocturnal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@
opacity: 0.3; /* Firefox */
}
}

.v-select {
background-color: darken($thead-bg-color-2, 5%);
input {
color: $text-color;
}
.vs__open-indicator {
fill: $text-color
}
}
}

.vgt-wrap.nocturnal{
Expand Down
3 changes: 3 additions & 0 deletions src/styles/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// V-select plugin
@import "../../node_modules/vue-select/dist/vue-select";

// base table styles
@import './variables';
@import './utils';
Expand Down
20 changes: 20 additions & 0 deletions vp-docs/guide/configuration/column-filter-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ columns: [
placeholder: 'Filter This Thing', // placeholder for filter input
filterValue: 'Jane', // initial populated value for this filter
filterDropdownItems: [], // dropdown (with selected values) instead of text input
filterMultiselectDropdownItems: [], // dropdown (with multiple selected values) instead of text input
filterFn: this.columnFilterFn, //custom filter function that
trigger: 'enter', //only trigger on enter not on keyup
},
Expand Down Expand Up @@ -61,6 +62,25 @@ filterDropdownItems: [
],
```

## filterMultiselectDropdownItems

type `Array of strings` or `Array of objects` with labels

allows creating a dropdown for filtering multiple items as opposed to an input

```javascript
//array of strings
filterMultiselectDropdownItems: ['Blue', 'Red', 'Yellow']
```
```javascript
//array of objects
filterMultiselectDropdownItems: [
{ id: 1, label: 'Blue' },
{ id: 2, label: 'Red' },
{ id: 3, label: 'Yellow' }
]
```

## filterFn

type `Function`
Expand Down

0 comments on commit 1cba945

Please sign in to comment.