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

Trouble with translating code from JavaScript to Python due to hash algorithm discrepancy

In an attempt to achieve consistent hash function results between JavaScript and Python, I encountered a roadblock when trying to convert my JavaScript function to its Python equivalent, resulting in unexpected outcomes. Original JavaScript Function: func ...

Ajax is displaying some unusual behavior

Currently, I am working on an ajax request to check if a specific combination of username or password exists. <script> $("form").submit(function(e){ e.preventDefault(); //send data to ajax file now $.ajax({ type: 'POST ...

Mastering the ng-submit directive for AngularJS

Having an issue with my form that submits a location to Google's Geocoder and updates the map with the lat/long. When using ng-click on the icon, it requires double clicking to work properly. And when using ng-submit on the form, it appends to the URL ...

Developing a custom npm package that integrates both Vue and Vuex for seamless integration in a

I am in the process of breaking down a Vue/Vuex project into an npm package that will be privately hosted. I believe I'm making progress, but I have some doubts about my current structure. Here's what I have so far: src/ ├── BrokerProposal ...

Unable to get PrependTo to remove itself when clicked

Below is a custom jQuery script I put together: $(function(){ $("a img").click(function() { $("<div id=\"overlay\"></div>").hide().prependTo("body").fadeIn(100); $("body").css({ ...

Display a spinning wheel or progress bar while the website is in the process of loading

Looking to construct a treeview using the jquery-treeview plugin but noticing it's quite time-consuming (about 5-7 seconds). I'm interested in adding a spinning wheel or progress bar to indicate loading while the page is processing. Any suggestio ...

Attempting to create an auto-suggestion tool that can process and accept multiple input values, filtering out only those that begin with a designated character

I've been working on implementing an auto-suggestion feature that displays suggestions with partial matches or values within the input box. The goal is for it to only provide suggestions that begin with a specific character, like the "@" symbol. Fo ...

What is the process of integrating BootstrapVue into our Vue.js project?

Currently, I am working with Vue.js and trying to integrate Bootstrap-vue into my project. However, I am encountering some issues where the screen turns black and none of the functionalities work properly once BootstrapVue is attached. Can someone please ...

Tips for simulating focus on a Material-ui TextField with a button press

My web application features a unique method for indirectly filling in text fields. Since there are multiple clicks involved (specifically in a calendar context) and numerous fields to fill, I want to provide users with a visual indication of which field th ...

Firefox triggers drag events while passing over a div scrollbar

I am looking to create a file drag and drop feature using a styled div: When dragging files over the div, I want the border color to change When dragging files out of the div, I want the border color to revert back to the original In Firefox 35 (Ubuntu) ...

Sticky header in React data grid

Is there a way to implement a sticky header for a data grid in react? I have tried various methods but haven't been able to figure it out. Any suggestions would be appreciated. You can find my code sandbox example here. #react code export const Styl ...

In jQuery, utilizing dynamic class names with variables

I have a series of images with unique classes such as: .1a .2a .3a .4a ..... I am looking to toggle some other classes named .1b .2b .3b .. and so on so that: '.1a' toggles to '1b' '.2a' toggles to &ap ...

What is the best way to arrange an array or display it accurately?

Guys, here's a challenge for you: extract the values from this JSON data: [[name, brand, oem, category], [name, brand, oem, category], [name, brand, oem, category], [name, brand, oem, category]] Check out my JavaScript code: $(function(){ $('i ...

Issue with loading CSS and JavaScript following a GET request

I initially used express and the render function to display different pages on my website. However, I've now decided to switch to vanilla JavaScript instead. The objective is to load the HTML file along with all the necessary JS and CSS files. Below i ...

What could be causing the Metamask account address to return as undefined even after it was stored in the useState() function?

A code snippet I have establishes a connection to the Metamask wallet and initializes the account address using useState() hook. const [currentAccount, setCurrentAccount] = useState("") const connectWallet = async () => { try { if (! ...

Navigate to the location using AngularJS elements in the JavaScript iframe1

Dealing with an issue while working on AngularJS. I am facing a frustrating problem where I am attempting to use one link to open links in two separate iframes. All aspects of this function correctly, except for the actual links. The issue arises when usin ...

Formik's setField function is not properly updating the value of an array when using Material UI's autocomplete

When the data is retrieved from the API, it comes in the following format: otherLanguages:[{code:EN,name:"English"},{code:MD,name:"Mandarin"}] I am attempting to initialize the Autocomplete with this data: initialValues: { otherLa ...

Is node.js required for utilizing Angularjs?

Considering incorporating angular.js into my website's Image Editing Tool. Is node.js necessary for this integration? I'm a bit puzzled here. Are there instances where both nodejs and angularjs are used together, or can they operate independentl ...

Encountering issues with Office.context.document.getFileAsync function

I am experiencing a strange issue where, on the third attempt to extract a word document as a compressed file for processing in my MS Word Task Pane MVC app, it crashes. Here is the snippet of code: Office.context.document.getFileAsync(Office.FileType.Co ...

Using ajax to submit a request to the controller

I'm currently developing an ASP.NET Core MVC application and have a registration page set up. My goal is to return View with errors if the model state is false: @model WebApplication2PROP.Entities.UserRegister @* For more information on enabling M ...