Utilizing a search bar with the option to narrow down results by category

I want to develop a search page where users can enter a keyword and get a list of results, along with the option to filter by category if necessary. I have managed to make both the input field and radio buttons work separately, but not together. So, when someone performs a keyword search, those results are shown. When someone filters by category, only those results are displayed. However, I am unsure how to utilize my search box once a category is selected. I would like the search box to search within the results belonging to that specific category.

HTML

<div id="app" v-cloak>
 <div class="container">
  <div class="row search-wrapper"> 
    <div class="col-xs-6 col-md-4">
      <div class="input-group stylish-input-group">
                    <input type="text" class="form-control"  placeholder="Filter by keyword"  v-model="search">
                    <span class="input-group-addon">
                        <button type="submit">
                            <span class="glyphicon glyphicon-search"></span>
                        </button>  
                    </span>
                </div>
    </div>    
    <div class="col-xs-12 col-md-8 text-right">
      <div data-toggle="buttons">
      <label class="btn btn-sm btn-all">
        <input type="radio" v-model="selectedCategory" value="All" /> All
      </label>
      <label class="btn btn-sm btn-hr">
        <input type="radio" v-model="selectedCategory" value="HR" /> Our People
      </label>
      <label class="btn btn-sm btn-finance">
        <input type="radio" v-model="selectedCategory" value="Finance" /> Finance
      </label>
     <label class="btn btn-sm btn-other">
        <input type="radio" v-model="selectedCategory" value="Other" /> Other
      </label>
</div>
    </div>    
  </div> <!-- search wrapper -->
  <div class="row sm-padding">
    <div v-for="form in filteredForms" class="col-xs-6 col-sm-4 sm-padding">
      <div class="box">
        <div class="form-type" v-bind:class="{ compClass }"></div>
        <div  class="text-right"><span class="glyphicon glyphicon-star"></span></div> 
        <div class="box__title"> {{ form.name }} </div>
        <div class="box__subtitle"> {{ form.category }} </div>
        <div class="box__link"> <a href="#" title="">Use this form</a></div>
      </div>
    </div>
    <div v-if="filteredForms.length === 0" >
      <div class="box box__empty"> No Match Found</div>
    </div>
  </div> <!-- results --> 
 </div> <!-- container -->
</div> <!-- #app -->

Vue JS

var vm = new Vue({
  el: '#app',
  data: {
      forms: [
        { name: 'Learning and Professional Development Record', category: 'HR', activeColor: 'red', views: 312},
        { name: 'New Vendor Request', category: 'Finance', activeColor: 'blue', views: 23121 },
        { name: 'On-call allowance', category: 'HR', activeColor: 'red', views: 231},
        { name: 'Overtime Claim', category: 'HR', activeColor: 'red', views: 443},
        { name: 'Alteration of Kindergarten Enrolment', category: 'Other', activeColor: 'yellow', views: 403},
        { name: 'Adjustment to vendor details', category: 'Finance', activeColor: 'blue', views: 8843}
      ],
      selectedCategory: 'All',
      search: '',
  },
  computed: {
    filteredForms: function() {
        var vm = this;
        var category = vm.selectedCategory;

       var forms = vm.forms.filter((form) => {
       return form.name.toLowerCase().includes(vm.search.toLowerCase());
          });

      if(category === "All") {
            return forms;
        } else {
          return vm.forms.filter(function(dept) {
          return dept.category === category;
            });
    }
    }
  }
})

Pen: Codepen

Answer №1

Your filtering system within a specific category is operating on the entire list rather than the list filtered by keyword:

filteredItems: function() {
    var vm = this;
    var category = vm.selectedCategory;

    var items = vm.items.filter((item) => {
        return item.name.toLowerCase().includes(vm.search.toLowerCase());
    });

    if(category === "All") {
        return items;
    } else {
        return items.filter(function(item) {
            return item.category === category;
        });
    }
}

For further reference, here is an updated Pen link: https://codepen.io/anon/pen/rpQzpz

Answer №2

I have made an update to the computed value for you. Your forms array now undergoes filtering with just one array iteration.

const vm = new Vue({
  el: '#app',
  data: {
      forms: [
        { name: 'Learning and Professional Development Record', category: 'HR', activeColor: 'red', views: 312},
        { name: 'New Vendor Request', category: 'Finance', activeColor: 'blue', views: 23121 },
        { name: 'On-call allowance', category: 'HR', activeColor: 'red', views: 231},
        { name: 'Overtime Claim', category: 'HR', activeColor: 'red', views: 443},
        { name: 'Alteration of Kindergarten Enrolment', category: 'Other', activeColor: 'yellow', views: 403},
        { name: 'Adjustment to vendor details', category: 'Finance', activeColor: 'blue', views: 8843}
      ],
      selectedCategory: 'All',
      search: '',
  },
  computed: {
    filteredForms() {
      return this.forms.filter(dept => (dept.category === this.selectedCategory || this.selectedCategory === 'All') && dept.name.toLowerCase().includes(this.search.toLowerCase()));
    }
  }
});

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

I am currently studying JavaScript. The syntax of my if statement with && appears to be accurate, however

I'm having trouble with the logic in my "Code your Own Adventure" program on Code Academy. I expect it to display "Great, come get your pizza!" when I enter PIZZA, YES, and YES as prompts, but instead it says "NO pizza for you!" I've tried using ...

Error occurred during download or resource does not meet image format requirements

Encountering an issue when attempting to utilize the icon specified in the Manifest: http://localhost:3000/logo192.png (Download error or invalid image resource) from the console? import React from 'react'; import Logo from '../Images/logo1 ...

Vuex has reserved this keyword

I am working on a Laravel application with the following code in app.js: require('./bootstrap'); window.Vue = require('vue'); import { store } from './store/store' import Sidebar from './Sidebar' Vue.component(& ...

Accessing QML Functions from JavaScript

Currently, I am faced with a challenge in my app development using Qt. I need to trigger a QML function from JavaScript when a specific event is triggered from my HTML page. I attempted the following method: app.html <html> <head><title& ...

Unable to initiate beforeDraw using Vue-Chartjs (or any similar plugins)

I'm currently attempting to customize the text displayed on my Chartjs chart using vue-chartjs. My research suggests that I should utilize a beforeDraw plugin to achieve this. I have added the plugin to the options.plugins section, but it does not see ...

Is there a way to identify whether the image file is present in my specific situation?

I have a collection of images laid out as shown below image1.png image2.png image3.png image4.png … … image20.png secondImg1.png secondImg2.png secondImg3.png secondImg4.png secondImg5.png ……. …….. secondImg18.png My goal is to dynamically ...

Unexpected Error: Null value prevents accessing 'getElementsByClassName' property in HTML, along with Troubleshooting Inactive Button Behavior in HTML

Can someone identify the error in my HTML code? I keep getting an "Uncaught TypeError: Cannot read property 'getElementsByClassName' of null" error on the second line of the script tag. Additionally, my implemented active header code is not funct ...

How to activate a window that's been minimized in Chrome

I am experiencing an issue with a button that is supposed to open a new window as a popup below the parent page. It works correctly in IE and Firefox, but in Chrome, the popup appears on top of the parent window. Can someone please provide a solution? Fo ...

Errors encountered by the Chrome extension

Hey there, I've recently delved into creating a chrome extension but hit a roadblock. My issue revolves around the service worker registration failing and encountering errors related to undefined properties. https://i.stack.imgur.com/bGzB4.png The c ...

"Unlocking the hidden powers within a directive: A guide to accessing inner

I have two directives called container and item. directive('container', function(){ return { replace: true, template: "<div>contains <p>...</p> </div>' } }); directive('item', fun ...

Using Vue-Slick to create dynamic data with v-for

I can't seem to get my images to display using vue-slick. I've tried multiple solutions without any success. Below is my template: <slick ref="slick" :options="slickOptions"> <img v-for="(item) in categories" :src="'/images/cate ...

Error Handling with Firebase Cloud Firestore and State Management in Vue using Vuex (firebase.firestore.QuerySnapshot)

Upon examining the code, I noticed an issue with docChanges. It seems to be a function, but when I try to use docChanges().doc.data().userId, I encounter the error message: store.js?3bf3:21 Uncaught TypeError: Cannot read property 'doc' of undefi ...

Setting up a new package through JPSM installation

I utilize jspm in my web application. My goal is to install the npm:angular2 package without needing to set it up in the config.js file. Instead of loading the angular2 module via jspm, I manually added the angular2 library like this: <script src="jspm ...

The message vanishes upon refreshing the page

I've developed a socket.io web app. When I click on the button to send a message, the message appears briefly but disappears when the page refreshes unexpectedly. How can I prevent this random refreshing and ensure that socket.io saves my messages? B ...

Retrieve events triggered by each element

Currently, my research centers around digital marketing and user experience. In order to gather the necessary data for this study, I must collect event logs from all components within a UI to create datasets on usability patterns. In a web interface, such ...

Obtain JSX content from a React Component that has been imported

As part of our library documentation efforts, I am looking to convert a React Component function into JSX format. To illustrate, let's consider a rendered Button component and showcase the code used to create it. One approach could be to simply read ...

What is the optimal strategy for managing multilingual text in a React website?

As I develop a react website with multiple localizations, I am faced with the question of how to best store UI texts for different languages. Currently, I am contemplating two approaches: One option is to store text directly in the UI code, using an objec ...

The reactivity of Vuex and Vue does not work as expected when a dictionary is used as a

What is the best approach to make a dictionary reactive as one of my store variables? Unlike an array, dictionaries are not reactive by default. Here's a minimal example I've created: Check out this example on CodeSandbox ...

I am currently using React to implement a feature that displays random facts for 5-second intervals. Despite no errors being displayed, the facts are not appearing on the page as expected

Client side My react application includes a section that is supposed to display random facts at 5-second intervals. Although no errors are displayed, the facts do not appear on the page when I run the code. import React from "react"; import &quo ...

Creating a customized plugin in JavaScript that utilizes a local JSON/GeoJSON file

I am relatively new to Drupal and currently working on developing a custom map module. While my module functions correctly and displays the map along with relevant information, I encountered a challenge regarding calling my geojson file using a hard-coded ...