Paulund

VueJS CRUD - Product Search

With a product list on the page it will be a good idea to be able to search through the products by product name so that you can find the right product to edit or delete. In the tutorial we're going to use the all-products.vue component created in a previous tutorial, then we need to add a search textbox and a new method to run on each key press inside the search box.

Search Textbox HTML

The HTML for this is simply going to be a textbox, we need to gather the input of the user so we link this to a data point by using v-model, then using v-on:keyup we can assign a method to run on each keypress.


<div class="form-group">
    <input type="text" name="search" v-model="productSearch" placeholder="Search products" class="form-control" v-on:keyup="searchProducts">
</div>

Data Points

During the search of the products we're going to search for all the products and change the this.products to only hold products that fit the search criteria, therefore we need to keep track of what the original products were in the first place.


data(){
    return{
        products: [],
        originalProducts: [],
        productSearch: ''
    }
}

On the fetch product data we need to also add the response from the API into the this.originalProducts data point.


fetchProductData: function()
{
    this.$http.get('http://localhost:3000/api/products').then((response) => {
        this.products = response.body;
        this.originalProducts = this.products;
    }, (response) => {

    });
}

Now we can change the products array without worrying about losing any of the original data. ## Search Products Method

First we need to get the value of what the user has typed something into the search box, if it's empty then we know we can reset the products list to be the original products. Then we can loop through all the original products and find any products that can match the product names the user has searched for. Once they match the search term then add the product object to a new array. At the end of the method we then use the matched products and replace the product list. Because Vue is reactive it will automatically change the elements in the HTML product table with the new data in the this.products object.


searchProducts: function()
{
    if(this.productSearch == '')
    {
        this.products = this.originalProducts;
        return;
    }

    var searchedProducts = [];
    for(var i = 0; i < this.originalProducts.length; i++)
    {
        var productName = this.originalProducts[i]['name'].toLowerCase();
        if(productName.indexOf(this.productSearch.toLowerCase()) >= 0)
        {
            searchedProducts.push(this.originalProducts[i]);
        }
    }

    this.products = searchedProducts;
}

Full Component Code


<template>
    <div id="all-products">
        <h1>All Products</h1>

        <p><router-link :to="{ name: 'create_product' }" class="btn btn-primary">Create Product</router-link></p>

        <div class="form-group">
            <input type="text" name="search" v-model="productSearch" placeholder="Search products" class="form-control" v-on:keyup="searchProducts">
        </div>

        <table class="table table-hover">
            <thead>
            <tr>
                <td>ID</td>
                <td>Name</td>
                <td>Price</td>
                <td>Actions</td>
            </tr>
            </thead>

            <tbody>
                <tr v-for="product in products">
                    <td>{{ product.id }}</td>
                    <td>{{ product.name }}</td>
                    <td>{{ product.price }}</td>
                    <td>
                        <router-link :to="{name: 'edit_product', params: { id: product.id }}" class="btn btn-primary">Edit</router-link>
                        <router-link :to="{name: 'delete_product', params: { id: product.id }}" class="btn btn-danger">Delete</router-link>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</template>

<script>

    export default{
        data(){
            return{
                products: [],
                originalProducts: [],
                productSearch: ''
            }
        },

        created: function()
        {
            this.fetchProductData();
        },

        methods: {
            fetchProductData: function()
            {
                this.$http.get('http://localhost:3000/api/products').then((response) => {
                    this.products = response.body;
                    this.originalProducts = this.products;
                }, (response) => {

                });
            },

            searchProducts: function()
            {
                if(this.productSearch == '')
                {
                    this.products = this.originalProducts;
                    return;
                }

                var searchedProducts = [];
                for(var i = 0; i < this.originalProducts.length; i++)
                {
                    var productName = this.originalProducts[i]['name'].toLowerCase();
                    if(productName.indexOf(this.productSearch.toLowerCase()) >= 0)
                    {
                        searchedProducts.push(this.originalProducts[i]);
                    }
                }

                this.products = searchedProducts;
            }
        }
    }
</script>

To access the repository for this example you can view it on Github. VueJS CRUD Example