skip to Main Content

I have the vue component below:

<template>
    <div class="container">
      <div class="row">
        <div class="col-md-4" v-for="product in products" :key="product.id">
          <div class="card mb-4">
            <!-- <img :src="product.image" class="card-img-top" alt="..."> -->
            <div class="card-body">
              <h5 class="card-title">{{ product.name }}</h5>
              <p class="card-text">{{ product.description }}</p>
              <a href="#" class="btn btn-primary">Buy</a>
            </div>
          </div>
        </div>
      </div>
      <nav>
      <ul class="pagination">
        <li class="page-item" :class="{ 'disabled': !links.prev }">
          <a class="page-link" @click.prevent="getProducts(links.prev)" href="#">Previous</a>
        </li>
        <li class="page-item">
            <span class="page-link">{{ meta.current_page }}/{{ meta.last_page }}</span>
        </li>
        <li class="page-item" :class="{ 'disabled': !links.next }">
          <a class="page-link" @click.prevent="getProducts(links.next)" href="#">Next</a>
        </li>
      </ul>
    </nav>
    </div>
</template>
<script>
export default {
    data(){
        return {
            products: [],
            meta: {},
            links: {}
        }
    },
    methods: {
        getProducts(url = '/api/products') {
            axios.get(url)
                .then(response => {
                this.products = response.data.data;
                this.meta = response.data.meta;
                this.links = response.data.links;
        });
        },
    },
    mounted(){
        this.getProducts();
    },
}
</script>

I have a simple resource API made with Laravel. When you load up the page, it lists the products from the database, and you can also paginate it.

How could I put a filtering option into it? Like a simple text input, and when you write something in it, the data is filtered?

I’ve tried binding a variable to the input and passing it to the getProducts method, but it didn’t work.

I’m very new to vue3 and a bit familiar with Laravel, so bear with me if possible…

2

Answers


  1. How could I put a filtering option into it? Like a simple text input, and when you write something in it, the data is filtered?

    What you need to do is just that: filter the data, and the best way to do this with Vue.js is to use a computed property.

    For instance, if you had a bunch of "product" data held in an array, data that had, for instance, id, name and description properties, and you also had a filterText field that held the text that you would use for filtering, then you could create a computed property, say called filteredProducts that returned this array filtered by the text of interest. You could even make this same computed property filter just the property name or both its name and description, if desired, something like so (using composition API):

    const filteredProducts = computed(() => {
        if (!filterText.value) {
            return store.products;
        } else {
            // if include description
            if (whatToFilter.value === 'nameAndDescription') {
                return store.products.filter((text) => {
                    return text.description.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1 || text.name.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1;
                });
            } else {
                return store.products.filter((text) => {
                    return text.name.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1;
                });
            }
        }
    });
    

    You could then use this computed property just as you would any other property in your program.

    A complete example could look like so:

    store.js

    class Store {
      constructor() {
        this.products = [
          {
            id: 1,
            name: "Lorem ipsum dolor sit amet",
            description:
              "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Aliquet risus feugiat in ante metus. Turpis in eu mi bibendum. Tellus integer feugiat scelerisque varius morbi. Feugiat nisl pretium fusce id velit ut. Curabitur vitae nunc sed velit dignissim sodales ut. Egestas integer eget aliquet nibh. Urna molestie at elementum eu facilisis sed. Sagittis aliquam malesuada bibendum arcu vitae elementum curabitur vitae. Facilisis volutpat est velit egestas dui id. Mauris vitae ultricies leo integer malesuada nunc vel.",
          },
          {
            id: 2,
            name: "Egestas purus viverra accumsan in nisl nisi scelerisque eu",
            description:
              "Egestas purus viverra accumsan in nisl nisi scelerisque eu. Eu non diam phasellus vestibulum lorem sed risus ultricies tristique. Penatibus et magnis dis parturient montes nascetur ridiculus. Massa sed elementum tempus egestas sed sed risus pretium. Risus pretium quam vulputate dignissim suspendisse in est. Nisl purus in mollis nunc sed id semper risus in. Quis commodo odio aenean sed. Id diam vel quam elementum pulvinar etiam. Quis ipsum suspendisse ultrices gravida dictum fusce ut placerat. Purus semper eget duis at tellus at. Vestibulum rhoncus est pellentesque elit. Augue interdum velit euismod in pellentesque massa placerat duis. Lacus vestibulum sed arcu non odio euismod. Ipsum dolor sit amet consectetur adipiscing elit ut aliquam. Dolor morbi non arcu risus quis varius quam quisque id. Adipiscing elit pellentesque habitant morbi tristique senectus et netus et. Tellus orci ac auctor augue mauris augue neque. Enim tortor at auctor urna nunc id cursus metus.",
          },
          {
            id: 3,
            name: "Commodo sed egestas egestas fringilla phasellus faucibus",
            description:
              "Commodo sed egestas egestas fringilla phasellus faucibus. Venenatis cras sed felis eget velit aliquet sagittis id. Vitae congue eu consequat ac felis donec et. Vivamus at augue eget arcu. Ultrices gravida dictum fusce ut placerat. Commodo nulla facilisi nullam vehicula. Mollis aliquam ut porttitor leo a diam. Viverra vitae congue eu consequat ac felis. Gravida quis blandit turpis cursus in. Neque convallis a cras semper auctor. Dui vivamus arcu felis bibendum ut. Phasellus egestas tellus rutrum tellus pellentesque eu. Turpis massa sed elementum tempus egestas sed sed risus. Mattis rhoncus urna neque viverra justo nec. Ipsum consequat nisl vel pretium lectus quam id. Pretium vulputate sapien nec sagittis aliquam. Ultricies integer quis auctor elit sed vulputate mi sit amet. Enim diam vulputate ut pharetra sit amet aliquam id. Senectus et netus et malesuada fames ac turpis.",
          },
          {
            id: 4,
            name: "Nunc congue nisi vitae suscipit tellus mauris a",
            description:
              "Nunc congue nisi vitae suscipit tellus mauris a. Eu feugiat pretium nibh ipsum. Malesuada nunc vel risus commodo viverra maecenas. Donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum arcu. Donec pretium vulputate sapien nec sagittis aliquam. Nibh sed pulvinar proin gravida hendrerit. Sed velit dignissim sodales ut. Ac placerat vestibulum lectus mauris ultrices. Hac habitasse platea dictumst vestibulum rhoncus est. Malesuada fames ac turpis egestas. Tristique senectus et netus et malesuada fames ac turpis egestas. Integer vitae justo eget magna fermentum iaculis eu non. Nisl nunc mi ipsum faucibus vitae aliquet. Etiam tempor orci eu lobortis elementum. Vel quam elementum pulvinar etiam. Vestibulum lorem sed risus ultricies tristique nulla aliquet enim tortor. Egestas congue quisque egestas diam in. Vehicula ipsum a arcu cursus vitae congue mauris rhoncus. Lacus vestibulum sed arcu non odio euismod lacinia at.",
          },
          {
            id: 5,
            name: "Nunc mi ipsum faucibus vitae",
            description:
              "Nunc mi ipsum faucibus vitae. Sed elementum tempus egestas sed sed risus pretium quam. Feugiat in ante metus dictum. Neque viverra justo nec ultrices dui sapien. Habitant morbi tristique senectus et netus. Scelerisque varius morbi enim nunc faucibus a pellentesque sit amet. Cursus in hac habitasse platea dictumst quisque sagittis purus sit. Ipsum faucibus vitae aliquet nec ullamcorper. Odio tempor orci dapibus ultrices in iaculis. Nulla porttitor massa id neque aliquam vestibulum. Cras adipiscing enim eu turpis egestas. Facilisis mauris sit amet massa vitae tortor. Donec ac odio tempor orci dapibus ultrices in iaculis. Quam nulla porttitor massa id neque aliquam vestibulum. Maecenas volutpat blandit aliquam etiam erat velit scelerisque in.",
          },
          {
            id: 6,
            name: "Consequat mauris nunc congue nisi vitae suscipit tellus",
            description:
              "Consequat mauris nunc congue nisi vitae suscipit tellus. Ridiculus mus mauris vitae ultricies leo. Habitasse platea dictumst vestibulum rhoncus est pellentesque elit. Facilisi etiam dignissim diam quis enim lobortis scelerisque. Nunc sed id semper risus in hendrerit gravida rutrum. Iaculis urna id volutpat lacus laoreet non curabitur gravida. Facilisis mauris sit amet massa vitae tortor. Congue eu consequat ac felis donec et. Quam elementum pulvinar etiam non quam lacus suspendisse. Vel facilisis volutpat est velit egestas dui id. Orci phasellus egestas tellus rutrum tellus pellentesque. Gravida quis blandit turpis cursus in hac. Enim sed faucibus turpis in eu mi bibendum neque. Dui sapien eget mi proin. Ante in nibh mauris cursus mattis molestie a. Mattis enim ut tellus elementum sagittis vitae. Ultrices in iaculis nunc sed. Scelerisque mauris pellentesque pulvinar pellentesque habitant morbi. Cras semper auctor neque vitae tempus quam pellentesque nec nam.",
          },
          {
            id: 7,
            name: "Malesuada fames ac turpis egestas sed tempus",
            description:
              "Malesuada fames ac turpis egestas sed tempus. Pretium aenean pharetra magna ac placerat vestibulum lectus mauris. Justo donec enim diam vulputate ut pharetra sit. Risus nec feugiat in fermentum posuere urna nec tincidunt praesent. Lectus proin nibh nisl condimentum id. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Pellentesque habitant morbi tristique senectus. Est ultricies integer quis auctor elit. Aliquam nulla facilisi cras fermentum odio eu feugiat. Tempus imperdiet nulla malesuada pellentesque elit eget gravida cum sociis.",
          },
          {
            id: 8,
            name: "Dui faucibus in ornare quam viverra orci sagittis eu volutpat",
            description:
              "Dui faucibus in ornare quam viverra orci sagittis eu volutpat. Placerat orci nulla pellentesque dignissim. Varius quam quisque id diam vel quam elementum pulvinar etiam. Ante metus dictum at tempor commodo ullamcorper. Elementum curabitur vitae nunc sed velit dignissim sodales ut. Interdum velit laoreet id donec ultrices tincidunt arcu. Aliquet enim tortor at auctor urna nunc. Amet porttitor eget dolor morbi. Placerat duis ultricies lacus sed turpis tincidunt. Non enim praesent elementum facilisis leo vel fringilla est ullamcorper. Aenean et tortor at risus viverra adipiscing. Massa sapien faucibus et molestie. Non consectetur a erat nam at. Cum sociis natoque penatibus et magnis dis parturient montes nascetur. Aenean sed adipiscing diam donec adipiscing tristique risus nec. Duis tristique sollicitudin nibh sit amet commodo nulla. Et odio pellentesque diam volutpat commodo sed egestas egestas fringilla. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl rhoncus.",
          },
          {
            id: 9,
            name: "Platea dictumst vestibulum rhoncus est pellentesque elit",
            description:
              "Platea dictumst vestibulum rhoncus est pellentesque elit. Iaculis urna id volutpat lacus laoreet non curabitur gravida. Enim neque volutpat ac tincidunt vitae semper quis lectus. At quis risus sed vulputate odio ut. Nibh cras pulvinar mattis nunc sed blandit libero volutpat. Maecenas volutpat blandit aliquam etiam erat. Risus in hendrerit gravida rutrum quisque non tellus orci. Lorem mollis aliquam ut porttitor leo a diam sollicitudin tempor. Non consectetur a erat nam at lectus urna duis convallis. Quam lacus suspendisse faucibus interdum posuere lorem ipsum. Volutpat maecenas volutpat blandit aliquam. Ornare massa eget egestas purus viverra accumsan in. Tincidunt nunc pulvinar sapien et. Morbi tristique senectus et netus. Arcu bibendum at varius vel pharetra. Turpis massa tincidunt dui ut ornare lectus.",
          },
          {
            id: 10,
            name: "Nibh nisl condimentum id venenatis a condimentum vitae sapien",
            description:
              "Nibh nisl condimentum id venenatis a condimentum vitae sapien. Sagittis aliquam malesuada bibendum arcu vitae. Condimentum mattis pellentesque id nibh. Viverra maecenas accumsan lacus vel facilisis volutpat. Est ullamcorper eget nulla facilisi. Faucibus turpis in eu mi bibendum neque egestas. Dui sapien eget mi proin sed libero enim sed faucibus. Id neque aliquam vestibulum morbi blandit cursus. Vel risus commodo viverra maecenas accumsan lacus vel facilisis volutpat. Pretium lectus quam id leo in vitae turpis. Feugiat pretium nibh ipsum consequat nisl vel. Faucibus turpis in eu mi.",
          },
          {
            id: 11,
            name: "Congue eu consequat ac felis donec",
            description:
              "Congue eu consequat ac felis donec. Pellentesque habitant morbi tristique senectus et netus et malesuada. Mauris nunc congue nisi vitae. Habitant morbi tristique senectus et netus. Malesuada pellentesque elit eget gravida cum sociis natoque penatibus et. Et tortor at risus viverra adipiscing at in tellus. Sagittis vitae et leo duis ut diam. Nec tincidunt praesent semper feugiat. Eu sem integer vitae justo eget magna fermentum iaculis eu. Vestibulum rhoncus est pellentesque elit ullamcorper dignissim. Lacus vel facilisis volutpat est velit egestas. Viverra aliquet eget sit amet tellus. Id diam vel quam elementum pulvinar etiam non quam. Arcu dui vivamus arcu felis bibendum ut tristique et. Faucibus a pellentesque sit amet porttitor eget dolor morbi non. Convallis a cras semper auctor neque vitae.",
          },
          {
            id: 12,
            name: "Lacus sed turpis tincidunt id aliquet risus feugiat in ante",
            description:
              "Lacus sed turpis tincidunt id aliquet risus feugiat in ante. Feugiat in ante metus dictum at. In nibh mauris cursus mattis molestie a iaculis. Aliquam etiam erat velit scelerisque. Pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus. Mi bibendum neque egestas congue quisque. Id semper risus in hendrerit gravida. Velit egestas dui id ornare arcu. Integer eget aliquet nibh praesent. Sit amet commodo nulla facilisi nullam vehicula ipsum a arcu. Nisl vel pretium lectus quam id. Volutpat odio facilisis mauris sit amet massa vitae. Faucibus pulvinar elementum integer enim neque volutpat. Ultricies integer quis auctor elit sed vulputate mi sit amet. Lacinia quis vel eros donec ac odio tempor. Posuere ac ut consequat semper viverra nam libero. Egestas sed sed risus pretium quam vulputate dignissim suspendisse in. Scelerisque eleifend donec pretium vulputate sapien nec sagittis. Neque gravida in fermentum et sollicitudin ac orci. Odio tempor orci dapibus ultrices in iaculis.",
          },
          {
            id: 13,
            name: "Netus et malesuada fames ac turpis egestas",
            description:
              "Netus et malesuada fames ac turpis egestas. Quisque egestas diam in arcu cursus euismod quis viverra nibh. Pharetra massa massa ultricies mi quis hendrerit dolor magna. Ultricies integer quis auctor elit sed vulputate mi. At in tellus integer feugiat. Amet risus nullam eget felis eget nunc lobortis mattis aliquam. Amet nulla facilisi morbi tempus iaculis urna id. Fermentum leo vel orci porta non pulvinar neque laoreet suspendisse. Aliquet lectus proin nibh nisl condimentum id. Volutpat odio facilisis mauris sit amet massa vitae. Tempus quam pellentesque nec nam aliquam. Lectus vestibulum mattis ullamcorper velit sed ullamcorper morbi tincidunt ornare. Mauris pharetra et ultrices neque ornare aenean euismod elementum nisi. Ipsum consequat nisl vel pretium lectus quam id leo in. Pulvinar pellentesque habitant morbi tristique senectus et netus et. Nec feugiat in fermentum posuere. Eu feugiat pretium nibh ipsum. Congue eu consequat ac felis donec et. Lobortis feugiat vivamus at augue eget arcu dictum. Sit amet venenatis urna cursus eget nunc scelerisque.",
          },
        ];
      }
    }
    export const store = new Store();
    

    App.vue

    <script setup>
    import { ref, computed } from 'vue'
    import { store } from './store.js'
    
    const filterText = ref(''); // This is the text that the user types into the filter box
    const whatToFilter = ref('justName'); // This is the radio button that the user selects to filter just the name or the name and description
    const selectedProduct = ref(null); // This is the selectedProduct that the user selects from the list
    const productSelected = (p) => {
        selectedProduct.value = p;
    };
    
    
    const filteredProducts = computed(() => {
        if (!filterText.value) {
            return store.products;
        } else {
            // if include description
            if (whatToFilter.value === 'nameAndDescription') {
                return store.products.filter((text) => {
                    return text.description.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1 || text.name.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1;
                });
            } else {
                return store.products.filter((text) => {
                    return text.name.toLowerCase().indexOf(filterText.value.toLowerCase()) > -1;
                });
            }
        }
    });
    
    </script>
    
    <template>
        <div>
            <label for="filterText">Filter Products:</label>
            <br />
            <input type="text" name="filterText" id="filterText" v-model="filterText" />
        </div>
        <div>
            <fieldset>
                <legend>Select What to filter:</legend>
                <input type="radio" id="justName" name="whatToFilter" value="justName" v-model="whatToFilter">
                <label for="justName">Just Name</label><br>
                <input type="radio" id="nameAndDescription" name="whatToFilter" value="nameAndDescription"
                    v-model="whatToFilter">
                <label for="nameAndDescription">Name and Description</label><br>
            </fieldset>
        </div>
        <div>
            <label for="products">Products:</label>
            <br />
            <ul>
                <li v-for="product in filteredProducts" :key="product.id" @click="productSelected(product)"
                    :class="{selected: product.id === selectedProduct?.id}"
                >
                    {{ product.name }}
                </li>
            </ul>
        </div>
        <div>
            <label for="description">Description:</label>
            <br />
            <textarea name="description" id="description" cols="40" rows="20" :value="selectedProduct?.description"></textarea>
        </div>
    </template>
    
    <style scoped>
    .selected {
        background-color: #dce68b;
    }
    </style>  
    

    A runnable example can be found on the Vue SFC Playground

    Login or Signup to reply.
  2. The simplest thing of course you can do is to filter by the model value (whatever value in your input). That is to say that your computed will react to each change of your input value and return computed result.

    const input = ref("")
    const array = [{ name: "First"}, { name: "Second"}]
    const filteredArray = computed(() => array.filter(item => item.name.includes(input.value))
    

    The way it works is that computed basically re-calculates whenever its reactive dependency (input) is changed

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search