filtering month in date angularjs - 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>

Related

Angular JS - filter text in a table column that contains an array

I'll try to explain my issue with an example:
html code:
<body>
<input type="search" placeholder="filter by line" ng-model="filter.line">
<input type="search" placeholder="filter by area" ng-model="filter.area">
<input type="search" placeholder="filter by text" ng-model="filter.text">
<div>
<tbody ng-repeat="document in result.documents | filter:{line:filter.line} |filter:{area:filter.area}">
<tr>
<td>{{document.line}}</td>
<td>{{document.area}}</td>
<td>{{document.sentences}}</td>
</tr>
</tbody>
My Data example:
$scope.result = {
documents: {
{code:"1",
line:"line1",
area:"area1",
sentences:
{
{"aaaaa"},
{"bbbb"},
{"ccccc"}
}
},
{code:"2",
line:"line2",
area:"area2",
sentences:
{
{"dddd"},
{"eeee"},
{"ffff"}
}
}
}};
So what i'm trying to do is to add a filter using the input "filter.text" to filter only in the column "sentences".
something like
filter:{sentences:filter.text}
How i can do it?
var myApp = angular.module('myApp', [])
myApp.controller("userCtrl", function ($scope) {
$scope.filter_t={};
$scope.result = {
documents:
[{"code":0,"line":"line0","area":"aaa0","sentences":{"id":0}},{"code":1,"line":"line1","area":"aaa1","sentences":{"id":1}},{"code":2,"line":"line2","area":"aaa2","sentences":{"id":2}},{"code":3,"line":"line3","area":"aaa3","sentences":{"id":3}},{"code":4,"line":"line4","area":"aaa4","sentences":{"id":4}},{"code":5,"line":"line5","area":"aaa5","sentences":{"id":5}},{"code":6,"line":"line6","area":"aaa6","sentences":{"id":6}},{"code":7,"line":"line7","area":"aaa7","sentences":{"id":7}},{"code":8,"line":"line8","area":"aaa8","sentences":{"id":8}},{"code":9,"line":"line9","area":"aaa9","sentences":{"id":9}}]
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="userCtrl">
<input type="search" placeholder="filter by line" ng-model="filter_t.line">
<input type="search" placeholder="filter by area" ng-model="filter_t.area">
<input type="search" placeholder="filter by sentences inside id based" ng-model="filter_t.sentences.id">
<div>
<table border='1'>
<tbody ng-repeat="document in result.documents | filter:filter_t">
<tr>
<td>{{document.line}}</td>
<td>{{document.area}}</td>
<td>{{document.sentences.id}}</td>
</tr>
</tbody>
</table>
</div>
try this Data,
$scope.result = {
documents: {
{code:"1",
line:"line1",
area:"area1",
sentences:
{
{"aaaaa"},
{"bbbb"},
{"ccccc"}
}
},
{code:"2",
line:"line2",
area:"area2",
sentences:
{
{"dddd"},
{"eeee"},
{"ffff"}
}
}
}
};

search not working in angular data

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.

Angular two way data-binding dosn´t update table in different route

I have an angular app, and an index.html with an ng-view that renders to different views partials/persons.html and partials/newPerson.html.
when i add a new person to the $scope.persons in my controller via the newPerson.html the $scope.persons is updated, but it dosn´t updated the table in the partials/persons.html. if i copy/paste the table into partials/newPerson.html the table is updated automatically. I cant seem to wrap my head around why? they are using the same controller...?
thank´s in advance for your help :)
js/app.js
var app = angular.module('app',['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when('/persons',{
templateUrl:'partials/persons.html',
controller:'PersonCtrl'
})
.when('/newperson',{
templateUrl:'partials/newPerson.html',
controller:'PersonCtrl'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('PersonCtrl',['$scope', function($scope){
var persons = [
{
id: 1
,name: "Jens",
age : 18}
,{
id: 2,
name: "Peter",
age : 23
}
,{
id: 3
,name: "Hanne"
,age : 23
}
];
$scope.persons = persons;
$scope.nextId = 4;
$scope.savePerson = function(){
if($scope.newPerson.id === undefined)
{
$scope.newPerson.id= $scope.nextId++;
$scope.persons.push($scope.newPerson);
}else{
for (var i = 0; i < $scope.persons.length; i++) {
if($scope.persons[i].id === $scope.newPerson.id){
$scope.persons[i] = $scope.newPerson;
break;
}
}
}
$scope.newPerson = {};
};
index.html
<html ng-app="app" ng-controller="PersonCtrl">
<head>
<title>Routing</title>
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.js"></script>
<script src="https://code.angularjs.org/1.4.7/i18n/angular-locale_da.js"></script>
<script src="angularSrc/app.js"></script>
</head>
<body>
<br>
<div class="container">
<header>
<h1>People Routing</h1>
<nav>
persons
new person
</nav>
</header>
<div ng-view="ng-view">
</div>
</div>
</body>
partials/persons.html
<h3>Persons</h3>
<table >
<thead>
<tr>
<td>Id</td>
<td>name</td>
<td>age</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="p in persons">
<td>{{p.id}} </td>
<td>{{p.name}} </td>
<td>{{p.age}} </td>
</tr>
</tbody>
</table>
partials/newPerson.html
<div >
<h1>New person</h1>
<form class="form-horizontal">
<fieldset>
<div class="form-group">
<input type="text" ng-model="newPerson.name" model="newPerson.name" class="form-control" id="year" placeholder="name">
</div>
<div class="form-group">
<input type="number" ng-model="newPerson.age" model="newPerson.age" class="form-control" id="age" placeholder="age">
</div>
</fieldset>
</form>
<button type="submit" ng-click="savePerson()" >Save</button>
<h2>nextId: {{nextId}}</h2>
</div>
The problem is that you aren't realizing that each use of controller creates new instance.
The scope is destroyed when you leave a controller so if you add to the scope in one instance , that change will be lost when you load controller again on your other route.
You need to use a service to persist the data during the life of each page load.
Simple service example:
app.factory('PersonService', function () {
var persons = [{
id: 1,
name: "Jens",
age: 18
}, {
...
}, {
...
}];
return {
persons: persons
}
});
Then inject in controller and use the service data in controller
app.controller('PersonCtrl',['$scope','PersonService', function($scope,PersonService){
$scope.persons = PersonService.persons;

Angular firebase filtering data with 3-way binding

I have a simple angular app with a a data array:
app.js
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl', function ($scope) {
$scope.data = [
{name: "Alice", age: 28},
{name: "Bob", age: 55},
...
];
});
index.html
<input type="text" ng-model="data.search">
<table>
<tbody>
<tr ng-repeat="row in data | filter:data.search">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
</tr>
</tbody>
</table>
Now, I want to start using the firebase service to experience cool 3-way binding. So I do something like this:
app.js
var myApp = angular.module('myApp', ['firebase']);
myApp.controller('Ctrl', function ($scope) {
var ref = new Firebase("https://<myapp>.firebaseio.com/");
// assume there is already data in here similar to above
$scope.data = $firebase(ref);
});
Of course now my search filter breaks because $scope.data is an Object not an Array. Of course I could transform the data, but that would break the automatic 3-way binding.
So my question is - how should filters be applied to this data whilst maintaining the 3-way relationship?
You can use the orderByPriority filter first which converts the object to an array:
<tr ng-repeat="row in data | orderByPriority | filter:data.search">
Alternatively, you can use the filter in your controller to make sure $scope.data is an array to begin with.
Anant's suggestion works. Working fiddle: http://jsfiddle.net/rwk1/vqVw7/
Can't post as a comment yet.
HTML
<div ng-app="myApp">
<div ng-controller="testController">
<input type="text" ng-model="search.searchText"></input>
<div>
<ul ng-repeat="person in people | orderByPriority | filter:search.searchText">
<li>name:{{ person.name }}</li>
<li>age:{{ person.age }}</li>
</ul>
<input type="text" placeholder="name" ng-model="newPerson.name"/>
<input type="text" placeholder="age" ng-model="newPerson.age"/>
<button type="submit" ng-click="addPerson()">Add New Person</button>
</div>
</div>
</div>
JS
var myApp = angular.module('myApp', ["firebase"]);
myApp.controller('testController', function ($scope, $firebase) {
$scope.data = [{
name: "Alice",
age: 28
}, {
name: "Bob",
age: 55
}];
var peopleRef = new Firebase("https://sqt.firebaseio.com/people");
// Automatically syncs everywhere in realtime
$scope.people = $firebase(peopleRef);
$scope.addPerson = function(){
$scope.people.$add($scope.newPerson);
$scope.newPerson = "";
};

How to default a table search results to hidden with AngularJS filters?

In the following Angularjs snippet, an entire table is shown by default and gets filtered down as you start typing.
What would be best practice to change it to show no results by default and only start showing results after, say, at least 3 results match the search query?
Bonus question, how would you go about only displaying results if a minimum of 2 characters have been entered?
Html:
<div ng-app="myApp">
<div ng-controller="PeopleCtrl">
<input type="text" ng-model="search.$">
<table>
<tr ng-repeat="person in population.sample | filter:search">
<td>{{person.name}}</td>
<td>{{person.job}}</td>
</tr>
</table>
</div>
</div>
Main.js:
var myApp = angular.module('myApp', []);
myApp.factory('Population', function () {
var Population = {};
Population.sample = [
{
name: "Bob",
job: "Truck driver"
}
// etc.
];
return Population;
});
function PeopleCtrl($scope, Population) {
$scope.people = Population;
}
You can do all of that in your markup, actually... here's a plunk to demonstrate
And here's the change in your markup:
<input type="text" ng-model="search">
<table ng-show="(filteredData = (population.sample | filter:search)) && filteredData.length >= 3 && search && search.length >= 2">
<tr ng-repeat="person in filteredData">
<td>{{person.name}}</td>
<td>{{person.job}}</td>
</tr>
</table>
EDIT: changed my answer to reflect your requests.

Resources