AngularJS search with multiple textboxes - angularjs

I want to do a search of a table with multiple textboxes. The user should be able to enter address in the address box and search the table my address, and enter city in the city search box and search the table by city. I can't get it to work, I'm getting the error message: Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Here's my html:
<table>
<thead>
<tr>
<th>
Address
</th>
<th>
City
</th>
</tr>
<tr>
<td>
<input ng-model="vm.search_address" />
</td>
<td>
<input ng-model="vm.search_city" />
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="search in searchesFound = ( vm.searches | filter: {address: search_address, city: search_city})">
<td>
{{ search.address }}
</td>
<td>
{{ search.city }}
</td>
</tr>
</tbody>
</table>
ANd here's my controller:
(function () {
angular.module('crm.ma')
.controller('AdvancedSearchCtrl', function () {
var vm = this;
vm.search_address = "";
vm.search_city = "";
vm.searchs = [
{
address: '202 This St',
city : 'Columbus'
},
{
address: '205 That St',
city: 'Dayton'
}
]
});
})();
Any clues on what I'm doing wrong?

You forgot the vm object. In your filter vm.search_city and vm.search_address should be used:
<tr ng-repeat="search in vm.searchs | filter: {address: vm.search_address, city: vm.search_city}">

Look this:
var app = angular.module('ngApp', []);
app.controller('MainCtrl', ['$scope', function ($scope) {
$scope.smartphones = [
{brand: 'Apple', model: 'iPhone 4S', price: '999'},
{brand: 'Samsung', model: 'SIII', price: '888' },
{brand: 'LG', model: 'Optimus', price: '777'},
{brand: 'htc', model: 'Desire', price: '666'},
{brand: 'Nokia', model: 'N9', price: '555'}
];
$scope.search = function(){
angular.forEach($scope.smartphones, function(value, key) {
var brand = ($scope.queryBrand? $scope.queryBrand.toLowerCase():' ');
var model = ($scope.queryModel? $scope.queryModel.toLowerCase():' ');
value.show = (value.brand.toLowerCase().indexOf(brand) > -1 ||
value.model.toLowerCase().indexOf(model) > -1 || (brand == ' ' && model == ' '));
console.log(!brand && !model)
});
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.0/css/bootstrap-combined.min.css" rel="stylesheet">
<div ng-app="ngApp" ng-controller="MainCtrl" class="container">
<input class="span4 pull-right" type="text" placeholder="Filter by brand" ng-model="queryBrand" ng-change="search()">
<input class="span4 pull-right" type="text" placeholder="Filter by model" ng-model="queryModel" ng-change="search()">
<div class="row">
<table id="results" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Brand</th>
<th>Model</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="smartphone in smartphones" ng-init="smartphone.show=true" ng-show="smartphone.show">
<td id="brand">{{smartphone.brand}}</td>
<td id="model">{{smartphone.model}}</td>
<td id="price">{{smartphone.price | currency}}</td>
</tr>
</tbody>
</table>
</div>
</div>

Related

How the value is passed inside the indexOf()?

In this code, the 'm' is written inside the indexOf function. But no where in the code the value is passed. I am not able to understand how this 'm' deleting the right item in ng-repeat. When i change 'm' to something else it is now working. I am new to AngularJS.
In the main.js file there is removeitem function, i am getting from where the value of 'm' is coming , it has,nt passed from anywhere. I tried removeing 'm' but it doesnt work, it deletes the last item.
var app = angular.module('myApp', []);
app.controller('cont', function($scope) {
$scope.invoice = {
number: 10,
tax: 14,
items: [{
description: "",
quentity: 10,
cost: 300
}],
};
$scope.currency_symbol = [{
name: 'Indian Rupee',
currency: '₹'
},
{
name: 'USD',
currency: '$'
},
{
name: 'Euro',
currency: '€'
}
];
$scope.addItem = function() {
$scope.invoice.items.push([{
description: "description",
quentity: 1,
cost: 1
}]);
}
$scope.removeItem = function(m) {
$scope.invoice.items.splice($scope.invoice.items.indexOf(m), 1);
}
$scope.subTotal = function() {
var total = 0.0;
angular.forEach($scope.invoice.items, function(item, key) {
total += item.quentity * item.cost;
});
return total;
};
$scope.calcuteTax = function() {
return (($scope.subTotal() * $scope.invoice.tax) / 100);
};
$scope.grandTotal = function() {
return ($scope.subTotal() + $scope.calcuteTax());
};
});
<head>
<title>Simple Invoicing - Built with AngularJS </title>
<meta charset='utf-8'>
<meta name="description" content="AngularJS and Angular Code Example for creating Invoices and Invoicing Application">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="cont">
<div class="container" width="800px" id="invoice">
<div class="row">
<div class="col-xs-12 heading">
<strong>Billing System</strong>
</div>
</div>
</div>
<div class="main1">
<div="customer">
<select ng-init="currencySymbol=currency_symbol[0]" ng-model="currencySymbol" ng-options="currency.name+' '+currency.currency for currency in currency_symbol"></select>
</div>
</div>
<div class="main2">
<table border=1 width=100%>
<th></th>
<th>Description</th>
<th>Quantity</th>
<th>Cost{{' '+currencySymbol.currency}}</th>
<th>Total</th>
<tr ng-repeat="item in invoice.items">
<td text-align="center">
<a class="btn" href="" ng-click="removeItem()">
<strong>[x]</strong>
</a>
</td>
<td><input type="text" ng-model="item.description" placeholder="Description"></td>
<td><input type="number" ng-model="item.quentity" placeholder="10"></td>
<td><input type="number" ng-model="item.cost" placeholder="10"></td>
<td placeholder="0">{{item.quentity*item.cost}}</td>
</tr>
<tr>
<td text-align="center"><a class="btn" style="background-color:green;" href ng-click="addItem()">[+]</a></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Sub Total:</td>
<td>
<p>{{subTotal()}}</p>
</td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Tax:<input type="number" ng-model="invoice.tax"></td>
<td>
<p>{{calcuteTax()}}</p>
</td>
</tr>
<tr>
<td text-align="center"></td>
<td></td>
<td></td>
<td>Grand Total:</td>
<td>
<p>{{grandTotal()}}</p>
</td>
</tr>
</table>
</div>
</body>
How do i make the code delete the item on which i click ?
Add item as an argument to the removeItem function:
<tr ng-repeat="item in invoice.items">
<td text-align="center">
̶<̶a̶ ̶c̶l̶a̶s̶s̶=̶"̶b̶t̶n̶"̶ ̶h̶r̶e̶f̶=̶"̶"̶ ̶n̶g̶-̶c̶l̶i̶c̶k̶=̶"̶r̶e̶m̶o̶v̶e̶I̶t̶e̶m̶(̶)̶"̶>̶
<a class="btn" href="" ng-click="removeItem(item)">
<strong>[x]</strong>
</a>
</td>
$scope.removeItem = function(m) {
$scope.invoice.items.splice($scope.invoice.items.indexOf(m), 1);
}

How to use Nested ng-repeat to repeat table columns dynamically?

I want to make dynamic columns of a table and create a new object to save it in mongoDb.
I have first Array of Student as:
students = [{id: "1", name: "abc"},{id: "2", name: "def"},{id: "3", name: "hij"}]
and have second Array of Subjects as:
subjects = [{sName: "maths"},{sName: "science"}]
Here is the HTML
<div ng-app='t' ng-controller='test'>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th ng-repeat="subject in subjects">{{subject.sName}}</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in finalData track by $index">
<th><input type="text" ng-model="row.rollNo"/></th>
<th><input type="text" ng-model="row.fullName"></th>
<th ng-repeat="subject in subjects"><input type="text" ng-model="row.marks"></th>
<th>
<button ng-click="action($index)">
add/remove
</button></th>
</tr>
</tbody>
</table>
</div>
Here is the Controller
(function(){
var app = angular.module('t', []);
app.controller('test',
[
'$scope',
function($scope)
{
$scope.students = [{id: "1", name: "abc"},{id: "2", name: "def"},{id: "3", name: "hij"}]
$scope.subjects = [{sName: "maths"},{sName: "science"}]
$scope.finalData = new Array();
$scope.finalData.push({
icon : false
});
$scope.action=function(index){
if(index == $scope.finalData.length-1){
$scope.finalData[index].icon = true;
$scope.finalData.push({
icon : false
});
}else{
$scope.finalData.splice(index, 1);
}
};
}
]);
})();
The Output Looks like this.
The marks columns are repeating similar values. But i want one single finalObject to save my data.
Here is the jsFiddle of my problem https://jsfiddle.net/g8tn71tr/
The row subjects refer to the same NgModel row.marks which makes them have the same value.
You can solve it by making the ng-model refer to each of the subjects ng-model="row.marks[subject.sName]". This will result in that row.marks will become an object where each subject will be a key and the model will be in its value
(function(){
var app = angular.module('t', []);
app.controller('test',
[
'$scope',
function($scope)
{
$scope.students = [{id: "1", name: "abc"},{id: "2", name: "def"},{id: "3", name: "hij"}]
$scope.subjects = [{sName: "maths"},{sName: "science"}]
$scope.finalData = new Array();
$scope.finalData.push({
icon : false
});
$scope.action=function(index){
console.clear();
console.log($scope.finalData[index]);
if(index == $scope.finalData.length-1){
$scope.finalData[index].icon = true;
$scope.finalData.push({
icon : false
});
}else{
$scope.finalData.splice(index, 1);
}
};
}
]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app='t' ng-controller='test'>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th ng-repeat="subject in subjects">{{subject.sName}}</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in finalData track by $index">
<th><input type="text" ng-model="row.rollNo"/></th>
<th><input type="text" ng-model="row.fullName"></th>
<th ng-repeat="subject in subjects"><input type="text" ng-model="row.marks[subject.sName]"></th>
<th>
<button ng-click="action($index)">
add/remove
</button></th>
</tr>
</tbody>
</table>
</div>

Not able to populate the data into the fields based on the dropdown selection

I am kind of new to angular trying to develop an application with CRUD operations. i am trying to hold the value of a drop down for further usage and populate the data into the fields based on the selection.
Not able to populate the data into the fields based on the selection of the dropdown: if i use "product.id as product.name for product in listProducts" instead of ng-options="product.name for product in listProducts"
any help is appreciated thanks in advance
var myapp = angular.module("myModule", []);
myapp.controller("myController", function($scope){
var listProducts = [
{ id: '100', name: "Macy", price: 200, quantity: 2 },
{ id: '101', name: "JCPenny", price: 400, quantity: 1 },
{ id: '102', name: "Primark", price: 300, quantity: 3 },
{ id: '103', name: "H&M", price: 600, quantity: 1 }
];
$scope.listProducts = listProducts;
});
<html ng-app="myModule">
<head>
<title> CRUD Operations </title>
<script src=https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js></script>
<script src="script.js"></script>
</head>
<body ng-controller="myController">
Here i am populating the data into the fields without holding the id as the value in the dropdown which is successfull
<div>
<select ng-model=search ng-options="product.name for product in listProducts">
</select>
<table>
<thead>
<tr>
<th>Edit Information </th>
</tr>
</thead>
<tbody>
<tr>
<td>ID</td>
<td>
<input type="text" ng-model="search.id"/>
</td>
</tr>
<tr>
<td>Name</td>
<td>
<input type="text" ng-model="search.name"/>
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" ng-model="search.price"/>
</td>
</tr>
</tbody>
</table>
</div>
if i hold the id as value display the name in the dropdown , not able to populate the data into the fields
<div>
<select ng-model=searchProduct ng-options="product.id as product.name for product in listProducts"></select>
<table>
<thead>
<tr>
<th>Edit Information </th>
</tr>
</thead>
<tbody>
<tr>
<td>ID</td>
<td>
<input type="text" ng-model="searchProduct.id"/>
</td>
</tr>
<tr>
<td>Name</td>
<td>
<input type="text" ng-model="searchProduct.name"/>
</td>
</tr>
<tr>
<td>Price</td>
<td>
<input type="text" ng-model="searchProduct.price"/>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Actually, you are almost there,
In your controller, simply assign an empty variable in your scope to hold the value selected:
var myapp = angular.module("myModule", []);
myapp.controller("myController", function($scope){
var listProducts = [
{ id: '100', name: "Macy", price: 200, quantity: 2 },
{ id: '101', name: "JCPenny", price: 400, quantity: 1 },
{ id: '102', name: "Primark", price: 300, quantity: 3 },
{ id: '103', name: "H&M", price: 600, quantity: 1 }
];
$scope.listProducts = listProducts;
$scope.selectedProduct = {};
});
and bind it to the select:
<select ng-model="selectedProduct" ng-options="product.name for product in listProducts">
Now, wherever you need the id, simply access it through $scope.selectedProduct.id

Angular table filtering with dynamic ng-model

I've done some basic Angular filtering but i encountered a little problem, and I don't know how to solve it. I have a table with heading with input. I want each input to filter the table by that column. The problem is trying to dynamically set ng-model to a corresponding column name. I can hard code it, but I need it dynamically. Has anyone done something like that before?
EDIT: Is there any way to sign key from ng-repeat to search[key] or something because i know interpolation doesn't work inside ng-model
Here is the code:
<table class="table table-striped">
<thead>
<tr ng-repeat="item in vm.students | limitTo:1">
<th ng-repeat="(key, val) in item">
{{key | format}}
</th>
</tr>
<tr ng-repeat="item in vm.students | limitTo:1">
<th ng-repeat="(key, val) in item">
<input type="text" ng-model='search.key'>
</th>
<tr>
</thead>
<tbody>
<tr ng-repeat="item in vm.students | filter:search.key ">
<td> {{item.id}}</td>
<td> {{item.car}}</td>
<td> {{item.payment_method}}</td>
<td> {{item.currency}}</td>
<td> {{item.city}}</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>
You can use Object.keys() method to populate an array of columns to generate your table and then use a search object for filtering, from the docs:
A pattern object can be used to filter specific properties on objects
contained by array. For example {name:"M", phone:"1"} predicate will
return an array of items which have property name containing "M" and
property phone containing "1".
Here is an example:
angular.module('app', [])
.controller('mainController', function mainController($scope) {
$scope.students = [
{ name: 'Aaron Judge', year: 'one', mark: 98 },
{ name: 'Ryan Zimmerman', year: 'two', mark: 76 },
{ name: 'Paul Goldschmidt', year: 'one', mark: 87 },
{ name: 'Mike Trout', year: 'two', mark: 89 },
{ name: 'Charlie Blackmon', year: 'one', mark: 77 },
{ name: 'Bryce Harper', year: 'three', mark: 67 },
{ name: 'Jose Altuve', year: 'two', mark: 83 },
];
$scope.columns = Object.keys($scope.students[0]);
$scope.search = {};
});
body { padding-top:50px; }
table input { color: black; }
<!-- CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/sandstone/bootstrap.min.css">
<!-- JS -->
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.js"></script>
<body ng-app="app">
<div class="container" ng-controller="mainController">
<div class="alert alert-info">
<h2>Students ({{search}})</h2>
<table class="table table-bordered">
<thead>
<tr>
<th ng-repeat="column in columns track by column">{{ column }}</th>
</tr>
<tr>
<th ng-repeat="column in columns track by column">
<input type="text" ng-model="search[column]">
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in students | filter:search track by student.name">
<td ng-repeat="column in columns track by column">{{ student[column] }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
Simple example of sorting table as per column , this can be improved by using custom filters also , this is basic example
<html>
<head>
<title>Angular JS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js">
</script>
<script>
var myApp = angular.module("myApp", []);
myApp.controller("firstCtrl", function($scope) {
$scope.books = [{
name: "Angular",
authur: "James",
price: 500,
year: 2012
}, {
name: "Java",
authur: "Durga",
price: 700,
year: 2001
}, {
name: "HTML",
authur: "Rahul",
price: 1500,
year: 2011
}, {
name: "CSS",
authur: "Anand",
price: 2500,
year: 2002
}, {
name: "Node",
authur: "Rade",
price: 550,
year: 2015
}];
});
</script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="firstCtrl">
<table border="1">
<tr>
<th >Name</th>
<th>Authur</th>
<th >Price</th>
<th>Year</th>
</tr>
<tr>
<td>
<input type="text" ng-model="filterWithName" />
</td>
<td>
<input type="text" ng-model="filterWithAuthur"/>
</td>
<td>
<input type="text" ng-model="filterWithPrice" />
</td>
<td>
<input type="text" ng-model="filterWithYear" />
</td>
</tr>
<tr ng-repeat="book in books | filter:{name:filterWithName,authur:filterWithAuthur,price:filterWithPrice,year:filterWithYear}">
<td>{{book.name}}</td>
<td>{{book.authur}}</td>
<td>{{book.price}}</td>
<td>{{book.year}}</td>
</tr>
</table>
</div>
</div>
</body>
</html>

AngularJS Table Custom Search Filter Per Column

I am looking for help in creating a custom filter that will work on any table that has a search property.
So far, I can get the table to filter based on what is input into each column search bar, but I can't figure out how to implement a 'startsWith' for each column as well so that it will only find 'Florida' if you type 'Flor' or 'Fl', etc. instead of finding it when typing 'lor' or 'ida'.
I have been able to get just one column working with a custom filter, but lost on how to implement this for multiple columns.
Here is the plunkr example: http://plnkr.co/edit/CE3uhZmksiepmVL2bLNF?p=preview
Script:
var app = angular.module("stateManagement", []);
app.controller("myCtrl", ["$scope", myCtrl]);
function myCtrl($scope) {
$scope.names = [{
Name: "Florida",
Country: "USA"
}, {
Name: "Texas",
Country: "USA"
}]
$scope.state = '';
$scope.elements = [{
state: "Florida"
}, {
state: "Texas"
}];
}
app.filter('myfilter', function() {
function strStartsWith(str, prefix) {
return (str.toLowerCase() + "").indexOf(prefix.toLowerCase()) === 0;
}
return function(items, state) {
var filtered = [];
angular.forEach(items, function(item) {
if (strStartsWith(item.state, state)) {
filtered.push(item);
}
});
return filtered;
};
});
Html:
<body ng-app='stateManagement' ng-controller='myCtrl'>
<div class="col-md-12">
<table class="table table-responsive">
<thead>
<tr>
<th>Name</th>
<th>Country</th>
</tr>
<tr>
<th><input class="form-control"
type="text"
placeholder="Search..."
ng-model="search.Name"/>
</th>
<th><input class="form-control"
type="text"
placeholder="Search..."
ng-model="search.Country"/>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names | filter:search">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-12">
<input ng-model="state">
<table id="hotels">
<tr data-ng-repeat="element in elements | myfilter:state">
<td>{{element.state}}</td>
</tr>
</table>
<br/>
</div>
</body>
Thank you in advance for helping!

Resources