Ng-repeat is not working as expected in html table? - javascript

Why doesn't this simple table structure work in angularjs? None of the rows gets populated with the data. If I replace span with tr, it works fine but my third column of Percent doesn't fit in well.
<table class="table table-hover">
<tbody>
<tr>
<th>Grade</th>
<th>Point</th>
<th>Percent</th>
</tr>
<tr>
<span ng-repeat="gdata in gradepoints">
<td ng-repeat="(grade, gp) in gdata"> {{grade | uppercase}} </td>
<td ng-repeat="(grade, gp) in gdata"> {{gp}} </td>
</span>
<span ng-repeat="pdata in percents">
<td ng-repeat="(grade, perc) in pdata"> {{perc}} </td>
</span>
</tr>
</tbody>
</table>

Try this:
<tr ng-repeat="gdata in gradepoints">
<td>{{gdata.grade | uppercase}}</td>
<td>{{gdata.gp}}</td>
<td>{{pdata[$index].perc</td>
</tr>
You want one row for each element in the gdata array, so the ng-repeat needs to be on the <tr> element. If the two arrays aren't in sync, you can create a function in your controller to return the pdata element you need:
$scope.findPdata(gdata, index) {
// ... do your magic here to find the pdata element you want
return result;
}
<td>{{findPdata(gdata, $index)}}</td>

guessing from the below:
<tr>
<th>Grade</th>
<th>Point</th>
<th>Percent</th>
</tr>
i guess your table has 3 columns so your each row has 3 columns?
in that case use the following
<tr ng-repeat="gdata in gradepoints">
<td>{{gdata.grade | uppercase}}</td>
<td>{{gdata.gp}}</td>
<td>{{gdata.percent}}</td>
</tr>
for above to work your gradepoints must be an ARRAY containing objects with 3 properties each i.e. grade,gp,percent

Related

Click event does not return $event on click

I have the following structure in my HTML in an angular 7 application:
What I am trying to do is to call the GetContent() function on click of any of the text inside the div. I am able to get the $event as "Liquidity" when I click on the text but if I click on any empty space between the text, the $event is empty. I tried every possible permutation of changing the location of the function call and id but same issue. Can anyone let me know what is wrong.
<tr (click)="GetContent($event)">
<td>
<table>
<tbody>
<tr>
<td>
<div id="Liquidity"> lot of text....................... </div>
</td>
</tr>
</tbody>
</table>
</td>
<tr>
Because there is no content in your TR's and TD's, its not creating a space at all. Look at my code, I have added padding for table row's ,table and table data tags
<table>
<tbody>
<tr (click)="GetContent($event)" >
<td style="padding:20px;background:red">TD
<table style="padding:20px;background:green">Table
<tbody>
<tr>
<td style="padding:20px;background:blue">TD
<div id="Liquidity" style="padding:10px;background:green"> lot of text....................... </div>
</td>
</tr>
</tbody>
</table>
</td>
<tr>
</tbody>
</table>
example stackblitz
Do it this way ,
UPDATED
<table>
<tbody>
<tr>
<td>
<div id="Liquidity" (click)="GetContent($event)"> lot of text....................... </div>
</td>
</tr>
</tbody>
</table>
ts file
GetContent(event) {
var target = event.target || event.srcElement || event.currentTarget;
var idAttr = target.attributes.id;
var value = idAttr.nodeValue;
console.log(value) //you will get liquid here.
}

How to make 2 Angular Lists appear next to each other in a html table

I am having a problem where when I run this code which reads data from 2 files both containing 10 numbers. These are both stored seperately in the mainlist but the only problem is when I try to output them into a table, instead of putting each one under its title it just puts both under the "List1" title in a 20 long list. So how do I make mainlist[0] appear under list 1 and mainlist[1] under list 2. Sorry that my code is very messy and very basic as I have only just started learning JS and Angular.
<div id="Tables">
<table>
<tr>
<th>List1</th>
<th>List2</th>
</tr>
<tr>
<tr ng-repeat="i in mainlist[0]">
<td>{{i}}</td>
</tr>
<tr ng-repeat="i in mainlist[1]">
<td>{{i}}</td>
</tr>
</tr>
</table>
</div>
JSfiddle
I hope you're liking Javascript and AngularJS so far! To answer your question the way that tables are created via HTML is row based and not column based meaning <tr> encapsulates cells,<td>, so to create tables you are filling in rows by cells. To accomplish what you want solely through HTML and no additional Javascript you could think of your data being two cells within a single row instead of several rows per column.
I wrote up a quick example of how you could accomplish this through nesting tables. So why nest tables and not just put <td><tr></tr></td>? Row elements cannot be placed within cell elements, but tables can! If you try to place <tr> within <td> it will be rendered ignoring <td>.
I hope this answers your question.
https://jsfiddle.net/krd4p0yt/
var myApp = angular.module('myApp', []);
myApp.controller('TestCtrl', ['$scope',
function($scope) {
$scope.mainList = [
[1, 2, 3],
[4, 5, 6]
];
}
]);
table {
border: 2px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="TestCtrl">
<table>
<th>List 1</th>
<th>List 2</th>
<tr>
<td>
<table>
<tr ng-repeat="i in mainList[0]">
<td>{{i}}</td>
</tr>
</table>
</td>
<td>
<table>
<tr ng-repeat="i in mainList[1]">
<td>{{i}}</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</body>
Here is a solution for your case based on the fact that the two lists have equal length:
<table ng-init="items = mainList[0]">
<tr>
<th>
List 1
</th>
<th>
List 2
</th>
</tr>
<tr ng-repeat="item in items">
<td>
{{item}}
</td>
<td>
{{mainList[1][$index]}}
</td>
</tr>
</table>

Show rows in table with cells name attribute containing string from input (JQuery)

I would like to have keyup function that would show only rows matching the input text by cell that spans on multiple rows.
Consider following table:
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1'> dummy1 </td>
</tr>
<tr>
<td name='Key1'> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2'> dummy3 </td>
</tr>
<tr>
<td name='Key2'> dummy4 </td>
</tr>
</table>
jsfiddle
Here each row has second td tag with name that matches its "parent" column text. So when I type 'Key1' at the input field I would like it to show only dummy1 and dummy2. Is it possible in jquery?
I understand that you want to display the rows that has a matching name. If this is wrong, please elaborate more, then I can update it.
Here is a demo: https://jsfiddle.net/erkaner/gugy7r1o/33/
$('input').keyup(function(){
$('tr').hide();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(keyword) != -1; }).parent().show().next().show();
});
});
Here's my take on your issue, assuming you always want the first column to show. https://jsfiddle.net/gugy7r1o/2/
<input type="text" id="myInput" />
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1' class="data"> dummy1 </td>
</tr>
<tr>
<td name='Key1' class="data"> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2' class="data"> dummy3 </td>
</tr>
<tr>
<td name='Key2' class="data"> dummy4 </td>
</tr>
</table>
.data{
display:none;
}
var theData = $('td.data');
var input = $('#myInput').on('keyup', function(){
theData.hide();
var value = input.val();
var matches = theData.filter('[name="'+value+'"]');
matches.show();
});
Firstly, I would recommend using <ul> to wrap each key in as tables should be used for data structure (Forgive me if that is what it is being used for).
Secondly, just attach an on keyup event to the search box and then find matches based on the id. See example below:
JS Fiddle Demo
It is also worth mentioning that it could be useful attaching a timeout to the keyup event if you end up having large amounts of rows so that only one filter is fired for fast typers!

checking number of td tags in a dynamic table and divide them into two equal tr tags

The question title might seems ambiguous but I will try to explain in detail over here.
So I am generating a dynamic table based on the JSON data. Inside the table I have few tags and in one of the tag I am further populating table data enclosed in tags. Number of tables inside the td tag might varies but the maximum number of tables are 4. Here is the rough HTML markup which is generated after the table is populated.
Current mark up
<table>
<tbody>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<table>
</table>
</td>
<td>
<table>
</table>
</td>
<td>
<table>
</table>
</td>
<td>
<table>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
Expected mark up
<table>
<tbody>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td>
<table>
</table>
</td>
<td>
<table>
</table>
</td>
</tr>
<tr>
<td>
<table>
</table>
</td>
<td>
<table>
</table>
</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
As you can see in the third tag I have 4 tag which contains individual tables. What I am trying to achieve if the number of tags in the third row is greater than 2 then I should create another tag below that and divide the 4 tags (which contains tables) into 2 tags (with 2 tags each).
Since the tables are generated dynamically I don't have a predefined HTML mark up.
This is my relevant JS function
drawRunningDailyDoublesTables: function (events, table) {
var indexes = $(table).data('BetTableData').eventIndexes;
table.innerHTML = '';
// Drawing STAB / NSW product selection
betTable.drawBetTypeProductSelection(table);
// Error space
betTable.drawErrorSpace(table);
var trForTables = $('<tr/>')
.appendTo(table);
// Drawing tables for doubles
$.each(indexes, function(j, index) {
var betTableData = new BetTableData();
betTableData.setMarketId(events[index].markets[0].id);
var doubleTable = $('<table/>')
.data('BetTableData', betTableData);
// Names and info of races
betTable.drawHeaderForDoubles(doubleTable, events[index], 3);
// Horse selections
betTable.drawSelectionsForRunningDoubles(table, doubleTable, events[index], j+1);
// here I am generating the td tag with tables as mentioned in the question. It could be 2,3 or 4 depending on the different situation.
$('<td style="vertical-align: top;"/>')
.appendTo(trForTables)
.append(doubleTable)
// Footer
createFooterRowForRunningDoubles("white", 2, table, doubleTable, j+1);
});
// draw button for betting
betTable.drawExoticBetBtnForDoubles(table);
betTable.selectDefaultRadioProduct(table);
},
Please see this fiddle:
http://jsfiddle.net/MXGBu/2/
var thirdRow = $('table:first>tbody>tr:nth-child(3)');
var tablesInThird = thirdRow.find('table');
if(tablesInThird.length === 4)
{
thirdRow.after('<tr class="arse"></tr>');//creates a new tr after 3rd row
tablesInThird.eq(2).parent().appendTo($('tr.arse')); //adds 3rd table
tablesInThird = thirdRow.find('table');
tablesInThird.eq(2).parent().appendTo($('tr.arse')); //adds 4th table
}

Manipulating <td>'s within different <tr>'s

I'm wondering if the following can be done.
I have a list of 'expenses' that I'm displaying in a table. 4 columns - amount, date, where, and what.
I was thinking I'd like to make each clickable via jQuery which would expand that particular expense, inline, to show a more detailed description.
What I'm trying to do is, on click, replace the contents of the 'tr' with a single 'td' that would contain the extended info. Problem is that 'td' only expands to about a quarter of the table. Is there any way of making it extend to the whole row, while maintaining the widths of the other 'td's in the other rows?
Here's what I would do. Working Demo.
<table id="expenses">
<thead>
<tr>
<td>Amount</td>
<td>Date</td>
<td>Where</td>
<td>What</td>
</tr>
</thead>
<tbody>
<tr class='expense' id='expense-1'>
<td>$5.99</td>
<td>4/2/2009</td>
<td>Taco Bell</td>
<td>Chalupa</td>
</tr>
<tr class='details' id='details-1'>
<td colspan='4'>
It was yummy and delicious
</td>
</tr>
<tr class='expense' id='expense-2'>
<td>$4.99</td>
<td>4/3/2009</td>
<td>Burger King</td>
<td>Whopper</td>
</tr>
<tr class='details' id='details-2'>
<td colspan='4'>
The king of burgers, indeed!
</td>
</tr>
<tr class='expense' id='expense-3'>
<td>$25.99</td>
<td>4/6/2009</td>
<td>Olive Garden</td>
<td>Chicken Alfredo</td>
</tr>
<tr class='details' id='details-3'>
<td colspan='4'>
I love me some italian food!
</td>
</tr>
</tbody>
</table>
With styles like these:
#expenses tr.expense {
cursor: pointer;
}
#expenses tr.details {
display: none;
}
And then have Javascript that looks like this:
$(function() {
$('tr.expense', '#expenses').click(function() {
var id = $(this).attr('id').split('-').pop();
var details = $('#details-'+id);
if(details.is(':visible')) {
details.hide();
} else {
details.show();
}
});
});
That should do it.
<td colspan="4"> ?

Categories

Resources