matfish2 / vue-tables-2

Vue.js 2 grid components
https://matanya.gitbook.io/vue-tables-2/
GNU General Public License v3.0
1.53k stars 305 forks source link

Using standard column filter inputs to apply custom filters #366

Closed ibanjo closed 6 years ago

ibanjo commented 6 years ago

I've been tinkering a lot with custom filters, and managed to apply one by using external inputs. However, it would be very nice if the standard inputs provided on each column when filterByColumn is enabled to trigger custom filters. It would be very useful, e.g. in presence of deeply structured data (i.e. some fields are, in turn, Objects).

Consider this minimal example:

Vue VM:

Vue.use(ClientTable);
Vue.component('structured', require('./components/StructuredComponent'));

const app = new Vue({
    el: '#app',
    methods: {
        filterStructured: function () {
            Event.$emit('vue-tables.filter::mystructured', 'horse');
        }
    },
    data: {
        countries: getData(),
        columns: ['name', 'code', 'structured'],
        options: {
            headings: {
                name: 'Country Name',
                code: 'Country Code',
                structured: 'Structured Data'
            },
            templates: {
                structured: 'structured'
            },
            sortable: ['name', 'code'],
            filterable: ['name', 'code', 'structured'],
            filterByColumn: true,
            customFilters: [{
                name: 'mystructured',
                callback: function(row, query) {
                    return row.structured.word.indexOf(query) !== -1;
                }
            }]
        }
    }
});

HTML:

<div id="app" class="container" align="center">
    <div class="row">
        <div class="col-md-12">
            <button @click="filterStructured">Apply Filter</button>
        </div>
        <v-client-table :columns="columns" :data="countries" :options="options">
        </v-client-table>
    </div>
</div>

Structured Vue template:

<template>
    <dl>
        <dt>{{ data.structured.number }}</dt>
        <dd>{{ data.structured.word }}</dd>
    </dl>
</template>

<script>
    export default {
        name: 'structured',
        props: ['data', 'index']
    }
</script>

Of course, this trivial example filters data with a fixed 'horse' query, but it's very straightforward to use an external text input to do the same exact thing.

Now, what I would like to do is to intercept the 'vue-tables.filter::structured' and do something like:

Event.$on('vue-tables.filter::structured', (payload) => {
    Event.$emit('vue-tables.filter::mystructured', payload);
});

I tried it, to no avail. This is because the chain of events emitted is:

vue-tables.filter $emit by <Root>
filter $emit by <ClientTable>
vue-tables.filter::mystructured $emit by <Root> // That's my custom filtering event, but then...
vue-tables.filter::structured $emit by <Root> // This should not happen!
filter::structured $emit by <ClientTable>

Is there any way to prevent the default filtering action? If necessary I may quickly prepare a JSFiddle.

matfish2 commented 6 years ago

Have you read the end of the Slots part in the docs?

ibanjo commented 6 years ago

Sorry, totally my bad, it was already in the docs. Thank you, by the way!