Searching for multiple filtered items in Vue.js

When working with Vue js, searching through a list is straightforward. However, when dealing with a large dataset of 1000 records and needing to apply specific filters for user searches, I find myself at a loss. Is there a plugin or method that can help me achieve this? I've tried searching but haven't found a suitable solution. To illustrate, imagine users who have the statuses "blocked" and "close" need to be filtered in search results. I've attempted to visualize this process, but being new to Vuejs, I would greatly appreciate if someone could provide an example. Thank you in advance.

https://i.stack.imgur.com/Liyrd.gif

const app = new Vue({
    el: '#app',
    data: {
        search: '',
        userList: [
            {
                id: 1,
                name: "Prem",
                age: 18,
                status: "close",
                gender: "male",
            },
            {
                id: 2,
                name: "Chandu",
                status: "close",
                age: 20,
                gender: "female",
            },
            {
                id: 3,
                name: "Shravya",
                status: "open",
                age: 35,
                gender: "female",
            },
            {
                id: 4,
                name: "Shravya",
                status: "blocked",
                age: 35,
                gender: "female",
            }
        ]
    },
    computed: {
        filteredAndSorted() {
            function compare(a, b) {
                if (a.name < b.name) return -1;
                if (a.name > b.name) return 1;
                return 0;
            }

            return this.userList.filter(user => {
                return user.name.toLowerCase().includes(this.search.toLowerCase())
            }).sort(compare)
        }
    }
});
$(document).ready(function () {
    $('.dropdown-submenu a.test').on("click", function (e) {
        $(this).next('ul').toggle();
        e.stopPropagation();
        e.preventDefault();
    });
});
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
}

td, th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #dddddd;
}

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu .dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<div class="dropdown">
    <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">Filtered
        <span class="caret"></span></button>
    <ul class="dropdown-menu">
        <li><a tabindex="-1" href="#">Name</a></li>
        <li><a tabindex="-1" href="#">Age</a></li>
        <li><a tabindex="-1" href="#">Gender</a></li>
        <li class="dropdown-submenu">
            <a class="test" tabindex="-1" href="#">Status <span class="caret"></span></a>
            <ul class="dropdown-menu">
                <li>
                    <input type="checkbox" value="close">
                    <button>Close</button>
                </li>
                <li>
                    <input type="checkbox" value="open">
                    <button>Open</button>
                </li>
                <li>
                    <input type="checkbox" value="blocked">
                    <button>Blocked</button>
                </li>
            </ul>
        </li>
    </ul>
</div>
<div class="search-wrapper">
    <input type="text" v-model="search" placeholder="Search title.."/>
</div>
<table>
    <tr>
        <th>Name</th>
        <th>Age</th>
        <th>Status</th>
        <th>Gender</th>
    </tr>
    <tr v-for="user in filteredAndSorted">
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
        <td>{{ user.status }}</td>
        <td>{{ user.gender }}</td>
    </tr>

</table>
</div>

Answer №1

Here is a custom snippet I created for you without the need for jQuery:

const app = new Vue({
    el: '#app',
    data: {
        search: '',
        selected: 'name',
        choice: '',
        choicesArr: [],
        options: [
          { text: 'Name', value: 'name' },
          { text: 'Age', value: 'age' },
          { text: 'Gender', value: 'gender' },
          { text: 'Status', value: 'status' }
        ],
        userList: [
            {
                id: 1,
                name: "Prem",
                age: 18,
                status: "close",
                gender: "male",
            },
            {
                id: 2,
                name: "Chandu",
                status: "close",
                age: 20,
                gender: "female",
            },
            {
                id: 3,
                name: "Shravya",
                status: "open",
                age: 35,
                gender: "female",
            },
            {
                id: 4,
                name: "Shravya",
                status: "blocked",
                age: 35,
                gender: "female",
            }
        ]
    },
    computed: {
      filteredAndSorted() {
        function compare(a, b) {
          if (a[this.selected] < b[this.selected]) return -1;
          if (a[this.selected] > b[this.selected]) return 1;
          return 0;
        }
        return this.userList.filter(user => {
          if (this.selected === "age") {
            if(this.choicesArr.length) {
              return this.choicesArr.indexOf(user[this.selected]) >= 0
            } else {
              return !this.search || user[this.selected] === Number(this.search)
            }
          } else {
            if(this.choicesArr.length) {
              return this.choicesArr.indexOf(user[this.selected]) >= 0
            } else {
              return user[this.selected].toLowerCase().includes(this.search.toLowerCase())
            }
          }
        }).sort(compare)
      },
      choices: function() {
        return [...new Set(this.userList.map(user => user[this.selected]))];
      }  
    },
    methods: {
      addChoice() {
        this.choicesArr.push(this.choice)
        console.log(this.choicesArr)
      },
      reset() {
        this.choice = ""
        this.choicesArr = []
      }
    }
});
table {
    font-family: arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
}

td, th {
    border: 1px solid #dddddd;
    text-align: left;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: #dddddd;
}

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu .dropdown-menu {
    top: 0;
    left: 100%;
    margin-top: -1px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
  <select v-model="selected" >
    <option value="" disabled>Select option</option>
    <option v-for="option in options" v-bind:value="option.value" >
      {{ option.text }}
    </option>
  </select>
  <select v-model="choicesArr" multiple>
    <option v-for="option in choices" v-bind:value="option" @click="addChoice">
      {{ option }}
    </option>
  </select>
  <button @click="reset">Clear filters</button>
  <div class="search-wrapper">
      <input type="text" v-model="search" placeholder="Search title.."/>
  </div>
  <table>
    <tr>
        <th>Name</th>
        <th>Age</th>
        <th>Status</th>
        <th>Gender</th>
    </tr>
    <tr v-for="user in filteredAndSorted">
        <td>{{ user.name }}</td>
        <td>{{ user.age }}</td>
        <td>{{ user.status }}</td>
        <td>{{ user.gender }}</td>
    </tr>

</table>
</div>

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

Error encountered in Next.js when defining columns for a MUI data grid

Currently, I am integrating MUI Data Grid into a Next.js app under development. While attempting to define a more intricate column structure, I encountered an error: { field: 'home_address', valueGetter: (value, row) => { retur ...

What is the proper way to implement JQuery within a constructor function contained in a JavaScript namespace?

Yesterday I ran into a problem when asking about using JQuery inside a JavaScript constructor function within a namespace. There was a bug in my code that caused me to get the answer to the wrong question. var NS=NS||{}; NS.constructor=function() { t ...

Displaying text files containing escaped characters using Express.js

I am facing an issue with my JSON object that has a text file within one of its fields. When I have Express render this text as "text/plain" in the response, it does not respect the '\n' line breaks and instead prints everything on one line. ...

What makes 'Parsing JSON with jQuery' unnecessary?

Just performed an ajax request with a query and noticed that my response is already in the form of a JavaScript object. When I try to parse the JSON using: var obj = jQuery.parseJSON(response); 'obj' turns out to be null, yet I can directly ac ...

Creating unique sizes for each quad in Three.js using InstancedBufferGeometry and ShaderMaterial

I'm working on creating a visually dynamic scene filled with points of varying widths and heights. The challenge I'm facing is figuring out how to manipulate the vertices in the vertex shader to achieve customized sizes for each point. Here' ...

Connecting to an Oracle database using Alfresco's Javascript API may seem daunting at first, but

Currently, I am working on a project that involves using Alfresco. One of the new requirements for this project is to retrieve a sequence number from our Oracle database and populate a custom property within an Alfresco space. var conObj = new ActiveXObje ...

Node.js and Express facing challenge with Stripe checkout functionality

I am encountering an issue while attempting to integrate stripe into my checkout process. When I click on the checkout button, instead of being directed to the checkout page, I receive the following message: {"url":"https://checkout.stripe.c ...

Tips for efficiently transmitting JSON information from Nuxt Axios to a FastAPI server via a POST operation

Currently, I am attempting to transmit user data from Nuxt.js using Axios through a POST request. The data is being fetched via a JavaScript CDN function that returns an object containing user parameters, so avoiding the usage of a form is preferred as I w ...

Ways To Obtain Trustworthy Dates Using JavaScript

Last week, I encountered an intriguing issue at my job. I needed to obtain a date accurately using JavaScript, but the code I was working with utilized new Date() which resulted in discrepancies due to some customers having incorrect system time settings. ...

The event listener for the custom cursor in Nuxt.js is failing to work properly when the route

I am currently in the process of constructing a new website for our studio, but am encountering difficulties with getting the custom cursor to function correctly. I implemented a custom cursor using gsap, and it worked perfectly; however, once I navigate t ...

Find the flowplayer when the page loads

Is there a way to make a flowplayer seek at the page load without it resetting? I've tried this: $(document).ready(function() { $f(0).seek(5); }); also tried: $(document).ready(function() { while(!$f(0).isLoaded()) { $f(0).seek(5); } }); ...

Ways to transform an ISO string formatted date time into the following hour

I have a function that converts my date to RFC3339 format, but I want it to be converted to the upper time limit. Could someone please help me figure out how to convert it to the upper limit? const date = new Date(); // converting to RFC 3339 format ...

Troubleshooting Database Saving Problem with Vue.js and Ruby on Rails

Trying to configure a nested form with Vue.js in a Rails application to save ingredients for a recipe. While all other details of the ingredients are saving correctly, the ingredient name (from an input field) is not getting saved in the database. How can ...

Automated playback of integrated Twitter video

Is there a way to make embedded Twitter videos autoplay? The code generates an iframe which is preventing me from using some JavaScript click tricks. Is there a workaround to enable autoplay? Plunker <script>window.twttr = (function(d, s, id) { v ...

Is there a way to showcase the generated results on a graph after the user presses the submit button?

I've been working with to generate a bar chart. Currently, when the user clicks 'submit', the input numbers are shown in a graph on http://jsfiddle.net/jx9sJ/5/. Now, I want to make some changes. I am attempting to send the input numbers t ...

Tips for modifying the value of a JSON object using Javascript or Jquery

I am looking to retrieve the value of a specific key, potentially accessing nested values as well. For example, changing the value of "key1" to "value100" or "key11" to "value111. { "key1": "value1", "key2": "value2", ...

The underscore (_) parameter in HTTP GET requests

Lately, I've been seeing the '_' parameter on many websites with a seemingly random string attached to it. For example: website.com/?_=98765432 Can someone explain the significance of this parameter and how these numbers are generated? ...

Add jQuery and underscore libraries to an AngularJS component

For my new service, I am incorporating angularjs, underscore, and jQuery: myModule.factory('MyService', ['MyResource', function (MyResource) { .... // Utilizing _ and $ }]); How can I properly inject underscore and jQuery int ...

Creating PDF files with Laravel serving as the API and Vue acting as the front-end client

My current setup involves using Laravel as an API and Vue as the client. To generate PDFs, I'm utilizing the barryvdh package which can be found at this link. I've created a page with some static elements for testing purposes. Below is the code s ...

The Typescript function unexpectedly returns a NaN value even though it should be returning a

Having an issue with my countdown timer function: startTimer(duration) { this.myTimer = duration; setInterval(function () { this.myTimer--; console.log("TIMER: " + typeof(this.myTimer) + " " + this.myTimer); }, 1000); } When I ...