Sorting array in asc desc - angularjs

I am new to angularjs here is my code i want to get data from url and also sort it by dynamically by selecting an item from select element but could't get the required result please help me out
Html
<tr ng-repeat="x in names | orderBy: sortBy ">
<td><a ng-href="{{ x.data.url}}">{{x.data.title}}</a>
</td>
<td>{{x.data.score}}</td>
</tr>
Code
$scope.$watch(function () {
return $scope.sortExpression
}, function (newSort) {
$scope.sortBy = 'data.' + $scope.sortExpression
})
$http.get("https://www.reddit.com/r/worldnews/new.json")
.success(function (response) {
$scope.names = response.data.children
})
Fiddle

https://jsfiddle.net/rr6q0umb/1/
Add input for the direction
<label><input type="checkbox" ng-model="direction">Reverse</label>
Add to your orderBy filter the direction value (true for reverse)
<tr ng-repeat="x in names | orderBy:sortBy:direction">

Related

AngularJS table orderBy checkbox

I want to sort a table when a checkbox is clicked and be able to filter the table also. The code below has been fixed and works now....
HTML
<table>
<tr ng-repeat="x in myArray | filter : name | orderBy : sortOrder">
<td>{{ x.name }}</td>
<td>{{ x.age }}</td>
</tr>
</table>
<input type="checkbox" ng-model="sortByName" ng-change="setSortOrder()">
<input type="text" ng-model="name">
AngularJS
app.controller("myController", function($scope, $http)
{
$scope.filterString = '';
$scope.sortByName = false;
$scope.sortOrder = '';
$scope.setSortOrder = function()
{
if($scope.sortByName)
{
$scope.sortOrder = 'name';
}
else
{
$scope.sortOrder = '';
}
}
You are missing telling your checkbox to call the controller method that selects the sort criteria when its checked status changes. You can do this by using the ngChange directive. Try the following:
<input type="checkbox" ng-model="sortByName" ng-change="setSortOrder()">

Applying sort and filter to an Angular table

I downloaded an Angular demo app to learn and work my way through Angular basics. I am having issue with applying a filter and sort to a data table. I made it by referring some examples and not sure if it is correct.
My table is :
<div class="widget-content" ng-controller="getAllBenchersController">
<table ng-table="talentPoolList" show-filter="true" class="table table-striped table-bordered">
<tr ng-repeat="employee in data | filter: testFilter">
<td data-title="'#'">{{$index + 1}}</td>
<td data-title="'Employee ID'" sortable="'empno'" filter="{ 'empno': 'text' }">
{{employee.employee.employeeNo}}
</td>
<td data-title="'First Name'" sortable="'employee.employee.firstName'" filter="{ 'employee.employee.firstName': 'text' }">
{{employee.employee.firstName}}
</td>
</tr>
</table>
</div>
Controller :
myApp.controller('getAllBenchersController', ['$scope', 'employeeTalentPoolServices', function ($scope, employeeTalentPoolServices) {
employeeTalentPoolServices.getAllBenchers().then(function (result) {
$scope.data = result.data;
$scope.testFilter = function (item) {
return (item.state.state.toLowerCase() === 'available' || item.state.state.toLowerCase() === 'blocked');
}
});
I have no clue how it works. Can anyone explain and provide a solution to fix this issue?
Thanks in advance
So to explain your demo example I've created a similar example to make you understand what's happening in your question.
We have a employees data with different statuses so when I want to display the list of employees I just want show 'fair' and 'good' so I've written a filter function passed to filter directive to tell what items should be displayed from the list.
If you observe the function it takes every item from list and checks for status to match the desired statuses for displaying.
Check out the demo for the same, hope this gives you a clear understanding on what's happening in your Demo app.
var app = angular.module('app',[]);
app.controller('getAllBenchersController',function($scope,$filter){
$scope.data = {employee:[
{'no':1,'name':'max','status':'bad'},
{'no':2,'name':'fox','status':'good'},
{'no':3,'name':'juno','status':'bad'},
{'no':4,'name':'pet','status':'fair'},
{'no':5,'name':'xyz','status':'good'},
{'no':6,'name':'shit','status':'bad'},
{'no':7,'name':'doggy','status':'fair'},
{'no':8,'name':'hmmm','status':'bad'}
]}
//this test filter is a function which allows me to decide which data should be displayed in this case I've used 'fair' & 'good' status employees to be displayed...
$scope.testFilter = function (item) {
return (item.status.toLowerCase() === 'good' || item.status.toLowerCase() === 'fair');
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" class="widget-content" ng-controller="getAllBenchersController">
<table>
<tr ng-repeat="emp in data.employee | filter: testFilter">
<td>{{$index+1}} </td>
<td> {{emp.no}}</td>
<td>{{emp.name}} </td>
</tr>
</table>
</div>

In table, get selected row id in array

In table every row assosiated with checkbox and have option to check all row.
I want to get selected rows id of table in array.
Here is plunker code.
HTML:
<table id="datatable-buttons" class="table table-striped table-bordered">
<thead>
<th>
<input type="checkbox" ng-model="selectRowId" ng-click="selectedAll()">
</th>
</thead>
<tbody ng-init="get_product()">
<!--step 6-->
<tr ng-repeat="product in filtered = (pagedItems| filter:search | orderBy : predicate :reverse) | startFrom:currentPage * entryLimit | limitTo:entryLimit | findobj:multipleVlaue | searchFor:searchString"> <!-- searchFor:searchString -->
<td>
<input type="checkbox" ng-model="selctedIds[product.id]" ng-checked="product.deleted">
</td>
</tr>
</tbody>
</table>
Controller:
$scope.selectedAll = function () {
$scope.pagedItems.forEach(function (product) {
if ($scope.selectRowId) {
product.deleted = true;
} else {
product.deleted = false;
}
});
}
If you want something scalable that accommodates things like complex filtering, pagination, etc. then I suggest you write an angular property to each object. So for the checkbox we'd want to toggle this boolean value like so:
<input type="checkbox" ng-model="item.$selected"/>
For your toggle all/none, you'll need to tap a controller function:
$scope.toggleAll = function(bSelect){
itemArray.forEach( function(item){ item.$selected = bSelect; })
}
The reason I suggest prepending your selected value with a $ like $selected is that any HTTP calls you make with the objects, Angular will strip any $property before converting to JSON, just in case your backend has issue.
I'd recommend using a filter to pull the IDs:
<div>{{ itemArray | getSelIds }}</div>
and the filter
.filter( 'geSeltIds', function(){
return function(items){
//if you happen to use lodash
return _.chain(items).filter({$selected:true}).map('id').value()
//manual
ids = []
items.forEach(function(item){
if(item.$selected)
ids.push(item.id)
})
return ids
}
})
This filter is cleaner:
.filter( function (item) {
return item.$selected;
}).map(function (item) { return item.id });

Stuck on angularjs ng-checked

I'm trying to implement that when a user clicks a check box it displays all products in the ng-repeat with a quantity of 0. Else when the check box is not check all items display. Currently I was able to get half the functionality.
Check box :
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" ng-checked="vm.OnHandQty()">
Table
<tr ng-repeat="item in vm.items | filter :search">
<td ng-bind="item.itemNo"> </td>
<td ng-bind="item.description"></td>
<td ng-bind="(item.listPrice | currency)"></td>
<td ng-bind="item.onHandQty" ng-model="quantity"></td>
</tr>
Controller
vm.OnHandQty = function () {
$scope.search = {};
vm.items.forEach(i => {
if (i.onHandQty == 2) {
console.log(i);
$scope.search = i;
return true;
}
else {
$scope.search =i;
return false;
}
});
}
I would propose changing the implementation of your checkbox and controller:
Checkbox
<input type="checkbox" ng-model="vm.checked" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch">
- Here, we use "ng-model" instead of "ng-checked" and "vm.checked" is a variable that you define as the ng-model for your checkbox.
Controller
$scope.search = function(item) {
return ($scope.vm.checked) ? item.onHandQuantity === 0: true;
};
- Here, we define the "ng-repeat" filter that you are using in your table.
Try this instead:
<tr ng-repeat="item in vm.items" ng-show="onoffswitch==true && item.onHandQty != 0? false : true">
<td ng-bind="item.itemNo"> </td>
<td ng-bind="item.description"></td>
<td ng-bind="(item.listPrice | currency)"></td>
<td ng-bind="item.onHandQty" ng-model="quantity"></td>
</tr>
This will only show the row if onoffswitch is true and if the onHandQty is zero, otherwise it will show the row. So the row will be hidden if onoffswitch is true and onHandQty is not zero.
You can make use of ng-change and ng-model.
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" ng-model="vm.checked" ng-change="checkBoxChange(vm.checked)">
Then, from you checkBoxChange function, apply your business logic:
vm.checkBoxChange = function(checked){
if(checked){
//Do something
}else{
//Something else
}
};

How to change $index for two ngRepeats with same input but different filters?

I've simulated my problem here.
Looking into this html, you can see that I am doing two ng-repeats with the same array as input, but different filters to each one:
<div ng-app='Lists'>
<div ng-controller='listsController'>
<table>
<tbody>
<tr ng-repeat='item in listValues | filter : xxx track by $index' ng-click="update($index)">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<table>
<tbody>
<tr ng-repeat='item in listValues | filter : yyy track by $index' ng-click="update($index)">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<div>{{updateIndex}}</div>
</div>
</div>
And my js code:
var appModule = angular.module('Lists', []);
appModule.controller('listsController', function($scope) {
$scope.listValues = [
{'ref' : '1', 'others' : 'abc..'},
{'ref' : '2', 'others' : 'def..'},
{'ref' : '1', 'others' : 'ghi..'},
{'ref' : '2', 'others' : 'jkl..'}
];
$scope.xxx = function(a){
return a.ref == 1;
};
$scope.yyy = function(a){
return a.ref == 2;
};
$scope.update = function(i) {
$scope.updateIndex = i;
};
$scope.updateIndex = "none";
});
The problem I'm stuck is that the update(index) function needs to change the object in the correct index of the listValues array. But as you can see clicking in the object of the second table gives me the $index of the first table.
How to work around this situation? Thanks in advance.
Using the $index is doomed to fail, even if you iterate once. $index is the index of the current item in the filtered array. And that index is different from the index of the same element in the original, non-filtered array.
If you want to modify an item on click, don't pass its index as argument. Pass the item itself:
ng-click="update(item)"
Instead of filters use ng-if which allows you to track items by index.Index will give exact click even list has duplicate items
<body>
<div ng-app='Lists'>
<div ng-controller='listsController'>
<table>
<tbody>
<tr ng-repeat="item in listValues track by $index" ng-click="update($index)" ng-if="xxx(item)=='1'">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<table>
<tbody>
<tr ng-repeat='item in listValues track by $index' ng-click="update($index)" ng-if="item.ref=='2'">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<div>{{updateIndex}}</div>
</div>
</div>
</body>

Resources