Skip to content

Commit

Permalink
Update to support new custom filters in Nova
Browse files Browse the repository at this point in the history
  • Loading branch information
rcknr committed Jan 3, 2019
1 parent bbefc59 commit 3a0513e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 85 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class UserType extends MultiselectFilter
return [
'Administrator' => 'admin',
'Editor' => 'editor',

];
}
}
Expand Down
2 changes: 1 addition & 1 deletion dist/js/filter.js

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions resources/js/components/Filter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<template>
<div>
<h3 class="text-sm uppercase tracking-wide text-80 bg-30 p-3">
{{ filter.name }}
</h3>

<div class="p-2">
<select-multiple
:dusk="filter.name + '-filter-select'"
class="block w-full form-control-sm form-select"
:options="filter.options"
:value="value"
@change="handleChange"
/>
</div>

</div>
</template>

<script>
import SelectMultiple from './SelectMultiple'
export default {
components: {
SelectMultiple
},
props: {
filterKey: {
type: String,
required: true,
},
},
methods: {
handleChange(value) {
this.$store.commit('updateFilterState', {
filterClass: this.filterKey,
value: value,
})
this.$emit('change')
},
},
computed: {
filter() {
return this.$store.getters.getFilter(this.filterKey)
},
value() {
return this.filter.currentValue
},
},
}
</script>
35 changes: 0 additions & 35 deletions resources/js/components/FilterSelector.vue

This file was deleted.

51 changes: 13 additions & 38 deletions resources/js/components/SelectMultiple.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<template>
<div class="form-select-multiple" ref="toggle">

<div v-if="(selected.length === 0) || !multiple" ref="selected" class="selected">{{ displayValue }}</div>

<div v-if="selected.length === 0" class="empty"></div>
<ul v-else ref="selected" class="selected">
<li v-for="option, index in selected" @click="remove(index)">
{{ option.name }}
</li>
</ul>

<ul v-if="optionsShown && availableOptions.length > 0" class="options">
<ul v-if="showDropdown && availableOptions.length > 0" class="options">
<li v-for="option in availableOptions" @click="select(option)" :class="{selected: selected.includes(option)}">
{{ option.name }}
</li>
Expand All @@ -21,10 +20,6 @@
<script>
export default {
props: {
multiple: {
type: Boolean,
default: false
},
options: {
type: Array,
default: []
Expand All @@ -34,58 +29,39 @@
}
},
data: () => ({
emptyValue: {
name: '',
value: ''
},
optionsShown: false,
showDropdown: false,
selected: [],
}),
computed: {
availableOptions() {
return this.multiple ?
this.options.filter(option => !this.selected.includes(option)) :
[this.emptyValue].concat(this.options);
},
displayValue() {
return this.selected.length === 1 ? this.selected[0].name : this.emptyValue.name;
return this.options.filter(option => !this.selected.includes(option));
},
effectiveValue() {
const values = this.selected.map(e => e.value);
if(values.length === 0) return '';
else if(values.length === 1 && !this.multiple) return values[0];
else return values;
return values.length === 0 ? '' : values;
},
},
methods: {
select(option) {
this.optionsShown = false;
if(this.multiple) {
this.selected.push(option);
}
else {
this.selected = [option];
}
this.showDropdown = false;
this.selected.push(option);
},
remove(index) {
this.selected.splice(index, 1);
},
toggle(event) {
if([this.$refs.toggle, this.$refs.selected].includes(event.target) && this.availableOptions.length > 0) {
this.optionsShown = !this.optionsShown;
this.showDropdown = !this.showDropdown;
}
else {
this.optionsShown = false;
this.showDropdown = false;
}
}
},
mounted() {
document.addEventListener('click', this.toggle);
this.selected = this.options.filter(option => {
return this.multiple ?
this.value.includes(option.value) :
this.value === option.value;
return this.value.includes(option.value);
});
},
watch: {
Expand All @@ -103,14 +79,13 @@
min-height: 2rem;
height: auto;
div.selected
.empty
{
margin: auto 0;
& + ul.options li.selected::after
&:before
{
content: '\2713';
float: right;
content: '\2014';
}
}
Expand Down
6 changes: 2 additions & 4 deletions resources/js/filter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import FilterSelector from './components/FilterSelector'

Nova.booting(Vue => {
Vue.component('filter-selector', Vue.component('filter-selector').extend(FilterSelector));
});
Vue.component('multiselect-filter', require('./components/Filter'));
})
9 changes: 3 additions & 6 deletions src/MultiselectFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@
abstract class MultiselectFilter extends Filter
{
/**
* Prepare the filter for JSON serialization.
* The filter's component.
*
* @return array
* @var string
*/
public function jsonSerialize()
{
return array_add(parent::jsonSerialize(), 'multiple', true);
}
public $component = 'multiselect-filter';
}

0 comments on commit 3a0513e

Please sign in to comment.