Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search-by filter in Angular.js,

I am new to this framework, hence practicing Angularjs and following the tutorials available on the website.

there is an example were we can search the data present in table, the example is as follows,

<!DOCTYPE html>
<html ng-app="SmartPhoneApp">
<head>
    <title>Smart phone Angular</title>      
    <script type="text/javascript" src="D:/Rahul Shivsharan/Installers/AngularJS/angular.js"></script>
    <script type="text/javascript">
        var smartPhoneApp = angular.module("SmartPhoneApp",[]);

        smartPhoneApp.controller("phoneCtrl",function($scope){
            $scope.phones = [
                {
                    "modelName" : "LUMIA 520",
                    "companyName" : "NOKIA"
                },
                {
                    "modelName" : "GALAXY S Series",
                    "companyName" : "SAMSUNG"
                },
                {
                    "modelName" : "CANVAS",
                    "companyName" : "MICROMAX"
                },
                {
                    "modelName" : "OPTIMUS",
                    "companyName" : "LG"                        
                }
            ];

        });
    </script>   
</head>
<body>  
    Search by Model Name : <input ng-model="comp.modelName" />  
    Search by Company : <input ng-model="comp.companyName" />   
    <div ng-controller="phoneCtrl">
        <table ng-repeat="phone in phones | filter: comp">
            <tr>
                <td>{{phone.modelName}}</td>
                <td>{{phone.companyName}}</td>
            </tr>
        </table>
    </div>
</body>
</html>

Here in the above code i am able to search the phone using two different inputs i.e. search by model Name and search by company Name , the above code runs fine,

But what if i need to search by using the type of search present in the select options,

the code is as follows

<!DOCTYPE html>
<html ng-app="EmployeeApp">
<head>
    <title>Orderring People</title>     
    <script type="text/javascript" src="D:/Rahul Shivsharan/Installers/AngularJS/angular.js"></script>
    <script type="text/javascript">
        var employeeApp = angular.module("EmployeeApp",[]);
        employeeApp.controller("empCtrl",function($scope){
            $scope.employees = [
                {
                    "name" : "Mahesh Pachangane",
                    "company" : "Syntel India Pvt. Ltd",
                    "designation" : "Associate"
                },
                {
                    "name" : "Brijesh Shah",
                    "company" : "Britanica Software Ltd.",
                    "designation" : "Software Engineer"
                },
                {
                    "name" : "Amit Mayekar",
                    "company" : "Apex Solutions",
                    "designation" : "Human Resource"
                },
                {
                    "name" : "Ninad Parte",
                    "company" : "Man-made Solutions",
                    "designation" : "Senior Architect"
                },
                {
                    "name" : "Sunil Shrivastava",
                    "company" : "IBM",
                    "designation" : "Project Lead"
                },
                {
                    "name" : "Pranav Shastri",
                    "company" : "TCS",
                    "designation" : "Senior Software Engineer"
                },
                {
                    "name" : "Madan Naidu",
                    "company" : "KPMG",
                    "designation" : "Senior Associate"
                },
                {
                    "name" : "Amit Gangurde",
                    "company" : "Amazon",
                    "designation" : "Programe Manager"
                }   
            ];
            $scope.orderProp="name";                
        });
    </script>   
</head>
<body ng-controller="empCtrl">      
    <table>
        <tr>
            <td align="right">Search :</td>
            <td><input ng-model="query" /></td>
        </tr>           
        <tr>
            <td align="right">Search By :</td>
            <td>
                <select ng-model="query">
                    <option value="name">NAME</option>
                    <option value="company">COMPANY</option>
                    <option value="designation">DESIGNATION</option>
                </select>   
            </td>
        </tr>
    </table>
    <hr>
    <div>
        <table>
            <tr>
                <th>Employee Name</th>
                <th>Company Name</th>
                <th>Designation</th>
            </tr>
            <tr ng-repeat="emp in employees | filter:query">
                <td>{{emp.name}}</td>
                <td>{{emp.company}}</td>
                <td>{{emp.designation}}</td>
            </tr>
        </table>
    </div>
</body>

From the above code you can see that i am trying to achieve is search employee by "Name", "Company" or "Designation" present in the selection box,

but i am going wrong here,

the ng-model query doesn't picks up the right mapping, or may be i am doing in a wrong way,

can you please tell me how will i achieve this,

which part of the code should i change

like image 676
Rahul Shivsharan Avatar asked Oct 25 '13 08:10

Rahul Shivsharan


Video Answer


3 Answers

I've created a plunkr. You can define properties on the search query to filter by. In the select you choose the property you want to filter by and assign it to the search query.

http://plnkr.co/edit/XklvXtc1AZpndjLvXrh8?p=preview

like image 73
bekite Avatar answered Oct 21 '22 19:10

bekite


Simple and flexible jsfiddle.

Can mention the filter fields also

filterFields: [
  "name",
  "company"
]
like image 36
Siva Kannan Avatar answered Oct 21 '22 18:10

Siva Kannan


An example you refer to uses object to specify filter keys, while your code always sends a string, and this is the main issue cause.

Let's assume I've typed "e" into search field. Without "Search by" selected, the filter would search for "e" in every key value. When we select value from "Search by", query string becomes current option's value ("name", "company" or "designation"), and will proceed in the same scenatio as "e", except without any result, because there aren't any matches in test data.

The proper way to choose "search by" would be contructing an object with a single key named as chosen option, equal to search query. So, if the user searches for name with "sh", it will be:

{
    name: "sh"
}

In case when no option chosen yet, the property should be named "$", this way filter will search among all properties.

I've fixed the code to work as intended (link). How you implement this is another question, but I went by defining queryFilter object on $scope, with getter which returns object of desired format.

.controller("empCtrl", function($scope) {
  Object.defineProperty($scope, "queryFilter", {
      get: function() {
          var out = {};
          out[$scope.queryBy || "$"] = $scope.query;
          return out;
      }
  })
...
<body ng-controller="empCtrl">      
    <table>
        <tr>
            <td align="right">Search :</td>
            <td><input ng-model="query" /></td>
        </tr>           
        <tr>
            <td align="right">Search By :</td>
            <td>
                <select ng-model="queryBy">
                    <option value="name">NAME</option>
                    <option value="company">COMPANY</option>
                    <option value="designation">DESIGNATION</option>
                </select>   
            </td>
        </tr>
    </table>
    <hr>
    <div>
        <table>
            <tr>
                <th>Employee Name</th>
                <th>Company Name</th>
                <th>Designation</th>
            </tr>
            <tr ng-repeat="emp in employees | filter:queryFilter">
                <td>{{emp.name}}</td>
                <td>{{emp.company}}</td>
                <td>{{emp.designation}}</td>
            </tr>
        </table>
    </div>
</body>
like image 35
Klaster_1 Avatar answered Oct 21 '22 19:10

Klaster_1