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

Is it possible to extract elements from a single list and insert them onto various pages?

Currently, I am retrieving items from a list using an ajax call. After constructing the HTML content, I insert these items onto a page. Now, I want to extract the same items and display them on another page with a different style. Is there a method to conn ...

When a Javascript function marked as async is executed, it will return an object

Async function is returning [object Promise] instead of the desired real value. Interestingly, I can see the value in the console log. It seems like this behavior is expected from the function, but I'm unsure how to fix my code. This code snippet is ...

What is the reason for not being able to use a fixed number instead of referring to this.item.number?

<template> <Page> <ActionBar title="item" /> <ScrollView> <StackLayout> <Label textWrap="true" v-for="n in times" :text="n" /> </StackLayout> < ...

Is there a way to turn off the auto-complete feature for JavaScript keywords in HTML within JSX in WebStorm?

While using WebStorm, I've noticed that it automatically completes JavaScript keywords as I type regular text in JSX. This behavior is starting to frustrate me because I have to constantly press ESC or click elsewhere to hide the auto-complete popup. ...

Stop JavaScript Injection Attacks

Let's consider a scenario where a user inputs information into a form that is then submitted to the server using PHP. In the PHP code, we have: $data = $_POST['data']; // or $data = strip_tags(@$_POST['data']); I am curious t ...

Blend express router by chaining the (.route) method with other HTTP methods like (.get, .post, etc) to create

Here is my code structure: let router = require( 'express' ).Router(); Later on, I define my routes like this: router .route( '/' ) .get( listMiddleware ); router .route( '/:id' ) .get( getOneByIdMiddleware ...

Is it possible to have separate ports for front-end and back-end in NODEJS?

As I develop my NodeJS website, incorporating both front-end and back-end components, it is recommended to organize the files in such a way that the front-end specifically requests data from the back-end via an API. I am curious whether it is considered a ...

The like button seems to be malfunctioning and I'm not sure what the issue is

I've added the ability for users to like my posts, but it's not working as intended. Here's the code snippet I used: models.py class Post(models.Model): title = models.CharField(max_length=100) content = models.TextField(blank=Tru ...

What is the best way to attach an event listener to a div so that clicking on it increases the width and height of the div by 20%?

I've started working on it and decided to use the same dimensions (100px by 100px) as a previous question. Right now, I'm sticking with just Javascript, but I might incorporate jQuery down the line. One big issue is that in the line (this.style.w ...

Is it necessary for a click handler to be triggered when clicking on a scrollbar?

Check out these HTML snippets: Jsfiddle <style> div { margin:20px; border: 30px red solid; padding: 20px; background-color:green; overflow-y:scroll; } </style> <div onclick="alert('div clicked');"> ...

Horizontal navigation bar encroaching on slideshow graphics

I'm encountering difficulties aligning the horizontal menu below the image slider. When I have just an image without the slider, the menu aligns properly (vertically), but as soon as I introduce the code for the slider, the menu moves to the top and d ...

`Issues encountered with resizing the menu``

Looking to create a unique restaurant horizontal list bar for my application. The goal is to have a horizontal menu that displays 3 options on the screen at a time, with the middle one being the largest and the two flanking it smaller in size. As I scroll ...

Sending JSON data back to the server using KeyValuePair in C#

My goal is to send my JSON list back to the POST method (EditCompanyReportField) on the C# server side. The related parameter (fieldSorted) in my method is an array object, but the values are not being passed through. I have a few question marks regarding ...

The Storybook file is unable to find and import the corresponding .vue file

Issue with Importing Vue File in Storybook I am facing an issue while trying to import a vue file (component/index.vue) into my storybook file (component/index.stories.ts). The compilation is failing and the import cannot be completed. component/index.st ...

Progress bar indicating the loading status of an AJAX script

I am facing a challenge with creating a progress bar in AJAX. The entire page is loaded through AJAX, and one of the webpage elements uses AJAX to fetch large rows from the database. I have attempted to implement a progress bar within this script using a ...

The seamless union of Vuestic with Typescript

Seeking advice on integrating Typescript into a Vuestic project as a newcomer to Vue and Vuestic. How can I achieve this successfully? Successfully set up a new project using Vuestic CLI with the following commands: vuestic testproj npm install & ...

Tips on concealing or deactivating the "sort by" input and label for the Vuetify 3 <v-data-table> when in mobile view

Utilizing a vuetify <v-data-table> to display some data : On Mobile: The Code: <v-data-table-server :items-per-page="itemsPerPage" :headers="headers" :items="serverItems" :items-length="totalI ...

The type 'string | undefined' cannot be assigned to type 'string'

I am facing a challenge in comparing two arrays, where one array is sourced from a third-party AWS service and its existence cannot be guaranteed. Despite my efforts to handle potential errors by incorporating return statements in my function calls, I con ...

Having trouble exporting a variable from one Node.js file to another and finding that the value remains unchanged?

Hey there, I've been working on exporting a variable to another file within my nodejs application. I have successfully exported the variable, however, I need it to update whenever a user logs in. Will the export automatically pick up on this change an ...

Tips for transfering variables from an electron application to the backend of an Angular project

My goal is to develop a website and desktop application using the same code base. However, due to some minor differences between the two platforms, I need a way for my Angular app to distinguish whether it has been called from the web or from Electron. I& ...