Using an AngularJS filter once the "Apply" button has been triggered

I am facing an issue with a large dataset containing over 4000 items. Whenever I start typing, my browser freezes for up to 15 seconds. To resolve this problem, I want to disable the auto-filter feature and only apply the filter function when a button is clicked. Despite searching on Google, I couldn't find a solution. Can someone help me please? :)

Code:

<input ng-model="search.phone" type="text" placeholder="Phone...">
<input ng-model="search.name" type="text" placeholder="Name...">
<input ng-model="search.city" type="text" placeholder="City...">

<div ng-repeat="user in users | filter:search" class="user_block" ng-include src="userTemplate"></div>

and controller:

app.controller("smsCtrl", ['$scope', 'smsData', 'createDialog', '$http', '$filter', function($scope, smsData, createDialog, $http, $filter){...}

Answer №1

When assisting a coworker, I encountered a similar situation where manually triggering the search filter was necessary. To simplify the process, I developed an alternative solution.

Start by utilizing your original repeating div.

<div ng-repeat="user in users | filter:search">
    ...
</div>

Next, set up an object to store user input.

$scope.search = {};
$scope.userInput = {};

Link your input fields to this user input object.

<input type="text" ng-model="userInput.name" />
<input type="text" ng-model="userInput.phone" />
<input type="text" ng-model="userInput.city" />

Create a function that iterates through the properties of the user input object and copies them to the search object.

$scope.applySearch = function() {
    for(prop in $scope.userInput) {
        $scope.search[prop] = $scope.userInput[prop];
    }
};

Finally, add a button to execute the search function.

<button ng-click="applySearch()">Search</search>

Hopefully, this solution proves beneficial to others facing a similar challenge.

Answer №2

Why not give adding a debounce a try instead of relying on a button?

Check out this link for a helpful debounce code created by Lars Gersmann. You can see how it works in his JSFiddle example linked at the end of the article.

This excerpt is from pull request #2129 of AngularJS project on GitHub:

Moreover, using an ng-update-model-debounce attribute allows delaying the actual model update after the last triggered event. Note that this feature does not apply to radio buttons.

For instance, setting ng-update-model-debounce="500" will introduce a delay of 500ms.

Here's a practical way to implement debounce:

/**
 * The uiDebounce service offers a solution for creating a wrapper function
 * that ensures the wrapped function is not called more frequently than a specified time interval.
 *
 * @param {!Function} func The function being wrapped (debounced)
 * @param {number} wait Time interval between calls to func
 * @param {Boolean} immediate If true, the function is invoked on the first call to the
 * wrapper function; otherwise, the call occurs only after the wait time has elapsed
 * @return {Function} A debounced wrapper around the func function.
 */
angular.module('ui.services').factory('uiDebounce', function($timeout, $q) {
  return function(func, wait, immediate) {
    var timeout;
    var deferred = $q.defer();
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) {
          deferred.resolve(func.apply(context, args));
          deferred = $q.defer();
        }
      };
      var callNow = immediate && !timeout;
      if (timeout) {
        $timeout.cancel(timeout);
      }
      timeout = $timeout(later, wait);
      if (callNow) {
        deferred.resolve(func.apply(context, args));
        deferred = $q.defer();
      }
      return deferred.promise;
    };
  };
});

Source: Github - Angular-UI

Answer №3

I finally figured it out!

Replace:

<div ng-repeat="user in users | filter:search" class="user_block" ng-include src="userTemplate"></div>

With:

<div ng-repeat="user in users" ng-hide="user.excludedByFilter" class="sms_user_block" ng-include src="userTemplate"></div>

Don't forget to add the "applySearchFilter" function to the controller

    $scope.applySearchFilter = function() {
        var nameFilter = $scope.filters.name.toLowerCase();
        var phoneFilter = $scope.filters.phone;
        var cityFilter = $scope.filters.city;
        var showAll = 0 === nameFilter.length && 0 === phoneFilter.length && 0 === cityFilter.length;
        angular.forEach($scope.users, function(user) {
            if (showAll) {
                user.excludedByFilter = false;
            } else {
                user.excludedByFilter = (user.name.toLowerCase().indexOf(nameFilter) === -1) 
                                        || (user.phone.indexOf(phoneFilter) === -1) 
                                        || (user.city.indexOf(cityFilter) === -1);
            }
        });
    }

Additionally, include this html code for the filter button:

<a class="btn btn-primary" href="#" ng-click="applySearchFilter()">Apply filters</a>

Success!

*Please note that I modified ng-model="search.*" to ng-model="filters.*" in inputs.

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

Add a JSON file containing an image path as a value into a CSS background property

I currently have a MongoDB database containing documents with 'img' values structured as follows: "img": "../folder/img.jpg" Would it be feasible to utilize this string in my CSS for modifying the background image? This is essential because I n ...

What is the best way to view all of the objects in an array?

My challenge involves an array consisting of ten objects, each with six properties to be displayed on a view. I want users to have the ability to update these properties by entering new data into inputs. How can I efficiently monitor the entire array to ...

Mobile devices do not support HTML5 Video playback

Here is the HTML5 Video code I am using: <div id="lightBox1" class="lightBox"> <video id="video" controls preload="metadata"> <source width="100%" height="470" src="/ImageworkzAsia/video/iworkzvid.mp4" type="video/mp4"> ...

As the input field is modified, HTML transforms accordingly

I'm working on a registration form that requires some basic details. I want to dynamically change a question based on the user's input without having to submit the form first. For example, when the page loads the question might be, "Is Attendee ...

Step by step guide to showcasing images dynamically in user interface

My current project involves displaying a screen with an HTML table and an image. The HTML table is fully dynamic. The Code Working Process When the user loads a page (with a URL), I render an HTML table in different parts as the page loads. I retrieve al ...

Troubleshooting the Create Order Issue: Integrating PayPal Checkout with Smart Payment Buttons using React and Redux

Every time I attempt to process a payment, I encounter a 422 error: Unprocessable entity. The issue arises when I try to dynamically capture the purchased item details received from the redux store. I tried following this example (duplicate): PayPal Check ...

Encountering a bug that states "TypeError: Cannot read properties of null (reading 'useState')" while trying to use useState in a react application

I'm working on incorporating useState into my Next.js app, but I encountered an error as soon as I added the line of code to initialize useState. The popup error message reads: TypeError: Cannot read properties of null (reading 'useState') ...

What is the main function of .promise() in Nodejs Lambda functions?

What exactly does .promise() do within AWS Lambda? I am looking to trigger a signal right after a file has been stored in S3. Can someone explain the function of .promise() in this context? (e.g. --s3.putObject({}).promise()--) I noticed that the timesta ...

Using PHP and AJAX, populate a table based on the selection made from a dropdown

Hello, thank you for taking the time to review my issue. Let me outline the objective. I have successfully implemented two drop-down menus that are populated dynamically from a database. The query retrieves names and phone numbers (with plans to fetch mor ...

Problem with AngularJS Select Box

My AngularJS dependable dropdowns are currently functioning well with static data from a script file. However, I am now looking to bind data to these dropdowns from a URL. The challenge is that I don't have a separate URL for the dropdowns; there is j ...

Retrieving user input in Angular and showcasing extracted keywords

I want to give users the flexibility to customize the format of an address according to their preference. To achieve this, there will be a text input where users can enter both keywords and regular text. The goal is to detect when a keyword is entere ...

Why doesn't the div click event trigger when the mouse hovers over an iframe?

My dilemma involves a div element with a click event. When the div is positioned over an iframe area (closer to the user than the iframe), the click event fails to trigger. However, if the div is located elsewhere and not above the iframe, the click event ...

Encountered a CastError in Mongoose when trying to cast the value "Object" to a string

I am struggling with a Mongoose CastError issue within my Node.js API. The problem arises at a specific route where data is being returned appended with some additional information. Despite finding various solutions for similar problems, my scenario seems ...

The latest update of NextJS, version 13.1.4, encounters issues when implementing SCSS support with the error message "Module next/dist/compiled/sass-loader/fibers.js not

After setting up a new NextJS project, I decided to incorporate SCSS support. The guidelines provided in the documentation seemed straightforward. Following the installation instructions and including an import of SCSS as shown below: import "@/styles ...

How can I trigger a CSS animation to replay each time a button is clicked, without relying on a timeout function?

I am having trouble getting a button to trigger an animation. Currently, the animation only plays once when the page is refreshed and doesn't repeat on subsequent clicks of the button. function initiateAnimation(el){ document.getElementById("anima ...

Is the ID selector the quickest method in jQuery and CSS?

Which is the optimal choice in jQuery/javascript for speed? $('#myID .myClass') or $('.myClass') What is the preferred option to utilize in CSS? #myID .myClass{} or .myClass{} In hindsight, I realize my explanation was insuffici ...

Can an $mdToast be positioned at the top of the page on a small viewport?

I want to add toast notifications on my site for messages like success or error notifications to be displayed at the top of the page. According to the Angular material documentation, you can position a toast at the top: position - {string=}: Where to p ...

What is the technique for transmitting a child element in VueJS?

Is there a way to include HTML code in a VueJS component and have it render properly within the component? <my-vue-component> <div> ect... </div> </my-vue-component> ...

Error: The variable "deleted1" is not declared and cannot be used on the HTML button element's onclick

Hello, I need assistance from someone. I encountered an error message after trying to delete a row even though I have declared the button already. Error: deleted1 is not defined at HTMLButtonElement.onclick Could it be due to the script type being modul ...

Using Node.JS and Socket.io to determine if a tab is currently active

Looking to add notifications to my chat feature similar to Gitter's notifications. Specifically, I want the html title to change when a new message is received. After searching online for solutions, I found that most examples involved checking if the ...