Date format in AngularJS and Symfony - angularjs

I'm trying to display a date in the format "dd/mm/yyyy" in AngularJS. I'm retrieving data from database with symfony2.
When I inspect my scope in the browser it looks like I have a valid date object:
CreationDate : Object { date="2014-05-15 00:00:00", timezone_type=3, timezone="Europe/Paris"}
Here is what i have tried:
{{res.creationDate | date:'dd/MM/yyyy' }}
which prints this:
{"date":"2014-08-12 00:00:00","timezone_type":3,"timezone":"Europe/Paris"}
and quite logically:
{{res.creationDate.date }} --> 2014-05-15 00:00:00`
I'd like to have "15-05-2014"
---- EDIT
My controller:
public function ViewAction()
{
$repository = $this->getDoctrine()->getManager()->getRepository('AcmeMyBundle:MyEntity');
$list = $repository->getArray();
$list = json_encode($list);
return $this->render('AcmeMyBundle:Search:search.html.twig', array('list' => $list) );
}
My custom getArray function in repo:
public function getArray()
{
$query = $this->createQueryBuilder('s');
return $query->getQuery()->getArrayResult();
}
My template looks something like this:
<div class="col-md-10 col-md-offset-1" ng-init= "result= {{list}}">
<ul class="list-group">
<div ng-repeat="res in result | filter:searchText | filter:nom | filter :prenom | limitTo:50 " >
<li class="list-group-item">Date {% verbatim %} {{res.creationDate | date:'dd/MM/yyyy' }} {% endverbatim %}</li>
</div>
</ul>
creationDate is a "date" format, in a SQL Database. In phpmyadmin it prints 'dd-mm-yyy'

If you can alter the date object from date="2014-05-15 00:00:00" to date="2014-05-15T00:00:00" it should work.
Working example at this JSFiddle
You might also want to take a look on this post about JSON date format

If you try to format the date directly?
{{res.creationDate.date | date:'dd/MM/yyyy' }}

If anyone wondering..
Here is a trick i came up with for my problem
view
{{ mySplit(res.symfonyDateObject.date, 0) | date:'dd-MM-yyyy' }}
controller
app.controller('SearchController', function($scope)
{
$scope.mySplit = function(string, nb) {
$scope.array = string.split(' ');
return $scope.array[nb];
}
});
tldr i split the string in half, remove the hh/mm/ss and then angular format works

You can use javascript Date object to convert your timestamp(2014-05-15 00:00:00) into a time string(1400092200000) and apply angular filter
Working example at this JSFiddle

Related

Is Angular ng-repeat filter result accessible?

I am successfully using ng-repeat and its filter and orderBy functions
<div ng-repeat="center in centers | filter: subjectName | orderBy:[\'name\',\'parent']">'
However when user decides to print/download the "centers" filtered and ordered by angular, the printing method fails because it knows only the original unsorted unfilterd array. Is there a way to capture the object resulted by the filtered/orderBy angular methods so I could use it directly in my printing method?
<div ng-repeat="center in centers | filter: subjectName | orderBy:[\'name\',\'parent']">'
'<span>{{center.name}</span>'+
</div>
....
// what I have so far
<li><a ng-click="print(centers)"><span class="glyphicon glyphicon-print"></span> Print All </a></li>
...
// what I would like to have
...
<li><a ng-click="print(filteredOrderedObject)"><span class="glyphicon glyphicon-print"></span> Print All </a></li>
...
// what I have
scope.print = function(ocw) {
//printing
}
// what I would like to have
scope.print = function(filteredOrderedObject) {
//printing
}
You can use the $filter service directly in your code. Something like this.
var filtered = $filter('filter')(centers, subjectName);
filtered = $filter('orderBy')(filtered, ['name', 'parent']);
https://docs.angularjs.org/api/ng/filter/filter
You can use $eval to evaluate expression in controller.
Following is the syntax
$scope.centers = $scope.$eval("center in centers | filter: subjectName | orderBy:[\'name\',\'parent']");

how to get first object in ng-repeat

I am displaying a contact's information using ng-repeat. Each contact has details. I am trying to grab the first object in the list. Here is my code:
<div ng-repeat="contact in contactList() | filter:{type: 'direct'} | filter:{duration: '1 year'} | orderBy: 'Date'">
<div ng-click="selectedContact(contact)">
<div>{{contact.name}}</div>
<div>{{contact.type}}</div>
</div>
</div>
contactList() is a function calling services:
$scope.contactList = function () {
return ContactService.getContactList();
};
How do I get the first contact object in the ng-repeat? I want to save that object for other windows.
You can set a new scope property to be a result of filtering and ordering. Note, how you group filters with ():
<div ng-repeat="contact in contacts = (contactList() | filter:{type: 'direct'} | filter:{duration:'1 year'} | orderBy: 'Date')">
<div ng-click="selectedContact(contact)">
<div>{{contact.name}}</div>
<div>{{contact.type}}</div>
</div>
</div>
Then to get the first from this list it will be just [0]:
{{ contacts[0] }}
I'm guessing you don't just want to display the one record and you also want the first record from the array after your filters/ordering are applied. If that is the case I would recommend simply adding an alias after your last condition and then you can reference that alias in your controller.
here is a fiddle to help show:
http://jsfiddle.net/nbavesuo/
I would suggest you not call the function in the ng-repeat instead reference an array that has already been called:
<div ng-repeat="contact in contactList|
filter:{type: 'direct'}| filter:{duration:'1 year'}|
orderBy: 'Date' as filteredArray">
....
Then in your controller:
$scope.contactList = ContactService.getContactList();
$scope.selectedContact = function(contact){
console.log(contact);
console.log($scope.filteredArray[0]);
}
You'll see that $scope.filteredArray[0] will have the 1st element in the sorted array.
You could use 'track by $index' and use an 'ng-if' to determine when it's the first object:
<div ng-repeat="contact in contactList()| filter:{type: 'direct'}| filter:{duration:'1 year'| orderBy: 'Date' | track by $index"
ng-if="$index == 0"
ng-init="someMethod()">
<div ng-click="selectedContact(contact)">
<div> {{contact.name}}</div>
<div>{{contact.type}}</div>
</div>
</div>
You could then have a function 'someMethod()' in your controller that saves the object to a window object or to local storage:
function someMethod(key, object) {
window.localStorage.setItem(key, object);
}
I have written an object to use for this exact thing in fact if you want to use it:
var LocalStorageManager = {
setValue: function(key, value) {
window.localStorage.setItem(key, JSON.stringify(value));
},
getValue: function(key) {
try {
return JSON.parse(window.localStorage.getItem(key));
} catch (e) {
}
}
};
So, you would use it with your stuff like this, in your 'someMethod()':
function someMethod(key, object) {
LocalStorageManager.setValue(key, object);
}
Then, to get the object, you would just use the 'getValue' method calling the 'key' that you gave the object.

How to search on the displayed data and not the backing data using Angular

I am using ng-repeat to create a table of data:
<div class="divTable" ng-repeat="expense in exp.expenses | filter:exp.query">
<div>{{expense.amount | ldCurrency : true}}</div>
...
</div>
A couple of the cells that I am creating are being modified through an Angular filter. In the example above, I am changing the integer to a currency. So the original 4 is changed to $4.00. When I filter the entire list with my exp.query, it does not modify the exp.query search term through the ldCurrency.
The means that if I search on $4, it will not find it, because the backing data is 4, even though $4 is on the page.
I know this is confusing, with the two types of filters that I am talking about here.
How can I search on the data that is being shown on the page and not on the backing data?
You have to create you own filter. What you want to do to is a bad idea, because you are melding the view layer and the model layer.
A example of a filter.
The html:
<input ng-model="query" ng-trim="true">
<span>Finding: </span><span>{{ query }}</span>
<div ng-repeat="product in products | productsFilter: query">
<strong>{{ $index }}</strong>
<span>{{ product.name }}</span>
<span>{{ product.price | currency: '$'}}</span>
</div>
The custom filter:
.filter('productsFilter', [function () {
// Private function: It removes the dollar sign.
var clearQuery = function (dirtyQuery) {
var index = dirtyQuery.indexOf('$');
if (index === -1)
return dirtyQuery;
return dirtyQuery.substr(index+1, dirtyQuery.length-index)
};
// The Custom filter
return function (products, query) {
if (query === '') return products;
var newProducts = [];
angular.forEach(products, function (product) {
var cleanQuery = clearQuery(query);
var strProductPrice = '' + product.price;
var index = strProductPrice.indexOf(cleanQuery);
if (index !== -1) {
newProducts.push(product);
}
});
return newProducts;
};
}]);
The key is in the angular.forEach. There I decide if the product will belong to the new filtered collection. Here you can do the match you want.
You can find the complete example in full plucker example and see a lot of filters in the a8m's angular-filter

OrderBy gets ignored

I have the following ng-repeat:
<div ng-repeat="location in truckDetail.locations track by $index | orderBy:location.startDate" class="locationLoopRow">
<span class="rowEdit"><i ng-click="location.editMode=!location.editMode" class="fa {{location.editMode?'fa-ban':'fa-pencil'}}"></i></span>
<span class="rowDate">{{location.startDate|date:'dd.MM.yyyy'}}</span>
<span class="rowDate">{{location.endDate|date:'dd.MM.yyyy'}}</span>
<span class="rowLocation">{{location.name}}</span>
</div>
The orderBy seems to be ignored completely as seen in the screenshot.
I also tried to solve this by using a sort-function:
| orderBy:dateOrderBy(location.startDate)
$scope.dateOrderBy=function(date) {
return date.getFullYear()+'/'+date.getMonth()+'/'+date.getDate();
},
In debug mode I can see that this message returns values like '2015/4/29'. Still: The list isn't sorted at all
You don't need to call dateOrderBy function in ng-repeat, you only need to specify it's name:
| orderBy:dateOrderBy
Then in your controller your sort function will receive the location object:
$scope.dateOrderBy = function(location) {
return location.startDate;
};
Example in plunkr.
UPD: this one should work as well:
| orderBy:'startDate'
UPD 2: track by $index should always go in the end of expression:
location in truckDetail.locations | orderBy:'startDate' track by $index

Angular, markup binding variable as index of another variable

I would like to know if it is possible with AngularJs to render an array element by using another scrop variable as the index like :
{{array[{{index}}]}}.
For example I am trying to achieve this (note the nested {{}} ) :
<ion-item collection-repeat="item in prodataSelect" collection-item-height="52">
<img class="imageoptionsbrand" src={{imagesUrls[{{item.brand | lowercase | nospace}}+'.png']}} />
</ion-item>
Both prodataSelect and imagesUrls are in the scope of the view in controller.js :
angular.module('SnowBoard.controllers', ['SnowBoard.services'])
.controller('ComputeCtrl', function($scope, $ionicPopup, $timeout, sessionService) {
$scope.prodataSelect = [];
prodata = sessionService.get('prodata');
$scope.prodataSelect = prodata;
$scope.imagesUrls = sessionService.get('imagesUrls');
})
The array imagesUrls is as follows:
Object {
byrne.png: "./img/brands/byrne.png"
byrne.pngtype: "brand"
owenwright.png: "./img/pros/owenwright.png"
owenwright.pngtype: "pro"
BX2.png: "./img/boards/BX2.png"
BX2.pngtype: "board"
BlakBox2.jpg: "./img/boards/BlakBox2.jpg"
BlakBox2.jpgtype: "board"
CI-girabbit.png: "./img/boards/CI-girabbit.png"
CI-girabbit.pngtype: "board"
...
Thanks
Yes you can.
Try removing the curly braces # item and maybe also remove the .png or add it after the retrieved image name?
<img class="imageoptionsbrand" ng-src={{imagesUrls[{{item.brand | lowercase | nospace}}]+'.png']}} />
to
<img class="imageoptionsbrand" ng-src="{{imagesUrls[(item.brand | lowercase | nospace) + '.png']}}"] />
To show you that it is possible check this quick example that I've put together
plunkr

Resources