Enhance Your Vue Tables with Unique Custom Filters

I'm currently working on implementing https://github.com/matfish2/vue-tables-2 in Vue 2.1.8.

Everything seems to be functioning flawlessly, but I need to incorporate custom filters to format certain fields based on their values.

In my options object, I have the following:

customFilters: [
{
  name:'count',
  callback: function(row, query) {
    console.log('see me?'); // Not triggering this
    return row.count[0] == query;
}
}
]

The documentation suggests using the event bus like so:

Using the event bus:

Event.$emit('vue-tables.filter::count', query);

However, I am unsure where to place this code. I have attempted placing it in various locations, such as within my axios success callback, with no success.

This may seem like a basic issue that I should already know how to resolve, but unfortunately, I am unsure. Any guidance on where to implement the event bus functionality would be greatly appreciated!

Answer №1

The documentation could use some improvement in explaining this concept. It's a bit challenging to grasp the idea.

To make use of the event bus in vue-tables-2, you need to import the named export Event. This will allow you to have access to the table's event bus and emit custom events within your click handler.

In the demo, the named export is available on the global object. In ES6, you can import it as shown in the documentation using

import { ServerTable, ClientTable, Event } from 'vue-tables-2';

Feel free to check out the alphabet filter demo below or on this sandbox.

This demo is similar to the demo fiddle for vue-tables-1 which can be accessed here.

// Vue.use(VueTables)
const ClientTable = VueTables.ClientTable
const Event = VueTables.Event // import eventbus

console.log(VueTables);
Vue.use(ClientTable)

new Vue({
  el: "#people",
  methods: {
    applyFilter(letter) {
      this.selectedLetter = letter;
      Event.$emit('vue-tables.filter::alphabet', letter);
    }
  },
  data() {
    return {
      letters: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
      selectedLetter: '',
      columns: ['id', 'name', 'age'],
      tableData: [{
        id: 1,
        name: "John",
        age: "20"
      }, {
        id: 2,
        name: "Jane",
        age: "24"
      }, {
        id: 3,
        name: "Susan",
        age: "16"
      }, {
        id: 4,
        name: "Chris",
        age: "55"
      }, {
        id: 5,
        name: "Dan",
        age: "40"
      }],
      options: {
        // see the options API
        customFilters: [{
          name: 'alphabet',
          callback: function(row, query) {
            return row.name[0] == query;
          }
        }]
      }
    }
  }
});
#people {
  text-align: center;
  width: 95%;
  margin: 0 auto;
}
h2 {
  margin-bottom: 30px;
}
th,
td {
  text-align: left;
}
th:nth-child(n+2),
td:nth-child(n+2) {
  text-align: center;
}
thead tr:nth-child(2) th {
  font-weight: normal;
}
.VueTables__sort-icon {
  margin-left: 10px;
}
.VueTables__dropdown-pagination {
  margin-left: 10px;
}
.VueTables__highlight {
  background: yellow;
  font-weight: normal;
}
.VueTables__sortable {
  cursor: pointer;
}
.VueTables__date-filter {
  border: 1px solid #ccc;
  padding: 6px;
  border-radius: 4px;
  cursor: pointer;
}
.VueTables__filter-placeholder {
  color: #aaa;
}
.VueTables__list-filter {
  width: 120px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dea8abbbf3aabfbcb2bbadf3ec9eeff0eaf0e9ee">[email protected]</a>/dist/vue-tables-2.min.js"></script>
<div id="people">
  <button @click="applyFilter(letter)" class="btn btn-default" v-for="letter in letters" :class="{active: letter==selectedLetter}">
    {{letter}}
  </button>
  <button  class="btn btn-default" @click="applyFilter('')">
  clear
  </button>
  <v-client-table :data="tableData" :columns="columns" :options="options"></v-client-table>
</div>

Answer №2

This particular tutorial really resonated with me. Visit the lesson here

In essence: The lesson emphasizes emitting events using the vue-events package or computing properties with Vuex (highly recommended). An important feature to note is the usage of :append-params="moreParams" on vuetable, as it appends additional values to the api-url, distinct from existing pagination parameters. For my setup, I opted for utilizing Vuex and making moreParams a computed property of the vuetable. This computed property leverages this.$store.getters.moreParams, aligning perfectly with my requirement for multiple search fields. It reacts responsively to changes in Vuex commits triggered by input field interactions.

    computed: {
      moreParams() {
        return this.$store.getters.moreParams
      },
    },

An alternative approach involves using $store.stage.property. I implemented a watch on moreParams that automatically refreshes the table upon querying:

    watch: {
      moreParams(newVal, oldVal) {
        this.$nextTick(() => {
          this.$refs.vuetable.refresh()
        })
      },
    },

Answer №3

Make the default filter and per page selection box disappear, and introduce a new filter called 'manual_agent'.

        optionsTable: {
            customFilters: ['manual_agent'],
            filterable: false,
            perPageValues: []
        },

The reason for hiding them is that there is no 'slot' option available to insert new custom filters between the default ones and the per page select box, and the default ones are not very responsive either. The following example pertains to server table implementation.

Here is the method to globally utilize custom filters:

toggleFilter: function(filterName, $event) {
                this.$refs.serverTableRef.setPage(1);
                setTimeout(function () {
                    let searchItem = '';
                    if (typeof $event === 'string') { searchItem = $event; } else { searchItem = $event.target.value; }
                    let table = this.$refs.serverTableRef;
                    table.customQueries[filterName] = searchItem;
                    table.getData();
                }.bind(this), 1000);
            }

In order for this to function properly, we must have a defined ref name on our v-server table like so:

<v-server-table ref="serverTableRef"

Next, in the template create a new custom select box filter (the v-model refers to a custom variable defined in data)

<select name="typeoftrip" v-model="agentFilter" @change="toggleFilter('manual_agent', agentFilter)">

Then add a custom filter that will replace the lost default filter by disabling it. (it used 'query' name so we use the same one)

<input name="typeoftrip" v-model="mainQuery" v-on:keyup="toggleFilter('query', mainQuery)">

Lastly, include a new custom select for our own per page selection

            <select v-model="limitFilter"  @change="$refs.serverTableRef.setLimit($event.target.value)" >
                <option value="10">10</option>
                <option value="25">25</option>
                <option value="50">50</option>
            </select>

Answer №4

Check out the updated fiddle if you're interested in experimenting with it. I'm still figuring out how to get it to work with nested, single page components.

customFilters: [{
  name: 'alphabet',
  callback: function(row, query) {
    return row.name[0] == query;
  }
}]

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Fetching an image from Firebase Storage for integration into a Vue application

I am encountering an issue while trying to fetch an image from my firebase storage to display it in my Vue application. The upload process from the app to firebase storage runs smoothly, but there is an error during retrieval. My setup involves using the F ...

Error in Vue.js 2 Composition API: Trying to access 'length' property of undefined object

Greetings to the Vue.js user community! I'm facing a challenging issue that I can't seem to resolve: I am currently using Vue.js 2.x on Windows 11. Whenever I run yarn install or npm install, I encounter an error as displayed in the console. Vi ...

What is the reason for Next.js and Gatsby.js necessitating the installation of Node.js, while React.js does not have that requirement?

Have you ever thought about the connection between Next.js and Gatsby.js, both being built on React.js? Could it be that the development environments are Node applications themselves? Or maybe there's something else I'm not seeing? While I have ...

Clicking on the parent page prevents the hyperlink inside the iframe from working as expected

I am having an issue with a hyperlink inside an iframe. When I click on it in the parent page, it doesn't work. Here is how it is set up: iframe.html <h1>I'm inner page!</h1> <a id="shared" class="btn" href=&q ...

What could be the reason behind my Vue custom directives not functioning as expected?

I'm brand new to Vue and very inexperienced with custom directives. I'm attempting something basic, but it doesn't seem to be working correctly. Can someone please help me figure out what's wrong? Thank you in advance! I have created tw ...

The Material UI Rating Component is malfunctioning and showing an incorrect value

I'm currently working on a component loop that takes in async data. Everything is rendering properly except for the first component, where the Rating component isn't displaying its value correctly (it just shows 0 stars). Here's the code: & ...

Incorporating an HTML element into a Vue template

I'm currently utilizing a chart component (Chartist) that needs an HTML element to serve as a parent during SVG rendering. The elements that the chart requires are generated within a v-for loop, meaning they are not part of the DOM when the chart is ...

What is the best way to fetch the id of the option that has been chosen from a bootstrap drop-down menu?

I recently created a basic drop-down list like this: https://i.sstatic.net/4Tlxx.png Here is the HTML code for it: <select class="form-control" id='0' (change)="retrieveValue($event.target)"> <option id='0'>{{ g ...

What could be causing my JavaScript/jQuery code to malfunction when dealing with checkboxes?

My code is supposed to select and disable checkboxes based on which radio button is clicked. For example, when Zero is selected, all checkboxes should be highlighted and disabled, except for the zeroth checkbox. However, this behavior does not consistent ...

What is the best way to loop through a list of questions and save the answers in an array of user input?

I'm encountering a challenge with iterating through an array of questions to correctly display them on the document. The initial code snippet provided below demonstrates what I aim to accomplish without using prompts. Currently, I have set up an arr ...

Modify the scoped variable using Angular's $resource module

I am facing an issue with my Angular application where I cannot get the results of a second $resource call to update a scoped variable. Initially, I am able to generate the initial view from an Angular $resource call to an external API and display the data ...

View the edited image preview instantly upon selecting the image

I have selected an image and previewed it before submitting the form. However, now I wish to be able to edit the file immediately after selecting it, preview the changes, and then submit the file. <input type ="file" accept="image/*" id="image" name="i ...

Customizing the "Actions" Dropdown in APEX Interactive Grid

Is there a way to modify the choices available in the Selection section of a Row Actions Menu in Apex? I managed to alter the options in the Line Menu, but I'm facing challenges when trying to make changes in the Selection Menu. The Selection Menu i ...

Connecting Vue component data to external state sources

I am facing a challenge with integrating a Vue component into a large legacy system that is not based on Vue. This component retrieves data through AJAX requests and displays information based on an array of database record IDs, typically passed at page lo ...

What is causing my controller action to create two new records instead of just one?

My current issue involves a simple Razor view featuring a button designed to add a new record to a table within my SQL database. The button is equipped with an Ajax function that triggers a call to the controller. I've experimented with two different ...

Invoking a Typescript function from the Highcharts load event

Struggling to call the TypeScript function openDialog() from the events.load of Highcharts? Despite using arrow functions, you are running into issues. Take a look at the code snippet below: events: { load: () => { var chart : any = this; ...

Guide on setting up and customizing run.json within the latest JetBrains Fleet for Next.js

I've been attempting to set up input/output for the latest IDE from JetBrains, Fleet. However, I've hit a roadblock and can't seem to figure it out on my own. That's why I'm turning to the Stack Overflow community for help - how do ...

hasOwnProperty function yields no results

I need help displaying a table from JSON data. Can someone assist me with the code below? <th> { x.amountForQuantity.filter((remaining) => { return remaining.hasOwnProperty(cost.key); })[cost.key] } </th> ...

A guide to sharing session variables with express views

Struggling to access session variables in EJS views and encountering various challenges. To locally access req.session, I've implemented middleware as outlined in this guide on accessing Express.js req or session from Jade template. var express = re ...

Converting sections of JSON data into boolean values

Is there a way to convert certain parts of a JSON string into booleans? Here is an example of my JSON string: { "file_id": { "width": "560", "height": "270", "esc_button": "1", "overlay_close": "1", "overl ...