search not working in angular data - angularjs

I want to format the date and then search from the input box. I am trying to use a converter but for some reason the search does not work and my filter isnt working either
here is my fiddle example
https://jsfiddle.net/U3pVM/25662/
here is my code
<div ng-app='app'>
<h2>Todo</h2>
<div ng-controller="TodoCtrl">
<form>
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-search"></i></div>
<input type="text" class="form-control" ng-model="search">
</div>
</div>
</form>
<div ng-repeat="item in data">
{{item.date }}
</div>
</div>
</div>
and here is my controller
var app = angular.module('app', []);
app.controller('TodoCtrl', function ($scope) {
$scope.data = [
{
name_object: "my Object",
date: "2016-05-01 20:00:00",
id: "123",
name: "xy kaj Pl"
},
{
name_object: "my Object2",
date: "2014-15-01 20:10:00",
id: "143",
name: "Rose Jack"
},
{
name_object: "my Object3",
date: "2015-17-01 04:00:00",
id: "143",
name: "John Smith"
},
{
name_object: "my Object4",
date: "2016-18-01 04:00:00",
id: "142",
name: "Barbara Francis"
}
]
});
$scope.dateFormat = function(string){
return isoDate(string);
};
app.filter('isoDate', function(string){
return new Date(string.split(' ').join('T'));
});
When I enter the date, it does not filter and also my custom filter is not working to formate date either.
Thanks

Search issue
As it is shown in example in filter angular docs you can use search filter as follows:
<div ng-repeat="item in data | filter:search:strict">
{{item.date }}
</div>
See jsfiddle
Formating issue
Prepare filter as follows:
app.filter('isoDate', function() {
return function(input) {
return new Date(input.split(' ').join('T'));
}}
);
Usage:
<div ng-repeat="item in data | filter:search:strict">
{{item.date | isoDate | date : 'yyyy-MM-dd hh:mm:ss'}}
</div>
Filter used this way affects only way of displaying dates and not affects search, so if you will use date format different than yyyy-MM-dd hh:mm:ss i.e. MM/dd/y search will work in data format, filter will affect on disply way. There will be mismach. Search will work for i.e. 05-02 (05/02/2012 will be displayed). See jsfiddle. Use custom search filter to keep consistency between way of displaying and search date format.
Custom search filter
app.filter('searchFor', function($filter) {
return function(arr, searchString) {
if (!searchString) {
return arr;
}
var result = [];
searchString = searchString.toLowerCase();
angular.forEach(arr, function(item) {
var itemDateInFormat = $filter('date')(new Date(item.date.split(' ').join('T')), 'MM/dd/y');
if (itemDateInFormat.indexOf(searchString) !== -1) {
result.push(item);
} else if (item.name.toLowerCase().indexOf(searchString) !== -1) {
result.push(item);
}
});
return result;
};
});
HTML:
<tr ng-repeat="item in data | searchFor:search">
<td> {{item.date | isoDate | date : 'MM/dd/y'}}</td>
<td> {{item.name}}</td>
</tr>
See jsfiddle
Remember to:
keep consistency between date format used in searchFor filter and date format used to display table.
add else if to apply search for other data like added else if (item.name.toLowerCase().indexOf(searchString) !== -1) { result.push(item);}
for item.name.

Related

How to sort dropdown list of objects in AngularJS

I have:
<select class="form-control" id="field_productDelivered" name="productDelivered" ng-model="vm.productDelivered.productDelivered" ng-options="product as product.name for product in vm.products track by product.id">
<option value=""></option>
</select>
Output is sorted by id, but I need to have it sorted by name.
I tried:
ng-options="product as product.name for product in vm.products track by product.id" | toArray | orderBy : 'name'"
but in console I get:
TypeError: dbg is undefined.
How can I sort it using Angular?
I think this should get you output going in the right direction. Hope it helps! Included a working example, with it the third param true to show items in reverse order.
This is what I imagine yours will look like to get them ordered accordingly.
ng-options="product as product.name for product in vm.products | toArray | orderBy : 'name' track by product.id"
function exampleController($scope) {
$scope.phones = [{
model: 'anteater'
}, {
model: 'bee'
}, {
model: 'cat'
}];
}
angular
.module('example', [])
.controller('exampleController', exampleController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container-fluid" ng-app="example">
<div class="container" ng-controller="exampleController">
<div class="row">
<ol>
<li ng-repeat="phone in phones | orderBy: 'model': true track by $index" ng-bind="phone.model"></li>
</ol>
</div>
</div>
</div>
This is a working example as same as in your case.
It looks you had the following two things which should be sorted.
You have closed the double quotes before the " | toArray in
"product as product.name for product in vm.products track by
product.id" | toArray | orderBy : 'name'"
Also the track by product.id should be at the end after the
filters like ng-options="product as product.name for product in vm.products | toArray | orderBy : 'name' track by product.id"
You can see the working example below as same as the one in the question.
var app = angular.module('app', []);
app.controller('TestController', function() {
this.productDelivered = {};
this.products = {
'product1': {
id: 4,
name: 'product B'
},
'product2': {
id: 3,
name: 'product D'
},
'product3': {
id: 1,
name: 'product A'
},
'product4': {
id: 2,
name: 'product C'
}
};
});
app.filter("toArray", function() {
return function(input) {
if(!input) return;
if (input instanceof Array) {
return input;
}
return $.map(input, function(val) {
return val;
});
};
});
angular.bootstrap(document, ['app']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="TestController as vm">
<select class="form-control" id="field_productDelivered" name="productDelivered" ng-model="vm.productDelivered.productDelivered"
ng-options="product as product.name for product in vm.products | toArray | orderBy : 'name' track by product.id">
<option value=""></option>
</select>
</div>

Hide headers in multiple ng-repeat if no values during filtering

I'm struggling with angularjs! Here's the problem. I've a list of employees from different company to show. Data are like these:
[
{
name : "company1",
employees : [
{ name : "emp1"},
{...}
]
},
{ .. }
]
I show them using two ng-repeat:
<div ng-repeat="company in companies ">
<div class="header">{{company.name}}</div>
<div ng-repeat="employee in company.employees | filter:search">
{{employee.name}}
</div>
</div>
Here we are, I want to avoid, during filtering the headers of company with no employees.
Hope you guys are smarter than me :)
<div ng-repeat="company in companies ">
<div class="header" ng-show="results.length>0"> {{company.name}}</div>
<div ng-repeat="employee in company.employees | filter:search as results">
{{employee.name}}
</div>
Explaination: after filtering your filtered data will be stored in ressults , which we can use to decide whether to show company name or not
Try this, I also attached demo.
ng-show="(company.employees | filter:search).length"
var app = angular.module('app', []);
app.controller('myctrl', function() {
var vm = this;
vm.companies = [{
name: "company1",
employees: [{
name: "emp1"
}, {
name: "poiuy"
}, {
name: "asdf"
}]
}, {
name: "company2",
employees: [{
name: "ghj"
}, {
name: "jkl"
}, {
name: "ooo"
}]
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="myctrl as ct">
<input ng-model="ct.search">
<div ng-repeat="company in ct.companies ">
<div class="header" ng-show="(company.employees | filter:ct.search).length">{{company.name}}</div>
<div ng-repeat="employee in company.employees | filter:ct.search">
{{employee.name}}
</div>
</div>
</div>
</body>

filtering month in date angularjs

I 've successed to filter a date with angularjs. but I want to filter the month only. i want if I typed 01 only titanic appears. here is my sample data.
view
<input type="text" ng-model="search" />
<tr ng-repeat="n in eventlist | filter:search">
<td>{{n.name}}</td>
<td>{{n.date | date:"dd MMMM yyyy"}}</td>
</tr>
controller
$scope.eventlist = [
{name:"Titanic", date:"2016-01-24"},
{name:"Civil War", date:"2016-07-01"}
];
you should use custome filter for this. try like this.
var app = angular.module('main', []);
app.controller('DemoCtrl', function ($scope,$filter) {
$scope.eventlist =
[
{name:"Titanic", date:"2016-01-24"},
{name:"Civil War", date:"2016-02-15"}
];
$scope.myFilter = function(month,search){
return function(event) {
return event.date.split('-')[1] == $scope.search ?true:false;
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="DemoCtrl" ng-app="main">
<input type="text" ng-model="search" />
<div ng-repeat="n in eventlist | filter:myFilter()" >
<span>{{n.name}}</span>
<span>{{n.date}}</span>
</div>
</div>

Compare two lists in angularJs

I have two list that creat from two different json object:
<ul ng-repeat="a in user.data">
<li>
<md-checkbox>
{{ a.name }}
</md-checkbox>
</li>
</ul>
and :
<ul ng-repeat="x in job.data">
<li>
<md-checkbox>
{{ x.user.name }}
</md-checkbox>
</li>
</ul>
I have to compare two lists and remove {{ a.name }} that the same as {{ job.user.name }} . Comparing json objects that have different structure is hard. How can I compare this two list and remove repeated items?
You can use the filter filter ;) using a function instead of a string in the expression argument. Remember this is the syntax of filter
{{ filter_expression | filter : expression : comparator}}
The expression can be a string, an object or a function. Something like this will do
$scope.filterUnemployed = function(value) {
var jobs = $scope.job.data;
for (var i = 0; i < jobs.length; i++) {
// Search every object in the job.data array for a match.
// If found return false to remove this object from the results
if (jobs[i].user.name === value.name) {
return false;
}
}
// Otherwise return true to include it
return true;
}
And then apply the filter to your ng-repeat directive like this
<ul ng-repeat="a in user.data | filter:filterUnemployed">
<li>
<md-checkbox>
{{ a.name }}
</md-checkbox>
</li>
</ul>
Note that this will not modify your original collection but will result in a new copy beign displayed in your html since this is usually the desired effect.
Check the sample for a working demo
angular.module('app', [])
.controller('SampleCtrl', function($scope) {
$scope.user = {
data: [{
name: 'John'
}, {
name: 'Mary'
}, {
name: 'Peter'
}, {
name: 'Jack'
}, {
name: 'Richard'
}, {
name: 'Elizabeth'
}]
};
$scope.job = {
data: [{
jobTitle: 'CEO',
user: {
name: 'John'
}
}, {
jobTitle: 'CFO',
user: {
name: 'Mary'
}
}, {
jobTitle: 'Analist',
user: {
name: 'Jack'
}
}]
};
$scope.filterUnemployed = function(value) {
var jobs = $scope.job.data;
for (var i = 0; i < jobs.length; i++) {
if (jobs[i].user.name === value.name) {
return false;
}
}
return true;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="SampleCtrl">
<h1>All Users</h1>
<ul ng-repeat="a in user.data">
<li>
<md-checkbox>
{{ a.name }}
</md-checkbox>
</li>
</ul>
<h1>Unemployed users</h1>
<ul ng-repeat="a in user.data | filter:filterUnemployed">
<li>
<md-checkbox>
{{ a.name }}
</md-checkbox>
</li>
</ul>
<h1>Employed</h1>
<ul ng-repeat="x in job.data">
<li>
<md-checkbox>
{{ x.user.name }}
</md-checkbox>
</li>
</ul>
</div>
You can create a new array made from filtering one of your arrays :
var newArray = job.data.filter(function(jobData) {
return user.data.some(function(userData) {
return userData.name === jobData.user.name;
});
});
Something like this should help :
for(i=0; i<user.data.length;i++){
for(j=0; j<job.data.length;j++){
if(user.data[i].name === job.data[j].name){
user.date.splice(i,1);
}
}
}
I would appreciate some feedback, at least to know that my code helped you
You can use vanilla javascript, jQuery or library undescore.
Please check related links:
How can I merge two complex JSON objects with only unique or different values only showing in resultant array
How to merge two object values by keys
How to merge two arrays of JSON objects - removing duplicates and preserving order in Javascript/jQuery?
Merging two json objects in Java script?

how get the list of selected items in angular.js

Here I am using angular.js to show a list of people
<div class="recipient" ng-repeat="person in people">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
$scope.people = [{id:1}, {id:2}, {id:3}, {id:4}];
The looks is like below
What I want to do is I can select multiple items and by click a OK button, I can get a list of selected items. so If I select id 1 and id 2, then I want to get return a list of [{id:1},{id:2}]
How could I implement it in angular.js
Well I guess that if you're looping through a collection of people using a ng-repeat, you could add the ng-click directive on each item to toggle a property of you're object, let's say selected.
Then on the click on your OK button, you can filter all the people that have the selected property set to true.
Here's the code snippet of the implementation :
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)">
<img src="{{person.img}}" /> person.name
<div class="email">person.email</div>
</div>
<button ng-click="result()">OK</button>
function demo($scope) {
$scope.ui = {};
$scope.people = [{
name: 'Janis',
selected: false
}, {
name: 'Danyl',
selected: false
}, {
name: 'tymeJV',
selected: false
}];
$scope.selectPeople = function(people) {
people.selected = !people.selected;
};
$scope.result = function() {
$scope.ui.result = [];
angular.forEach($scope.people, function(value) {
if (value.selected) {
$scope.ui.result.push(value);
}
});
};
}
.recipient {
cursor: pointer;
}
.select {
color:green;
}
.recipient:hover {
background-color:blue;
}
<script src="https://code.angularjs.org/1.2.25/angular.js"></script>
<div ng-app ng-controller="demo">
<div class="recipient" ng-repeat="person in people" ng-click="selectPeople(person)" ng-class="{ select: person.selected }">
<div class="name">{{ person.name }}</div>
</div>
<button ng-click="result()">OK</button>
Result :
<ul>
<li ng-repeat="item in ui.result">{{ item.name }}</li>
</ul>
</div>
If you only want to show checked or unchecked you could just apply a filter, but you would need to toggle the filter value from undefined to true if you didn't wan't to get stuck not being able to show all again.
HTML:
<button ng-click="filterChecked()">Filter checked: {{ checked }}</button>
<div class="recipient" ng-repeat="person in people | filter:checked">
<input type='checkbox' ng-model="person.isChecked" />
<img ng-src="{{person.img}}" />{{ person.name }}
<div class="email">{{ person.email }}</div>
</div>
Controller:
// Apply a filter that shows either checked or all
$scope.filterChecked = function () {
// if set to true or false it will show checked or not checked
// you would need a reset filter button or something to get all again
$scope.checked = ($scope.checked) ? undefined : true;
}
If you want to get all that have been checked and submit as form data you could simply loop through the array:
Controller:
// Get a list of who is checked or not
$scope.getChecked = function () {
var peopleChkd = [];
for (var i = 0, l = $scope.people.length; i < l; i++) {
if ($scope.people[i].isChecked) {
peopleChkd.push(angular.copy($scope.people[i]));
// Remove the 'isChecked' so we don't have any DB conflicts
delete peopleChkd[i].isChecked;
}
}
// Do whatever with those checked
// while leaving the initial array alone
console.log('peopleChkd', peopleChkd);
};
Check out my fiddle here
Notice that person.isChecked is only added in the HTML.

Resources