Merge pull request #2 from asacolips/vue-browser-name-filter
Proof of concept for filter componentpull/12/head
commit
c218a2001e
|
@ -2,26 +2,7 @@
|
||||||
<div class="actor-browser browser flexrow">
|
<div class="actor-browser browser flexrow">
|
||||||
<section class="control-area flexcol">
|
<section class="control-area flexcol">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="filtercontainer">
|
<FilterNameSort v-model="name" :filters="sorts"/>
|
||||||
<!-- Name filter. -->
|
|
||||||
<div class="filter">
|
|
||||||
<input type="text" name="compendiumBrowser.name" v-model="name" :placeholder="game.i18n.localize('Name')" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Sort -->
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{ game.i18n.localize('Sort by:') }}</label>
|
|
||||||
<div class="form-fields">
|
|
||||||
<select class="sort" v-model="sortBy">
|
|
||||||
<option v-for="(option, index) in sortOptions" :key="index" :value="option.value">{{ option.label }}</option>
|
|
||||||
</select>
|
|
||||||
<a class="direction" data-direction="asc" @click="changeDirection()">
|
|
||||||
<i class="fa-solid fa-sort-numeric-up" v-if="direction === 'asc'"></i>
|
|
||||||
<i class="fa-solid fa-sort-numeric-down-alt" v-if="direction !== 'asc'"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="filtercontainer">
|
<div class="filtercontainer">
|
||||||
<h3>{{ game.i18n.localize('General') }}</h3>
|
<h3>{{ game.i18n.localize('General') }}</h3>
|
||||||
|
@ -182,6 +163,7 @@ import { onUpdated } from 'vue';
|
||||||
// External components.
|
// External components.
|
||||||
import Slider from '@vueform/slider';
|
import Slider from '@vueform/slider';
|
||||||
import Multiselect from '@vueform/multiselect';
|
import Multiselect from '@vueform/multiselect';
|
||||||
|
import FilterNameSort from '@/components/dialogs/compendium-browser/filters/FilterNameSort.vue';
|
||||||
// Helper methods.
|
// Helper methods.
|
||||||
import {
|
import {
|
||||||
getPackIndex,
|
getPackIndex,
|
||||||
|
@ -197,6 +179,7 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
Slider,
|
Slider,
|
||||||
Multiselect,
|
Multiselect,
|
||||||
|
FilterNameSort,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
|
@ -226,13 +209,15 @@ export default {
|
||||||
totalRows: 0,
|
totalRows: 0,
|
||||||
},
|
},
|
||||||
// Sorting.
|
// Sorting.
|
||||||
sortBy: 'name',
|
sorts: {
|
||||||
direction: 'asc',
|
sortBy: 'name',
|
||||||
sortOptions: [
|
direction: 'asc',
|
||||||
{ value: 'name', label: game.i18n.localize('Name') },
|
sortOptions: [
|
||||||
{ value: 'cr', label: game.i18n.localize('Challenge Rating') },
|
{ value: 'name', label: game.i18n.localize('Name') },
|
||||||
{ value: 'size', label: game.i18n.localize('Size') },
|
{ value: 'cr', label: game.i18n.localize('Challenge Rating') },
|
||||||
],
|
{ value: 'size', label: game.i18n.localize('Size') },
|
||||||
|
],
|
||||||
|
},
|
||||||
// Our list of pseudo documents returned from the compendium.
|
// Our list of pseudo documents returned from the compendium.
|
||||||
packIndex: [],
|
packIndex: [],
|
||||||
// Filters.
|
// Filters.
|
||||||
|
@ -279,8 +264,8 @@ export default {
|
||||||
* Click event to reset our filters.
|
* Click event to reset our filters.
|
||||||
*/
|
*/
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
this.sortBy = 'name';
|
this.sorts.sortBy = 'name';
|
||||||
this.direction = 'asc';
|
this.sorts.direction = 'asc';
|
||||||
this.name = '';
|
this.name = '';
|
||||||
this.crRange = [0, 30];
|
this.crRange = [0, 30];
|
||||||
this.legact = '';
|
this.legact = '';
|
||||||
|
@ -292,10 +277,6 @@ export default {
|
||||||
this.size = [];
|
this.size = [];
|
||||||
this.creatureType = [];
|
this.creatureType = [];
|
||||||
},
|
},
|
||||||
changeDirection() {
|
|
||||||
if (this.direction === "asc") this.direction = "desc";
|
|
||||||
else this.direction = "asc";
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Get multiselect options.
|
* Get multiselect options.
|
||||||
*/
|
*/
|
||||||
|
@ -386,7 +367,7 @@ export default {
|
||||||
// Sort.
|
// Sort.
|
||||||
result = result.sort((a, b) => {
|
result = result.sort((a, b) => {
|
||||||
// Add sorts here.
|
// Add sorts here.
|
||||||
switch (this.sortBy) {
|
switch (this.sorts.sortBy) {
|
||||||
case 'cr':
|
case 'cr':
|
||||||
return a.system.details.cr - b.system.details.cr;
|
return a.system.details.cr - b.system.details.cr;
|
||||||
case 'size':
|
case 'size':
|
||||||
|
@ -394,7 +375,7 @@ export default {
|
||||||
}
|
}
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
});
|
});
|
||||||
if (this.direction === "desc") {
|
if (this.sorts.direction === "desc") {
|
||||||
result = result.reverse();
|
result = result.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<template>
|
||||||
|
<div class="filtercontainer">
|
||||||
|
<!-- Name filter. -->
|
||||||
|
<div class="filter">
|
||||||
|
<input type="text" name="compendiumBrowser.name" v-model="value" :placeholder="game.i18n.localize('Name')" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Sort -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{ game.i18n.localize('Sort by:') }}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
<select class="sort" v-model="filters.sortBy">
|
||||||
|
<option v-for="(option, index) in filters.sortOptions" :key="index" :value="option.value">{{ option.label }}</option>
|
||||||
|
</select>
|
||||||
|
<a class="direction" data-direction="asc" @click="changeDirection()">
|
||||||
|
<i v-if="filters.direction === 'asc'" class="fa-solid fa-sort-numeric-up"></i>
|
||||||
|
<i v-else class="fa-solid fa-sort-numeric-down-alt"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FilterNameSort',
|
||||||
|
// Use a modelValue prop and emit to allow v-model on this component.
|
||||||
|
// The name input itself will use a computed property named value that
|
||||||
|
// has both a getter and setter which are automatically triggered by
|
||||||
|
// v-model.
|
||||||
|
props: ['modelValue','filters'],
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
components: {},
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
// Expose Foundry globals to the template.
|
||||||
|
CONFIG,
|
||||||
|
game
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {},
|
||||||
|
methods: {
|
||||||
|
// updateValue(event) {
|
||||||
|
// this.valueMutable = event.target.value;
|
||||||
|
// console.log(event.target.value);
|
||||||
|
// this.$emit('update:value', event.target.value);
|
||||||
|
// },
|
||||||
|
changeDirection() {
|
||||||
|
if (this.filters.direction === "asc") this.filters.direction = "desc";
|
||||||
|
else this.filters.direction = "asc";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
value: {
|
||||||
|
// Retrieve the internal value.
|
||||||
|
get() {
|
||||||
|
return this.modelValue;
|
||||||
|
},
|
||||||
|
// In addition to setting the internal value,
|
||||||
|
// emit the new value to the parent.
|
||||||
|
set(value) {
|
||||||
|
this.$emit('update:modelValue', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async created() {},
|
||||||
|
async mounted() {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
</style>
|
Loading…
Reference in New Issue