I am trying to sort the table data based on the column "Submitted Date" . I have written some code but it doesn't seem to be working. As I am new to Angular JS I need some guidance here. Please help.
code:
Angular js:
vm.sotData = function (column) {
vm.reverseSort = (vm.sortColumn == column) ? !vm.reverseSort : false;
vm.sortColumn = column;
}
Html Code:
<th style="width:13%" ng-click="">Total Amt<span ng-class=""></span></th>
<th style="width:7%" ng-click="">Status<span ng-class=""></span></th>
<th style="width:7%" ng-click="vm.sotData('SubmittedDate')">Submitted Date
<span ng-class="vm.getSortClass('SubmittedDate')"></span>
</th>
The main key of writing sorting functionality is to use
{{ orderBy_expression | orderBy : expression : reverse }}
This returns a sorted Array based on the item. You can change the sorting order by specifying the reverse parameter.
Let's take the example of below array
$scope.friends = [
{sno:1,name:'Yogesh Singh',age:23,gender:'Male'},
{sno:2,name:'Sonarika Bhadoria',age:23,gender:'Female'},
{sno:3,name:'Vishal Sahu',age:24,gender:'Male'},
{sno:4,name:'Sanjay Singh',age:22,gender:'Male'}
];
// column to sort
$scope.column = 'sno';
// sort ordering (Ascending or Descending). Set true for descending
$scope.reverse = false;
// called on header click
$scope.sortColumn = function(col){
$scope.column = col;
if($scope.reverse){
$scope.reverse = false;
$scope.reverseclass = 'arrow-up';
}else{
$scope.reverse = true;
$scope.reverseclass = 'arrow-down';
}
};
// remove and change class
$scope.sortClass = function(col){
if($scope.column == col ){
if($scope.reverse){
return 'arrow-down';
}else{
return 'arrow-up';
}
}else{
return '';
}
};
In html reverse is used for detecting ascending or descending ordering. The default value set to false for ascending.
<table border='1'>
<tr >
<th ng-click='sortColumn("sno")' ng-class='sortClass("sno")'>S.no</th>
<th ng-click='sortColumn("name")' ng-class='sortClass("name")'>Name</th>
<th ng-click='sortColumn("age")' ng-class='sortClass("age")'>Age</th>
<th ng-click='sortColumn("gender")' ng-class='sortClass("gender")'>Gender</th>
</tr>
<tr ng-repeat='friend in friends|orderBy:column:reverse'>
<td width='20%' align='center'>{{friend.sno}}</td>
<td width='35%' align='center'>{{friend.name}}</td>
<td width='20%' align='center'>{{friend.age}}</td>
<td width='25%' align='center'>{{friend.gender}}</td>
</tr>
</table>
<th style="width:13%" ng-click="">Total Amt<span ng-class=""></span></th>
<th style="width:7%" ng-click="">Status<span ng-class=""></span></th>
<th style="width:7%" ng-click="vm.sotData('SubmittedDate')">Submitted Date
<span class="fa" ng-class="{'fa-caret-down':sortType.type=='SubmittedDate' && sortType.order==-1 ,
'fa-caret-up':sortType.type=='SubmittedDate' && sortType.order==1}"> </span></th>
/*for sorting Column*/
$scope.vm.sotData= function (type) {
$scope.sortType.order = $scope.sortType.order === 1 ? -1 : 1;
if ($scope.sortType.order == '1') {
$scope.sortBy = type;
}
else {
$scope.sortBy = '-' + type;
}
};
Try this quick fix.
Code for sorting with Name in Friends
In your HTML,
1st change in table header for which sorting is to be done:-
<th style="width:7%" ng-click="orderByField='name'; reverseSort = !reverseSort"">Friend Name<span ng-class=""></span></th>
2nd change in table row
<tr ng-repeat="friend in Friends | orderBy:orderByField:reverseSort">....</tr>
Related
I'm a beginner at JavaScript and haven't been able to figure this out...
I need to check each row of a table to see if the string "Business Cards" exists in each row. If EVERY row contains this string, I'll proceed with option A, but if even one row doesn't contain the string, I'll stop checking and proceed with option B.
Here is an idea of what the table looks like in HTML (although the number of rows and products in each row will vary, since they're dynamically generated):
<table class="rgMasterTable" border="0" id="ctl00_cphMainContent_dgShippingItems_ctl00" style="width:100%;table-layout:auto;empty-cells:show;">
<thead>
<tr>
<th scope="col" class="rgHeader" style="text-align:center;">Name</th>
<th scope="col" class="rgHeader" style="text-align:center;">No. of Units</th>
</tr>
</thead>
<tbody>
<tr class="rgRow" id="ctl00_cphMainContent_dgShippingItems_ctl00__0" style="text-align:center;">
<td style="width:250px;">
Business Cards - TEST - CA Back
</td>
<td style="width:100px;">
250 Business Cards
</td>
</tr>
<tr class="rgAltRow" id="ctl00_cphMainContent_dgShippingItems_ctl00__1" style="text-align:center;">
<td style="width:250px;">
Business Cards - Joint Venture - TEST
</td>
<td style="width:100px;">
250 Business Cards
</td>
</tr>
</tbody>
</table>
And here's my attempt at the code. I'm trying to make use of the fact that the tr id will always have the index (eg: "ctl00_cphMainContent_dgShippingItems_ctl00__0" for the first row, "ctl00_cphMainContent_dgShippingItems_ctl00__1" for the second, etc), but maybe there's an easier way to do this?
var businessCardItem = 'Business Cards';
var orderItemCount = $('#ctl00_cphMainContent_dgShippingItems_ctl00 tr').length;
var onlyBusinessCards = true;
for (var i = 0; i <= orderItemCount; i++) {
if($('#ctl00_cphMainContent_dgShippingItems_ctl00__' + i).text().indexOf(businessCardItem) >= 0) {
return onlyBusinessCards;
}
else {
onlyBusinessCards = false;
return onlyBusinessCards;
break;
}
}
if (onlyBusinessCards == true) {
//Option A
}
else {
//Option B
}
Any help would be appreciated! Let me know if any more detail or clarification is needed!
Count how many rows contain "Business Cards" and compare to the number of rows:
Note: only count rows within tbody
var table = $("#ctl00_cphMainContent_dgShippingItems_ctl00");
var rows = $("tbody tr",table).length;
var rowsWithBC = $("tbody tr:contains(Business Cards)",table).length;
if( rows == rowsWithBC ) {
// Option A
} else {
// Option B
}
To make sure two arrays are the same in Javascript, this is what I do:
(inserting zeroes where there is missing data in item1)
var viewModel = #Html.Raw(Json.Encode(Model));
var items = viewModel.Date1;
var items2 = viewModel.Date2;
items = items2.map( row =>
//is there a matching row in items?
items.filter( r => r.theString == row.theString).length == 0 ?
//if not, fill with zeros
{theString:0, theCount:0} :
//if there is, return the items' row
items.filter( r => r.theString == row.theString)[0] );
I use that data for the barchart as percentages. I need to display the results in table form with the actual count numbers like this:
<div style="padding-top: 30px">
<table id="table_id" class="display">
<thead>
<tr>
<th>Month</th>
<th>Cancelled</th>
<th>Total</th>
</tr>
</thead>
<tbody>
#using (var e1 = Model.Date1.Reverse().GetEnumerator())
{
using (var e2 = Model.Date2.Reverse().GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
var item1 = e1.Current;
var item2 = e2.Current;
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2.theCount</td>
</tr>
}
}
}
</tbody>
</table>
</div>
Problem is that those arrays haven't been fixed to match eachother, so the data it's displaying is incorrect. The dates (theDate) are not matching the values.
Or could I just use items and items2 from the javascript to make a table?
Something like this should work:
#foreach (var item1 in Model.Date1.Reverse())
{
var item2Count = Model.Date2.Where(i2 => i2.theDate == item1.theDate)
.Select(i2 => i2.theCount)
.FirstOrDefault();
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2Count</td>
</tr>
}
This has the same n² asymptotic complexity as the JavaScript you posted, so if you had a very large number of items there's a chance you'd see slow performance. This could be resolved by creating a lookup of the Date2 values, like so:
#{
var item2CountsByDate = Model.Date2.ToLookup(i => i.theDate, i => i.theCount);
foreach (var item1 in Model.Date1.Reverse())
{
var item2Count = item2CountsByDate[item1.theDate]
.FirstOrDefault();
<tr>
<td>#item1.theDate.Value.ToString("MMMM-yyyy") </td>
<td>#item1.theCount</td>
<td>#item2Count</td>
</tr>
}
}
I am trying to filter the rows of a table to display the results of entered text in the search bar. The code below does the job but for some reason filters the column headings as well.
$('#search').keyup(function () {
var data = this.value.split(" ");
var rows = $(".Info").find("tr").hide();
if(this.value ==""){
rows.show();
return;
}
rows.hide();
rows.filter(function(i,v){
var t = $(this);
for (var d = 0; d < data.length; d++) {
if (t.is(":Contains('" + data[d] + "')")) {
return true;
}
}
return false;
}).show();
});
HTML
<input type = "search" name = "search" id = "search">
<table style ="width:95%" class = "Info">
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
</table>
The user adds rows which is why i haven't written any HTML for it.
Any help would be appreciated. Thanks in advance
http://jsfiddle.net/szjhngwm/
It looks like you need to filter using tbody
<table style ="width:95%" class = "Info">
<thead>
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
<thead>
<tbody>
</tbody>
</table>
var rows = $(".Info tbody tr").hide();
Another way to do this would be to use jQuery's :gt() selector.
The only thing that would change is this line:
var rows = $(".Info").find("tr:gt(0)").hide();
Notice the addition of :gt(0) to your tr.
I cannot properly use my ng-if inside an ng-repeat. I've updated my AngularJS to the newest version (09/27/2014) and I still can not get it to work right. I have code that works fine outside of the ng-repeat and I also have code that works inside ng-repeat fine when I ng-if="vm.detail == false". However ng-if="vm.detail == true" does NOT work. I even have printed the value of vm.detail to the console and it's correct, as it should be. But, the block of code that evaluates ng-if="vm.detail == true" as "true" does NOT execute. It's nuts. Here is my code:
<th>Division</th>
<th>Pool</th>
<th>Subpool</th>
<th ng-click="sort.predicate = 'ExperienceGroup.RenewalGroup.Name'; sort.reverse = !sort.reverse">
RenewalGroup
</th>
<th>MCH</th>
<th ng-click="sort.predicate = 'ContractNumber'; sort.reverse = !sort.reverse">
Contract
</th>
<th ng-click="sort.predicate = 'PlanCode'; sort.reverse = !sort.reverse">
PlanCode
</th>
</tr>
<!--Search By: Mch, Contract Number, Mcp, PlanCode-->
<tr ng-if="vm.detail == true">
<th>Trust</th>
<th>MCH</th>
<th>Contract</th>
<th>Plan Code</th>
<th>Status Date</th>
<th>Status</th>
<th>Effective Date</th>
<th >MCP</th>
<th >Rates</th>
<th>State Availability</th>
</tr>
</thead>
<tbody>
<!--Data for MchNumber, ContractNumber, PlanCode Searches-->
<tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td> {{vm.TrusteeCustNum}}</td>
<td>{{vm.CustomerNumber}}</td>
<td>{{vm.ContractNumber}}</td>
<td>{{vm.PlanCode}}</td>
<td>{{vm.PlanStatusDate}}</td>
<td>{{vm.PlanStatus}}</td>
<td> {{vm.PlanEffectiveDate}}</td>
<td>{{vm.Mcp}}</td> <!--Not yet implemented-->
<td>Rates</td>
<td>State Availability</td>
</tr>
<!--Data for Division, Pool, Subpool, and RenewalGroup Searches-->
<tr ng-repeat="plan in vm.plans
| filter: {MchNumber : planFilter.Mch}
| limitTo: vm.pageSize" ng-if="vm.detail == false">
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.Division.DivisionName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.PoolName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.SubpoolName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.RenewalGroupName}}</td>
<td>{{plan.MchNumber}}</td>
<td>{{plan.PlanDesign.ContractNumber}}</td>
<td>{{plan.PlanDesign.PlanCode}}</td>
<td>{{plan.Mcp}}</td>
</tr>
And the controller:
function getPlans(searchParameters)
{
vm.loadingPlans = true; vm.search = searchParameters;
mchService.searchParameters = searchParameters.MchNumber;
datacontext.getAssignedPlans(searchParameters, vm.pageSize).then(function (plans)
{
vm.plans = plans;
//Compares which columns are being populated for choosing which headings to show
if (vm.search.MchNumber != null
||vm.search.ContractNumber != null
|| vm.search.PlanCode != null)
{
vm.detail = true;
vm.test = !vm.test;
alert("vm.detail is: " + vm.detail)
//vm.detail = !vm.detail;
//If users enter JUST a MCH number then display those results
if (vm.search.ContractNumber == null & vm.search.PlanCode == null)
{
vm.getEntityInformation();
}
}
if (vm.search.DivisionName != null
|| vm.search.PoolName != null
|| vm.search.SubpoolName != null
|| vm.search.RenewalGroupName != null)
{
vm.detail = false;
alert("vm.detail is: " + vm.detail);
// vm.detail = !vm.detail;
}
//Sets values to NULL after every search is performed
vm.search.MchNumber =
vm.search.ContractNumber =
vm.search.PlanCode =
vm.search.DivisionName =
vm.search.PoolName =
vm.search.SubpoolName =
vm.search.RenewalGroupName = null;
}).finally(function () { vm.loadingPlans = false; });
}
Please update that bit.
<tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td>{{vm.TrusteeCustNum}}</td>
<td>{{vm.CustomerNumber}}</td>
<td>{{vm.ContractNumber}}</td>
<td>{{vm.PlanCode}}</td>
<td>{{vm.PlanStatusDate}}</td>
<td>{{vm.PlanStatus}}</td>
<td>{{vm.PlanEffectiveDate}}</td>
<td>{{vm.Mcp}}</td>
<!--Not yet implemented-->
<td>Rates
</td>
<td>State Availability
</td>
</tr>
to :
<tr ng-repeat="info in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td>{{info.TrusteeCustNum}}</td>
<td>{{info.CustomerNumber}}</td>
<td>{{info.ContractNumber}}</td>
<td>{{info.PlanCode}}</td>
<td>{{info.PlanStatusDate}}</td>
<td>{{info.PlanStatus}}</td>
<td>{{info.PlanEffectiveDate}}</td>
<td>{{info.Mcp}}</td>
<!--Not yet implemented-->
<td>Rates
</td>
<td>State Availability
</td>
</tr>
Im trying to find the results in a table column if its set in my function below, most of this was setup by someone else, ive just added some extras into it, my final one is searching 1 column only by name set in the thead but alas in its current edition nothing happens at all :|
thanks for any help
USAGE
<a href='javascript:searchTable("Bob", "table",1,"Name");'>Test</a>
TABLE
<table id="table" class="table">
<thead>
<tr>
<th id="blank"> </th>
<th id="Name">Name</th>
<th id="Dept">Department</th>
<th id="JobTitle">Job Title</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>Bob</td>
<td>IT</td>
<td>IT Support</td>
</tr>
<tr>
<td> </td>
<td>Fred</td>
<td>Finance</td>
<td>Finance Man</td>
</tr>
</tbody>
</table
FUNCTION
function searchTable(inputVal, tablename,starts, column) {
var table = $(tablename);
table.find('tr:not(.header)').each(function (index, row) {
if (column != '') {
//Columnname
var Cells = $(row).find('td').eq(column);
} else {
//AllCells
var Cells = $(row).find('td');
}
if (Cells.length > 0) {
var found = false;
Cells.each(function (index, td) {
if (starts == 1) {
var regExp = new RegExp((starts ? '^' : '') + inputVal, 'i');
} else {
var regExp = new RegExp(inputVal, 'i');
}
if (regExp.test($(td).text())) {
found = true;
return false;
}
});
if (found == true) $(row).show().removeClass('exclude'); else
$(row).hide().addClass('exclude');
}
});
}
As you're passing the column as a string, you need get the corresponding elements index:
var Cells = $(row).find('td:eq(' + $('#' + column).index() + ')');
The above presumes that you're matching based on the id, if you're matching based on the text within the <th> you could use the :contains selector:
$(row).find('td:eq(' + $(table.prop('id') + ' th:contains(' + column + ')').index() + ')');
If you can control and modify the function calls, the best thing to do would be to just pass the elements index directly to the function:
javascript:searchTable("Bob", "table", 1, 1); <-- Would be the "Name" column
That way, you won't have to do any of the above.
By the way, your table selector is incorrect based on your comment, not sure if that's just a typo on your part?
var table = $(tablename);
Should be:
var table = $('#' + tablename);
I am not sure what you are trying to control but you can use this to loop through rows and get the values of cells.
$("#table>tbody>tr").each(function(){
var name= $(this).children("td").eq(1).html();//Name
var department= $(this).children("td").eq(2).html();//Department
var jobTitle= $(this).children("td").eq(2).html();//Job Title
alert(name);
});
http://jsbin.com/uvefud/1/edit
Edit:
You can try this searchTable function.
function searchTable(name,tableName,row,column){
var $Tds= $("#"+tableName+">tbody>tr").eq(row-1).children("td");
if(column=="Name"){
$Tds.eq(1).html(name);
}
else if(column=="Dept"){
$Tds.eq(2).html(name);
}
else if(column=="JobTitle"){
$Tds.eq(3).html(name);
}
}
http://jsfiddle.net/W9zpq/2/
Usage: This will update the name column of 2nd row of tbody to 'Bob'
searchTable("Bob", "table",2,"Name")