0

I am writing an app using AngularJS on the front end. I want to search through a table by any word/field; one search box for everything. I tried to follow this plunker's working example: http://plnkr.co/edit/aIuSDYlFbC4doW6pfsC9?p=preview

This is my code on the front end:

<div class = "row">
   <label>Search: <input ng-model="query"></label>
</div>

<div class = "row">
  <table ng-repeat="post in posts | orderBy: sort | filter: search">
    <tr>
       <td> {{index(post)}} </td>

       <td> {{post.title}} </td>

       <td> {{post.author}} </td>

       <td> {{post.content}} </td>

       <td> {{post.date | date: "d/M/yyyy"}} </td>
    </tr>
  </table>
</div>

And this is inside my main controller:

'use strict';
 $scope.posts = posts.posts;

 $scope.search = function (row) {
    return (angular.lowercase(row.author).indexOf($scope.query || '') !== -1 ||
    angular.lowercase(row.title).indexOf($scope.query || '') !== -1 ||
    angular.lowercase(row.content).indexOf($scope.query || '') !== -1 ||
    angular.lowercase(row.date).indexOf($scope.query || '') !== -1 ||
 };

What should I do? Thank you

OneMoreQuestion
  • 1,693
  • 3
  • 25
  • 51
  • `filter: query`. I'd also pipe the array through `filter` before `orderBy` – Phil Jul 13 '15 at 23:12
  • 1
    the example you posted appears to be using angular 1.0.3; I doubt that any new projects are using this release. Filters have changed drastically in angular, and this doesn't look like a function I would expect to work in modern angular releases. – Claies Jul 13 '15 at 23:33
  • also, you seem to have some syntax errors in that filter code, i.e. missing closing `)`, and a trailing `||` with no option after it. – Claies Jul 13 '15 at 23:35
  • @Phil: I know for a fact that the order on orderBy vs filter does not matter, and it will work the way it is now. – VSO Jul 14 '15 at 00:01
  • @VSO it might not make a functional difference but giving `orderBy` fewer items to sort will make it faster – Phil Jul 14 '15 at 00:12
  • @Phil: Makes sense, I didn't even consider that tbh. – VSO Jul 14 '15 at 00:31
  • possible duplicate of [searchKeyword not working in AngularJS filter](http://stackoverflow.com/questions/31393712/searchkeyword-not-working-in-angularjs-filter) – isherwood Jul 14 '15 at 13:23

3 Answers3

4

Make a filter variable in your scope like so:

$scope.myFilter = "defaultFilterValue";

Bind your filter to a search field like this:

    <input type="text" ng-model="myFilter"></input>

Put the filter in your html like so:

  <table ng-repeat="post in posts | orderBy: sort | filter: myFilter">
    <tr>
       <td> {{index(post)}} </td>

       <td> {{post.title}} </td>

       <td> {{post.author}} </td>

       <td> {{post.content}} </td>

       <td> {{post.date | date: "d/M/yyyy"}} </td>
    </tr>
  </table>

And then...oh wait, that's it. Let me know if you have any problems. Tutorial here on exactly your question.


Edit: This code is TESTED, so use it exactly as is and go from there. Html:

<div class = "row">
    <label>Search: <input type="text" ng-model="myFilter"></input></label>
</div>

<div class = "row">
    <table ng-repeat="post in posts | orderBy: sort | filter: myFilter">
        <tr>
            <td> {{index.post}} </td> //you had a weird formatting mistake here

            <td> {{post.title}} </td>

            <td> {{post.author}} </td>

            <td> {{post.content}} </td>

            <td> {{post.date | date: "d/M/yyyy"}} </td>
        </tr>
    </table>
</div>

JS:

$scope.myFilter = "";

$scope.posts = [
        {index: 1, author: "Mark Twain", title: "Tom Sawyer", description: "And den Jim said some racist stuff", date:"02/05/1870"},
        {index: 2, author: "Eirch Remarque", title: "Western Front", description: "Our lost generation, bawww", date: "03/17/1955"}
];

Note: I REALLY recommend the tutorial I linked earlier. If you don't read it, then at least use table headers.

VSO
  • 11,546
  • 25
  • 99
  • 187
  • 1
    You don't need a default filter value if the default is *no filter* – Phil Jul 14 '15 at 00:13
  • So I took out all that stuff I had before in the controller and just put in $scope.myFilter = ""; and binded the filter to a search field and put the filter in the html. But it is not working? @VSO – OneMoreQuestion Jul 14 '15 at 07:24
  • Am I missing something else? @Phil – OneMoreQuestion Jul 14 '15 at 07:25
  • @VSO Thank you for this. I have read the tutorial and looked through the codes multiple times. This solution doesn't work 100% for me. I don't know why. Sometimes the search works, it pulls results as expected. Sometimes it does not. For example, when my post.title is B, the search can find it. When it is A or C or D, it doesn't find them. Could it be the post.date interfering with it somehow? Btw I am using MongoDB to store the results – OneMoreQuestion Jul 14 '15 at 18:31
  • Are you familiar with
    {{yourPostData | json}}>
    tags convention to test your data from post? You can use it to see what data is returned. If some data is returned for every field, your ng-repeat should work. If your ng-repeat works, the filter should work. Basically, what I am saying is that I don't think the date is the issue as long as you are getting data. It's not like you are bringing BSON back to the client. P.S. I don't know what the problem is at the point, those are just suggestions. I can say with fair certainty that it has nothing to do with the date, as long as its there.
    – VSO Jul 14 '15 at 18:41
  • My ng-repeat returns the data just fine. What is really interesting is that when I do or , it works. So it is fine as long I am searching by a single field. However, I cannot do all fields at once. I have no idea why. @VSO – OneMoreQuestion Jul 14 '15 at 22:45
1
<div class = "row">
   <label>Search: <input ng-model="query"></label>
</div>

<div class = "row">
    <table ng-repeat="post in posts | orderBy: sort | filter: query">
        <tr>
            <td> {{index(post)}} </td>
            <td> {{post.title}} </td>
            <td> {{post.author}} </td>
            <td> {{post.content}} </td>
            <td> {{post.date | date: "d/M/yyyy"}} </td>
        </tr>
    </table>
</div>
Kurt Van den Branden
  • 11,995
  • 10
  • 76
  • 85
  • Please put an explanation saying what you changed and why it was wrong. That will help future visitors who may be having the same problem learn what to do. – Fencer04 Sep 19 '16 at 15:35
0

Try this one.

HTML:

<label>Search:
  <input ng-model="searchKeyword" ng-model-options="{debounce:1000}">
</label>

<table ng-repeat="post in posts | orderBy: sort | filter: search">
  <tr>
    <td> {{post.title}} </td>
    <td> {{post.author}} </td>
    <td> {{post.content}} </td>
    <td> {{post.date}} </td>
  </tr>
</table>

Controller:

$scope.posts = [{
  title: 'Title one ',
  author: 'Author one ',
  content: 'Content one ',
  date: new Date('10.10.2010')
}, {
  title: 'Title two ',
  author: 'Author two ',
  content: 'Content two ',
  date: new Date('11.11.2011')
}, {
  title: 'Title three ',
  author: 'Author three ',
  content: 'Content three ',
  date: new Date('12.12.2012')
}];

$scope.searchKeyword = '';
$scope.sort = 'title';

var authorMatch, titleMatch, contentMatch, dateMatch;

$scope.search = function(row) {
  authorMatch = row.author.toLowerCase().includes($scope.searchKeyword);
  titleMatch = row.title.toLowerCase().includes($scope.searchKeyword);
  contentMatch = row.content.toLowerCase().includes($scope.searchKeyword);
  dateMatch = row.date.toString().toLowerCase().includes($scope.searchKeyword);

  return authorMatch || titleMatch || contentMatch || dateMatch;
};

The debounce option is explained here. Includes function is new in JavaScript and is explained here.

Community
  • 1
  • 1
  • Thank you. Do I have to have Angular Strap for this approach? Because I am getting the "TypeError: Cannot read property 'toLowerCase' of undefined" error. @Sofre Garevski – OneMoreQuestion Jul 15 '15 at 00:50
  • Also this error: "TypeError: Cannot read property 'includes' of undefined" @Sofre Garevski – OneMoreQuestion Jul 15 '15 at 01:00
  • "TypeError: Cannot read property 'toLowerCase' of undefined" - means that author or title or content or date is not defined. From here comes the second error "TypeError: Cannot read property 'includes' of undefined". Make sure your data is consistent, or improve the method so it will check first if data exists. – Sofre Garevski Jul 15 '15 at 06:07
  • I don't understand why they could be undefined. Because I double checked all the data names. @Sofre Garevski – OneMoreQuestion Jul 15 '15 at 06:19
  • But I definitely see why this would work @Sofre Garevski – OneMoreQuestion Jul 15 '15 at 06:19