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
Related
I have a function that checks if a value is true or false and a function that changes value.
checkValue(item){
if item.exists{
return 1;
}
else {
return 0;
}
}
and in my html I have a ng-repeat that orders by this function:
<span ng-repeat="item in items | orderBy: checkValue"></span>
<a ng-click="changeItemExists(selectedItem)">
now when item.exists change the orderBy does not work again and order the spans again.
How can I make the orderBy to watch for any changes in the item.exsist?
You don't need the checkValue function.
Just do:
<span ng-repeat="item in items | orderBy: 'exists'"></span>
Then the orderBy will refresh the order automatic on any changes of the 'exists' property.
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']");
I have the following ng-repeat:
<td data-ng-repeat="scheduleAbsenceDayContainer in scheduleAbsenceMonthContainer.scheduleAbsenceDayContainers track by $index
and scheduleAbsenceDayContainer can contain an array of scheduleIntervalContainers:
My question now would be if there is any possibility to filter all scheduleIntervalContainers with a special containerType value.
My filter- name is is calles vm.absenceType:
<select name="typeSelection" id="typeSelection" data-ng-model="vm.absenceType"
I have tried this one withour success, because I don't know how to gete any or when not possible only the first one:
<td data-ng-repeat="scheduleAbsenceDayContainer in scheduleAbsenceMonthContainer.scheduleAbsenceDayContainers track by $index | filter: {scheduleIntervalContainers(any or - when not possible than only first): {containerType.value: vm.absenceType}}"
You will need to use nested ng-repeat. Then you can use a custom filter to filter the scheduleIntervalContainers using your vm.absenceType model variable.
<div data-ng-repeat="scheduleAbsenceDayContainer in scheduleAbsenceMonthContainer.scheduleAbsenceDayContainers track by $index">
<div data-ng-repeat="scheduleIntervalContainer in scheduleAbsenceDayContainer.scheduleIntervalContainers | filter: check" >
</div>
</div>
Custom filter function
$scope.check = function(a){
if (angular.equals(a.containerType,$scope.vm.absenceType))
return true;
else
return false;
}
You could also implement this without a custom filter function by renaming your filter model (if it's possible) to vm.containerType and giving filter : vm in the nested 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.
I am trying to use angular orderBy to order multiple fields, but i get syntax error as:
Syntax error, unrecognized expression: div[ng-repeat='r in
vm.GetRequests() | filter: vm.SearchText |
orderBy:['LastName','FirstName']']
It seems there appears additional sign ']', but i do not have it in html
The html looks like:
<div ng-repeat="r in vm.GetRequests() | filter: vm.SearchText |orderBy:'RequestedOn'| orderBy:['LastName','FirstName']">
{{r.LastName}} : {{r.FirstName}}
</div>
the function GetRequests() returns a array of object as following:
[{FirstName:"Test1", LastName:"First"},{FirstName:"Test2",LastName:"Second"},{FirstName:"Test3",LastName:"Third"}]
Can anyone help me for the problem?
Changing HTM - remove orderBy: 'RequestedOn'
<div ng-repeat="r in vm.GetRequests() | filter: vm.SearchText | orderBy:['LastName','FirstName']">
{{r.LastName}} : {{r.FirstName}}
</div>
but i still get syntax error:
Uncaught Error: Syntax error, unrecognized expression: div[ng-repeat='r in vm.GetRequests() | filter: vm.SearchText | orderBy:['LastName','FirstName']']
UPDATE
The syntax seems comes from a browserlink, because the order works goed when i get the error.
And recommend to put all order property in a array
Thanks a lot for the inputs all of you, especially thanks for RishiPrakash :)
I think that filter only works on arrays and doesn't evaluate functions.
I would assign the request to a scope variable in the controller:
js:
$scope.requests = vm.GetRequests();
html:
<div ng-repeat="r in requests | filter: vm.SearchText | orderBy:['RequestedOn','LastName','FirstName']"> {{r.FirstName }}, {{r.LastName}} </div>
note: I don't think there's a problem with the way you sort your array, although I prefer combining them in one orderBy expression as Rishi Prakash suggested.
try <div ng-repeat="r in vm.GetRequests() | filter: vm.SearchText() | orderBy:['RequestedOn','LastName','FirstName']">
filter:vm.SearhText must be a function so () in end of it.