AngularJS ordering collection - angularjs

I have a simple inbox table which consists of mails that have mailtext, sender and date attributes. I want this table to be sortable in terms of every one of these attributes when clicked to correspondent table header. Right now I am only trying to order this table in terms of sender attribute. I am using AngularJS 'orderBy' filter but nothing changes in the table. What is wrong with my code?
HTML Code Snippet:
<div class="container">
<h2>Your Inbox</h2><br><br>
<table ng-show="showInboxTable" class="table table-hover">
<thead>
<tr>
<th>Mail</th>
<th ng-click="sortMailsSender()">Sender</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="mail in mails">
<td>{{mail.mailtext}}</td>
<td>{{mail.sender}}</td>
<td>{{mail.date}}</td>
</tr>
</tbody>
</table>
</div>
AngularJS Controller:
$scope.sortMailsSender = function()
{
if ( !$window.sessionStorage.inboxCompare || $window.sessionStorage.inboxCompare == 'gt')
{
console.log('filter straight');
$filter('orderBy')($scope.mails, 'sender', false);
$window.sessionStorage.setItem('inboxCompare', 'lt');
}
else
{
console.log('filter reverse');
$filter('orderBy')($scope.mails, 'sender', true);
$window.sessionStorage.setItem('inboxCompare', 'gt');
}
}

You should assign to your $scope.mails after applying filter and syntax should be
$scope.mails = $filter('orderBy')($scope.mails , 'sender', false);

Related

How to get visible row of table in Angular JS after doing filtration

I am showing list on table using html (table, tr, td) and angularJS. Table also contains filters on columns. Table is populating data properly and filters are working properly using AngularJS.
After doing some filtration, I want to get only visible rows in one of my angularJS's function.
How can I get only the Visible Rows of a Table in angularJS after Few Filters?
Please note that I am not using any checkboxes or radio buttons with data list.
Please see my code below:
var myapp=angular.module("myapp",[]);
myapp.controller('ctrcommodity',['$scope',function($scope) {
$scope.commodity={
allPreferredCommodity: [
{
"commodityId": "2016070011220000141",
"commodityName": "Computer (PC)"
},
{
"commodityId": "2016080011220000004",
"commodityName": "Laptop"
},
{
"commodityId": "2016070011220000032",
"commodityName": "Keyboard"
},
{
"commodityId": "2016080011220000054",
"commodityName": "Mouser"
}
]
};
$scope.getVisibleRows=function()
{
//want to get details of visible rows after filtration
}
}]);
<table border="1" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>Commodity Id</th>
<th>Commodity Name</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="txtcid" id="txtcid" ng-model="s.commodityId"></td>
<td><input type="text" name="txtcname" id="txtcname" ng-model="s.commodityName"></td>
</tr>
<tr ng-repeat="commoditylist in commodity.allPreferredCommodity | filter:s">
<td>{{commoditylist.commodityId}}</td>
<td>{{commoditylist.commodityName}}</td>
</tr>
<tr>
<td align="center" colspan="6" height="50">
<input type="button" value="Show Visible Rows" ng-click="getVisibleRows()">
</td>
</tr>
</tbody>
Do like the follwing . I am changing your function as
$scope.getVisibleRows=function(arrayData,s)
{
console.log(s);
$scope.filerList=$filter('filter')(arrayData,s);
alert( $scope.filerList);
//want to get details of visible rows after filtration
}
and similarly change it is html also like ng-click="getVisibleRows(commodity.allPreferredCommodity,s)"
dont forget to inject filter to controller like myapp.controller('ctrcommodity',['$scope','$filter',function($scope,$filter)

How to use ng-repeat for array in array using single ng-repeat

I got a json of table which has columns and rows as below
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
, Rows:[{Items:[{Value:1},{Value:5},{Value:8},{Value:""}]}
,{Items:[{Value:2},{Value:6},{Value:9},{Value:""}]}
,{Items:[{Value:3},{Value:7},{Value:10},{Value:15}]}]
} //end of table
I want to display Columns.SubHeaders as Sub header row of a table.
Here what I tried, but did not work
<table class="table table-stripped table-bordered">
<thead>
<tr>
<th ng-repeat="col in table.Columns" colspan="{{col.SubHeaders.length}}">{{col.Header}}</th>
</tr>
<tr>
<td class="center text-black" ng-repeat="head in table.Columns[0].SubHeaders">{{head}}</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in table.Rows">
<td ng-repeat="item in row.Items">
{{item.Value}}
</td>
</tr>
</tbody>
</table>
I used head in table.Columns[0].SubHeaders just to show it is working for hard-coded index value.
How can I achieve this using single ng-repeat? I can use two ng-repeats but it will lead to unnecessary html markup.
Here is the complete fiddle
I created this fiddler (forked from yours):
https://jsfiddle.net/b50hvzef/1/
The idea is to join the subheaders as they are they actual columns:
<td class="center text-black" ng-repeat="head in subHeaders">{{head}}</td>
and the code looks like this:
var app = angular.module("app",[]);
app.controller("MyController", function ($scope, $http) {
$scope.table = {
Columns: [{Header:"22-Jul-15",SubHeaders: ["10:33 AM"]}
, {Header:"21-Jul-15",SubHeaders: ["03:40 AM"]}
, {Header:"17-Jul-15",SubHeaders: ["01:05 PM", "12:06 PM"]}]
,Rows:[{Items:[{Value:1},{Value:5},{Value:8}]}
,{Items:[{Value:2},{Value:6},{Value:9}]}
,{Items:[{Value:3},{Value:7},{Value:10}]}]
};
var subHeaders = [];
$scope.table.Columns.forEach(function(col) {
col.SubHeaders.forEach(function(subHeader) {
subHeaders.push(subHeader);
});
});
$scope.subHeaders = subHeaders;
});
Note that there is still a mismatch between columns and data. But it's up to you how to solve it.
Hope this helps.

Populate and update a table with data from a different table

My site allows for a user to search for a term which returns a table of associated songs. When the "Add Track" button in a particular row is clicked after the search, the respective track name and trackId are added to the table "playlist". The problem I am having is that once "Add Track" is clicked within a different row, the data from that row is not added to the "playlist" table, but rather it just replaces the previous information. I need to be able to generate a cumulative table. Any help would be great and thanks in advance!
<body ng-app>
<body ng-app>
<div ng-controller="iTunesController">
{{ error }}
<form name="search" ng-submit="searchiTunes(artist)">
<input type="search" required placeholder="Artist or Song" ng-model="artist"/>
<input type="submit" value="Search"/>
</form>
<div class="element"></div>
<table id="SongInfo" ng-show="songs">
<thead>
<tr>
<th>Album Artwork</th>
<th>Track</th>
<th></th>
<th>Track Id</th>
<th>Preview</th>
<th>Track Info</th>
<th>Track Price</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="song in songs">
<td><img ng-src="{{song.artworkUrl60}}"
alt="{{song.collectionName}}"/>
</td>
<td>{{song.trackName}}</td>
<td><button ng-click="handleAdd(song)">Add Track</button></td>
<td>{{song.trackId}}</td>
<td>Play</td>
<td>View Track Info</td>
<td>{{song.trackPrice}}</td>
</tr>
</tbody>
</table>
<table id="playlist">
<thead>
<tr>
<th>Playlist</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="song in addedtracks">
<td>{{song.trackName}}</td>
<td>{{song.trackId}}</td>
</tr>
</tbody>
</table>
</div>
</body>
itunes_controller.js
var iTunesController = function($scope, $http){
$scope.searchiTunes = function(artist){
$http.jsonp('http://itunes.apple.com/search', {
params: {
'callback': 'JSON_CALLBACK',
'term': artist,
limit: 5,
}
}).then(onSearchComplete, onError)
}
$scope.handleAdd = function(song) {
// this song object has all the data you need
console.log("handle add ", song)
$scope.addedtracks = [{song:'trackName', song:'trackID'}]
$scope.addedtracks.push(song)
}
var onSearchComplete = function(response){
$scope.data = response.data
$scope.songs = response.data.results
}
var onError = function(reason){
$scope.error = reason
}
}
I saw some issues with your code. First the code below
$scope.addedtracks = [{song:'trackName', song:'trackID'}]
$scope.addedtracks.push(song)
Acording to your html, you are passing the song object to the handleAdd. So just remove the first line from code above. After that step, declare addedtracks array before handleAdd like below
$scope.addedtracks = [];
Modify the ng-repeat for the playlist like below:
<tr ng-repeat="song in addedtracks track by $index">
<td>{{song.trackName}}</td>
<td>{{song.trackId}}</td>
</tr>
And that's it. Note that I used track by $index because ngRepeat does not allow duplicate items in arrays. For more information read Tracking and Duplicates section.
Finally this is working plunker

$broadcast appending dynamic data (rows) at wrong place using ng-scrollbar

I have used ng-scrollbar like this :
<tbody ng-scrollbar rebuild-on="rebuild:me" class="scrollme" id ="tempID">
and in ng table , included the broadcast
getData: function($defer, params) {
$scope.$broadcast('rebuild:me');
Now the ng-repeat is populating the tr in thead after first th instead of appending/loading it correctly in tbody
how to correctly display my results?
did you try this
getData: function($defer, params) {
$defer.promise.then(function(){
$scope.$broadcast('rebuild:me');
};
...
right after updating table
Edit 1
tbody is replacing by div and thus how layout became messy,check plunk
Edit 2
Here some workaround about this,need some editing,i will update later
Edit 3(final)
Finally get working example of ngtable and ngscrollbar together,but its not most beautiful solution but still:
1.
you need separate thead from rest of table into new table which locate right above main table
<thead>
<tr >
<th class="sortable" ng-class="{
'nameasc':'sort-asc' ,
'namedesc':'sort-desc'
}[sortTableParam]"
ng-click="SortBy('name')">
<div>name</div>
</th>
<th class="text-center sortable" ng-class="{
'ageasc':'sort-asc' ,
'agedesc':'sort-desc'
}[sortTableParam]"
ng-click="SortBy('age')">
<div>Age</div>
</th>
</tr>
</thead>
</table>
2.
second - hide thead in main table and wrap table into div tag,which will be processing by directive:
<div style="height:300px" ng-scrollbar rebuild-on="rebuild:me" class="scrollme">
<table ng-table="tableParams" show-filter="true" class="table">
<thead><tr><th ></th><th ></th></tr></thead>
<tbody >
<tr ng-repeat="user in $data">
<td data-title="'Name'" filter="{ 'name': 'text' }" sortable="name">
{{user.name}}
</td>
<td data-title="'Age'" sortable="age">
{{user.age}}
</td>
</tr>
</tbody>
</table>
</div>
3.
Clicks from header will trigger reloading data with sorting option,by binding SortBy function
var sorting = $scope.tableParams.$params.sorting;
var dir = sorting != null ? (sorting[param.toString()] == 'asc' ? 'desc' : 'asc') : 'asc';
var sort={};
sort[param.toString()]=dir;
$scope.tableParams.sorting(sort);
//edit classes in header for rows imaging(check plunk)
updatesorting(param);
};

selecting object in an array in angularjs

I am trying to make it possible so that by clicking on a 'client' in one of the following <td>s I can select that specific object from the 'clients' array and switch to a new view. I assume I would want to start with an ng-click, just not sure how to go about it. Also I will not be using any jquery.
<div ng-init="clients = [
{firstname:'Buster', lastname:'Bluth', tagid:'4134'},
{firstname:'John', lastname:'McClane', tagid:'9845'},
{firstname:'Mister', lastname:'Spock', tagid:'0905'}
]"></div>
<div>
<div>Clients</div>
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>I-Number</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in clients">
<td>{{client.firstname}}</td>
<td>{{client.lastname}}</td>
<td>{{client.inumber}}</td>
</tr>
</tbody>
</table>
</div>
ng-click is the correct approach. You can get the selected object like this
<tr ng-repeat="client in clients" ng-click="redirect(client)">
Create a controller with the method:
function ctrl($scope, $location){
$scope.redirect = function(client){
console.log(client);
$location.url('/someurl'); //this is the routing defined in the $routingProvider, you need to implement it.
}
}
Make sure you refer to the class in the outer div containing the select like this
<div ng-controller='ctrl'>

Resources