Converting Datetime in month using AngularJs - angularjs

I'm consuming json data in an array. In each row I have a datetime field.
Each datetime field represents data in this form 2016-11-19 00:00:00.
I want to show date and month separate as separate values.
It's my code:
<span class="day">8</span>
<span class="month">{{ event.event_date | date:'MMM' }}</span>
<span class="year">2014</span>
<span class="time">12:00 AM</span>

I have a simple solution to this:
In controller:
$scope.myDate = new Date("2016-11-19 00:00:00");
$scope.myDate_month = $scope.myDate.getMonth();
$scope.myDate_day = $scope.myDate.getDate();
$scope.myDate_year = $scope.myDate.getFullYear();
$scope.time = $scope.myDate.getHours();
$scope.time = $scope.myDate.getMinutes();
In html:
<span class="day">{{myDate_day}}</span>
<span class="month">{{myDate_month}}</span>
<span class="year">{{myDate_year}}</span>
<span class="time">{{myDate | date: 'h:mm a'}}</span>

Since your dates are strings, you should parse them to Date, like this:
$scope.event_date = new Date("2016-11-19 00:00:00");
Then you can call your filter in view:
<span ng-bind="date | date:'MMM'"></span>
Example:
angular.module('app', [])
.controller('mainCtrl', function($scope) {
$scope.events = [];
// Simulation of $http.get
for (var i = 1; i < 10; i++) {
$scope.events.push({
"id": Math.floor(Math.random() * 100) + 1,
"event_date": "201" + i + "-0" + i + "-" + i + " 0" + i + ":00:00"
})
}
// Parsing your strings to date objects
$scope.events.map(function(value) {
value.event_date = new Date(value.event_date);
})
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<div ng-repeat="event in events track by $index">
<!--
<span class="day">8</span>
<span class="month" ng-bind="event.event_date | date:'MMM'"></span>
<span class="year">2014</span>
<span class="time">12:00 AM</span>
-->
<span class="day" ng-bind="event.event_date | date:'dd'"></span>
<span class="month" ng-bind="event.event_date | date:'MMM'"></span>
<span class="year" ng-bind="event.event_date | date:'yyyy'"></span>
<span class="time" ng-bind="event.event_date | date:'HH:mm'"></span>
</div>
</body>
</html>
Check the API of the date-filter.

Related

Custom Filter in Angular throws in console errors

Getting started with Angular . Had a doubt . In this piece of code ..
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in names | orderBy: totalMoney">
{{ x.name + ', ' + x.country +', '}} {{x.salary | currency}} {{', '}} {{x.salary + x.bonus | currency}}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway',salary:8500,bonus:350},
{name:'Carl',country:'Sweden',salary:5500,bonus:250},
{name:'Margareth',country:'England',salary:7250,bonus:750},
{name:'Hege',country:'Norway',salary:4750,bonus:220},
{name:'Joe',country:'Denmark',salary:5950,bonus:250},
{name:'Gustav',country:'Sweden',salary:11050,bonus:550},
{name:'Birgit',country:'Denmark',salary:6700,bonus:300},
{name:'Mary',country:'England',salary:3500,bonus:150},
{name:'Kai',country:'Norway',salary:9750,bonus:400}
];
})
.filter('totalMoney',function(){
return function(user) {
return user.salary + user.bonus;
}
});
</script>
</body>
</html>
the totalMoney filter does not work as expected and throws errors in console.
But the following code works .
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<p>Looping with objects:</p>
<ul>
<li ng-repeat="x in names | orderBy: totalMoney">
{{ x.name + ', ' + x.country +', '}} {{x.salary | currency}} {{', '}} {{x.salary + x.bonus | currency}}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway',salary:8500,bonus:350},
{name:'Carl',country:'Sweden',salary:5500,bonus:250},
{name:'Margareth',country:'England',salary:7250,bonus:750},
{name:'Hege',country:'Norway',salary:4750,bonus:220},
{name:'Joe',country:'Denmark',salary:5950,bonus:250},
{name:'Gustav',country:'Sweden',salary:11050,bonus:550},
{name:'Birgit',country:'Denmark',salary:6700,bonus:300},
{name:'Mary',country:'England',salary:3500,bonus:150},
{name:'Kai',country:'Norway',salary:9750,bonus:400}
];
$scope.totalMoney = function(user) {
return user.salary + user.bonus;
}
});
</script>
</body>
</html>
But is not the first approach the desired one while creating custom filters ?
Then why did not it work ?
How to make it work ?
You cannot assign custom filter to a filter like
<li ng-repeat="x in names | orderBy: orderByValue">
orderBy Can only take sting and function as parameter not other custom filter. Either you can create a function and pass to orderBy like in you did in your working example. Or you can use custom filter as i have shown below.
This will be your custom filter:
myApp.filter('orderByValue', function () {
// custom value function for sorting
function myValueFunction(card) {
return user.salary + user.bonus;
}
This will be your HTML:
<ul>
<li ng-repeat="x in names | orderByValue">
{{ x.name + ', ' + x.country +', '}} {{x.salary | currency}} {{', '}} {{x.salary + x.bonus | currency}}
</li>
</ul>
OrderBy will not allow objects. so you have to create custom filter.
View code: <ul>
<li ng-repeat="x in names | orderObjectBy">
{{ x.name + ', ' + x.country +', '}} {{x.salary | currency}} {{','}} {{x.salary + x.bonus | currency}}
</li>
</ul>
JS code:
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway',salary:8500,bonus:350},
{name:'Carl',country:'Sweden',salary:5500,bonus:250},
{name:'Margareth',country:'England',salary:7250,bonus:750},
{name:'Hege',country:'Norway',salary:4750,bonus:220},
{name:'Joe',country:'Denmark',salary:5950,bonus:250},
{name:'Gustav',country:'Sweden',salary:11050,bonus:550},
{name:'Birgit',country:'Denmark',salary:6700,bonus:300},
{name:'Mary',country:'England',salary:3500,bonus:150},
{name:'Kai',country:'Norway',salary:9750,bonus:400}
];
})
.filter('orderObjectBy', function() {
return function(items, field, reverse) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
filtered.sort(function (a, b) {
return (a['salary']+a['bonus'] > b['salary']+b['bonus'] ? 1 : -1);
});
if(reverse) filtered.reverse();
return filtered;
};
});

How to get array count of filtered result on dir-pagination?

At the monent I have this code.
<tr dir-paginate="person in People | filter:q
| orderBy:sortKey:reverse| itemsPerPage: criteria.pagesize"
current-page="currentPage" pagination-id="PeoplePagination">
My question is how to do I get the count for the filtered array when using angular dir-pagination on the controller.
on the directive template url which is dirPagination.tpl.html the code below provides value.
<div class="range-label">Displaying {{ range.lower }} -
{{ range.upper }} of {{ range.total }}</div>
My question is how do I get the {{range.total}} if I put this on my main controller.
UPDATE :
Range is located on dir-pagination directive
link: function dirPaginationControlsLinkFn(scope, element, attrs) {
// rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has
// not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is
// no corresponding dir-paginate directive and wrongly throwing an exception.
var rawId = attrs.paginationId || DEFAULT_ID;
var paginationId = scope.paginationId || attrs.paginationId || DEFAULT_ID;
if (!paginationService.isRegistered(paginationId) && !paginationService.isRegistered(rawId)) {
var idMessage = (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' ';
throw 'pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive.';
}
if (!scope.maxSize) { scope.maxSize = 9; }
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;
var paginationRange = Math.max(scope.maxSize, 5);
scope.pages = [];
scope.pagination = {
last: 1,
current: 1
};
scope.range = {
lower: 1,
upper: 1,
total: 1
};
Here's the Plunker
Basically what I want is to get the value of the current array size when the user enter something on the searchbox.
You could use
<li dir-paginate="meal in filteredMeals = (meals | filter:q)
| itemsPerPage: pageSize" current-page="currentPage">
and then reference
<span ng-bind="filteredMeals.length"></span>
as described by https://stackoverflow.com/a/19517533/4068027.
Strangely enough the Angular 1.3+ method with filter: q as filteredMeals did not work with dir-paginate (at least not with the versions used in your plnkr).
See updated plunker
Instead of using dir-paginate - I have created a simple logic, I hope you can use this for your requirement..!!
<script>
var angularPageList = angular.module('angularPageList',['ui.bootstrap']);
angularPageList.controller('listCountControl',['$scope',function($s){
$s.totalListCount = 20;
$s.currentPage = 1;
$s.numPages = 1;
$s.viewby = 5;
$s.itemsPerPage = $s.viewby;
$s.maxSize = 5;
$s.setItemsPerPage = function(num) {
$s.itemsPerPage = num;
$s.currentPage = 1; //reset to first page
}
$s.getLastIndex = function (index){
$s.lastIndex = index;
console.log($s.lastIndex)
}
$s.getFirstIndex = function (index){
$s.firstIndex = index;
console.log($s.firstIndex)
}
}]);
</script>
<div ng-app="angularPageList">
<div class="container">
<h2>List Count - UIB Pagination (AngularJs)</h2>
<div ng-controller="listCountControl">
<div class="row" style="margin-top:50px">
<div class="col-sm-2 text-center">
<div ng-repeat="i in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20].slice(((currentPage-1)*itemsPerPage), ((currentPage)*itemsPerPage))">
<span ng-init="$last ? getLastIndex(tutorSearchBlok.sBindex) : '';$first ? getFirstIndex(tutorSearchBlok.sBindex) : ''"></span>
<span ng-init="$last ? getLastIndex(i) : '';$first ? getFirstIndex(i) : ''"></span>
<div style="font-size:18px;padding:10px 0;background:#fafafa;border-top:1px solid #ddd;">{{i}}</div>
</div>
</div>
<div class="col-sm-6">
<span>List Count: </span>«<b>{{firstIndex+1}}</b> to <b>{{lastIndex+1}}</b>» of {{totalListCount}}
<hr>
<ul uib-pagination total-items="totalListCount" ng-model="currentPage" max-size="maxSize" class="pagination-sm" boundary-links="true" num-pages="numPages" items-per-page="itemsPerPage"></ul>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script>
<script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.5.2/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="ui-bootstrap-2.5.0.min.js"></script>

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>

How to show data in model coresponding to another model data

How to make a custom filter in angularjs for filtering data based on 1 criteria nad displaying the corresponding data in another model.??? in dis code, i want to show subject name corresponding to the fee, if i enter 165 in fee then subject Name model shoud show math.
<html>
<head>
<title>Angular JS Filters</title>
</head>
<body>
<h2>AngularJS Sample Application</h2>
<div ng-app="" ng-controller="studentController">
<table border="0">
<tr><td>Enter first name:</td><td><input type="text" ng-model="student.firstName"></td></tr>
<tr><td>Enter last name: </td><td><input type="text" ng-model="student.lastName"></td></tr>
<tr><td>Enter fees: </td><td><input type="text" ng-model="subjectFee"></td></tr>
<tr><td>Enter subject: </td><td><input type="text" ng-model="subjectName"></td></tr>
</table>
<br/>
<table border="0">
<tr><td>Name in Upper Case: </td><td>{{student.fullName() | uppercase}}</td></tr>
<tr><td>Name in Lower Case: </td><td>{{student.fullName() | lowercase}}</td></tr>
<tr><td>Fee:</td><td>
<ul>
<li ng-repeat="subject in student.subjects | filter: subjectFee |orderBy:'marks'">
{{ ' fee:' + subject.fee }}
</li>
</ul>
</td></tr>
<tr><td>Subject:</td><td>
<ul>
<li ng-repeat="subject in student.subjects | filter: subjectName |orderBy:'marks'">
{{ subject.name + ', marks:' + subject.marks +', fee:' + subject.fee }}
</li>
</ul>
</td></tr>
</table>
</div>
</script>
<script>
function studentController($scope) {
$scope.student = {
firstName: "Mahesh",
lastName: "Parashar",
subjects:[
{name:'Physics',marks:70, fee:170},
{name:'Chemistry',marks:80, fee:180},
{name:'Math',marks:65, fee:165}
],
fullName: function() {
var studentObject;
studentObject = $scope.student;
return studentObject.firstName + " " + studentObject.lastName;
}
};
}
</script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"> </script>
</body>
</html>
The following change in your code can generate the desired output.
<li ng-repeat="subject in student.subjects | filter: (subjectFee || subjectName) |orderBy:'marks'">

Filter results 6 through 10 of 100 with ng-repeat in AngularJS

I see the limitTo filter in the docs, which allows me to limit the first 5, or last 5 results, but I want to set where my limit starts so I can show the second set of 5 results.
Is there a built in filter for that?
Since Angular 1.4.0, the limitTo filter takes an optional begin argument:
<div ng-repeat="item in items | limitTo:5:5">{{item}}</div>
In older versions, writing a custom filter is fairly straightforward. Here's a naïve implementation based on Array#slice (note you pass the first and last index, instead of a count):
app.filter('slice', function() {
return function(arr, start, end) {
return (arr || []).slice(start, end);
};
});
<div ng-repeat="item in items | slice:6:10">{{item}}</div>
Working jsFiddle: http://jsfiddle.net/BinaryMuse/vQUsS/
Alternatively, you can simply steal the entire Angular 1.4.0 implementation of limitTo:
function limitToFilter() {
return function(input, limit, begin) {
if (Math.abs(Number(limit)) === Infinity) {
limit = Number(limit);
} else {
limit = toInt(limit);
}
if (isNaN(limit)) return input;
if (isNumber(input)) input = input.toString();
if (!isArray(input) && !isString(input)) return input;
begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
begin = (begin < 0 && begin >= -input.length) ? input.length + begin : begin;
if (limit >= 0) {
return input.slice(begin, begin + limit);
} else {
if (begin === 0) {
return input.slice(limit, input.length);
} else {
return input.slice(Math.max(0, begin + limit), begin);
}
}
};
}
AngularJS provides that functionality already out of the box. If you carefully read the limitTo documentation it allows you to specify a negative value for the limit. That means N elements at the end so if you want to process 5 results after an offset of 5 you need to do the following:
<div ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</div>
I started playing around with customer filters but then found out you can just call slice inside of the ng-repeat expression:
<div ng-repeat="item in items.slice(6, 10)">{{item}}</div>
As bluescreen said, it can be done using only the limitTo filter, although dealing with the last page problem noticed by Harry Oosterveen needs some extra work.
I.e. using ui-bootstrap pagination directive properties:
ng-model = page // current page
items-per-page = rpp // records per page
total-items = count // total number of records
The expression should be:
<div ng-repeat="item in items | limitTo: rpp * page | limitTo: rpp * page < count ? -rpp : rpp - (rpp * page - count)">{{item}}</div>
Here's a functional example on how to filter a list with offset and limit:
<!doctype html>
<html lang="en" ng-app="phonecatApp">
<head>
<script src="lib/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
Offset: <input type="text" ng-model="offset" value="0" /><br />
Limit: <input type="text" ng-model="limit" value="10" /><br />
<p>offset limitTo: {{offset - phones.length}}</p>
<p>Partial list:</p>
<ul>
<li ng-repeat="phone in phones | limitTo: offset - phones.length | limitTo: limit">
{{$index}} - {{phone.name}} - {{phone.snippet}}
</li>
</ul>
<hr>
<p>Whole list:</p>
<ul>
<li ng-repeat="phone in phones">
{{$index}} - {{phone.name}} - {{phone.snippet}}
</li>
</ul>
</body>
</html>
The example is based on the second step of AngularJS tutorial.
Note that the filter for the offset has to be put as the first filter if you want to cover the generic case where the limit is uknnown.
from bluescreen answer :
<div ng-repeat="item in items | limitTo: 10 | limitTo: -5">{{item}}</div>
you might also find a scenario where you need to take N-th item till the last item, this is another way using limitTo:
<div ng-repeat="item in items | limitTo:-(items.length-5)>{{item}}</div>
negative sign will take as much as items.length from last, then minus 5 inside the bracket will skip the first 5 items
There's a tidier way to do it without having to invoke a filter and will behave more like a paginator:
$scope.page = 0;
$scope.items = [ "a", "b", "c", "d", "e", "f", "g" ];
$scope.itemsLimit = 5;
$scope.itemsPaginated = function () {
var currentPageIndex = $scope.page * $scope.itemsLimit;
return $scope.items.slice(
currentPageIndex,
currentPageIndex + $scope.itemsLimit);
};
And just stick that in your view:
<ul>
<li ng-repeat="item in itemsPaginated() | limitTo:itemsLimit">{{item}}</li>
</ul>
Then you can just increment/decrement $scope.page:
$scope.page++;
You can also create your own reusable filter startFrom like so:
myApp.filter('startFrom', function () {
return function (input, start) {
start = +start;
return input.slice(start);
}
});
and then use it in your ng-repeat like so:
ng-repeat="item in items | startFrom: 5 | limitTo:5
That way it is done "in a spirit of AngularJs filters", testable, can have some "extra" logic if needed, etc.
#bluescreen's ans and #Brandon's ans are not equivalent.
for example:
var pageSize = 3;
var page = 2;
var items = [1, 2, 3, 4];
--
item in items | limitTo: page*pageSize | limitTo: -1*pageSize
produce [2, 3, 4]
item in items | slice: (page-1)*pageSize : page*pageSize
produce [4]
For Ionic based projects find the solution below:
mainpage.html:
<ion-view view-title="My Music">
<ion-content>
<ion-list>
<ion-item ng-repeat="track in tracks | limitTo: limit | limitTo: -10 ">
{{track.title}}
</ion-item>
</ion-list>
<div class="list"></div>
<div align="center">
<button class="button button-small button-positive" ng-disabled="currentPage == 0" ng-click="decrementLimit()">
Back
</button>
<button class="button button-small button-energized">
{{currentPage+1}}/{{numberOfPages()}}
</button>
<button class="button button-small button-positive" ng-disabled="currentPage >= data_length/pageSize - 1" ng-click="incrementLimit()">
Next
</button>
</div>
</ion-content>
</ion-view>
controller.js:
var myApp = angular.module('musicApp.controllers', []);
myApp.controller('AppCtrl', function($scope, $http) {
console.log('AppCtrl called');
// $scope.tracks = MusicService.query();
$http.get('api/to/be/called').then(function(result){
$scope.tracks = result.data['results'];
$scope.data_length = $scope.tracks.length;
console.log(result)
// console.log($sco pe.tracks.length)
});
var currentPage = 0;
$scope.pageSize = 10;
$scope.numberOfPages = function(){
return Math.ceil($scope.tracks.length/$scope.pageSize);
}
var limitStep = 10;
$scope.limit = limitStep;
$scope.currentPage = currentPage;
$scope.incrementLimit = function(){
$scope.limit += limitStep;
$scope.currentPage += 1
};
$scope.decrementLimit = function(){
$scope.limit -= limitStep;
$scope.currentPage -= 1
}
});

Resources