I have a collection of elements of different types. I want to iterate them using ng-repeat, and conditionally draw the right tr per each type.
I can't use ng-repeat-start since I want to use virtual scrolling and none of the libraries I found supports the start/end concept.
Here is a jsfiddle: http://jsfiddle.net/mx6v8j98/1/, which doesn't work. here is the HTML part:
<div ng-app ng-controller="MyCtrl">
<table>
<tbody>
<tr ng-repeat="item in itemsList" ng-switch="$even" ng-class-even="'even'" ng-class-odd="'odd'">
<div ng-switch-when="true">
<td>{{item}} is even</td>
<td>even content</td>
</div>
<div ng-switch-default>
<td>{{item}} is odd</td>
<td>odd content</td>
</div>
</tr>
</tbody>
</table>
</div>
In my real world case, I have many td with complex content, so I don't want to use ng-if/ng-switch-when on each
Update: I can put the ng-repeat on the <tbody> tag, but that looks ugly and I'm not sure what the consequences are regarding styling
Update II: In my case, the 'tr' tag itself is rendered differently according to a condition
As stated in another answer, <div> is not allowed as a child element of <tr>.
You are clearly trying to use <div> as a logical container for ng-switch-when, but since ng-switch-when (and ng-switch-default) supports multi-element, you don't need this container:
<tr ng-repeat="item in items" ng-switch="$even">
<td ng-switch-when-start="true">{{item}} is even</td>
<td>even content 1</td>
<td>even content 2</td>
<td ng-switch-when-end>even content last</td>
<td ng-switch-default-start>{{item}} is odd</td>
<td>odd content 1</td>
<td>odd content 2</td>
<td ng-switch-default-end>odd content last</td>
</tr>
It seems you cannot put <DIV> within <TR> but before <TD>.
Solution 1: Put conditional expression in every <TD>.
<!-- TDs for even row -->
<td ng-if="$even">{{item}} is even</td>
<td ng-if="$even">even content</td>
<!-- TDs for odd row -->
<td ng-if="!$even">{{item}} is odd</td>
<td ng-if="!$even">odd content</td>
Solution 2: For fairly complex table structure, you'd consider create your own directive to represent row cells.
Related
I have this kind of Html and i want to get first <td> class, how can i do it?
<div class="className">My Class</div>
<table>
<tbody>
<tr>
<td>Value 1</td>
<td>Value 1</td>
</tr>
</tbody>
</table>
</div>
First of all i get the class
var Myclass = document.getElementsByClassName('className')[0];
Bu then i cannot figure out how should i navigate to td value.
If you want to stick to pure vanilla js, the simplest answer would probably be:
document.querySelector('.className td').innerHTML;
This is assuming your HTML is structured like below. It's kinda unclear since you have two closing div tags:
<div class="className">My Class
<table>
<tbody>
<tr>
<td>Value 1</td>
<td>Value 1</td>
</tr>
</tbody>
</table>
</div>
Could someone please explain to me why
$(".transaction_history_tab").hide();
will not hide both
// Container
<tbody class="transaction_history_tab">
</tbody>
// In example this is inside the transaction_history_tab container
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
After hiding transaction_history_tab the "NO DATA TO SHOW" still appears.
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
// Without table tags around
<tbody class="transaction_history_tab">
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</tbody>
Working with the answer from Rory
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
// With table tags around
<table>
<thead>
<tr>
<td></td>
</tr>
</thead>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
The issue is solely caused by invalid HTML. The tbody element must be contained within a table. As yours is not, it isn't rendered. You can see this if you check the DOM in the inspector. The tbody can only contain tr elements too. The child div is therefore also a problem, it should be wrapped in a tr and then a td.
As the tbody element is not rendered, and the .transaction_history_tab doesn't exist, hence there's nothing to hide.
To fix the issue correct your HTML. Either add a table around the tbody, including a tr and td around the div, or remove the tbody completely.
$(".transaction_history_tab").hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>This will be shown...</td>
</tr>
</thead>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
Maybe because structure tbody>div without a table/rows/cells is not a valid HTML structure.
Try either using a table>tbody>tr>td>div structure as in this JSFiddle https://jsfiddle.net/u58460ot
or use just the div without tbody as parent
<table>
<tbody class="transaction_history_tab">
<tr>
<td>
<div class="data-info-box">
<span>NO DATA TO SHOW</span>
</div>
</td>
</tr>
</tbody>
</table>
try like above it will work...
You haven't included your css here, but it is possible that your css includes something like this:
.data-info-box {
visibility: visible;
}
which would need changing to:
.data-info-box {
visibility: inherit;
}
This is because a child element set to 'visible' will still show up, even if their parent is 'hidden'. Setting the visibility to 'inherit' means that the child will take on whatever visibility attribute the parent has.
'Inherit' is the default setting for visibility, so if this is the problem you would have had to manually set it to 'visible' in your css (or dynamically in your js).
Using Angular smart table lib:
I just want to display the pagination buttons on the bottom. According to the documentation, it looks like st-pagination directives inserts those dom elements in there. However, for me, it is not working. Here is the plunker given by the smart table documentation:http://plnkr.co/edit/wzUHcc9PBF6tzH8iAEsn?p=preview
Here is my table footer code:
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-items-by-page="10" st-pagination="">
</div>
</td>
</tr>
</tfoot>
I must be misunderstanding something. I know you can put your own customized template for the pagination.
Here is a screenshot, of the output and debugger:
You should use <td> tag only. you should not use <div> tag.
OK
<td colspan="5" class="text-center" st-items-by-page="10" st-pagination="">
</td>
NG
<td colspan="5" class="text-center">
<div st-items-by-page="10" st-pagination="">
</div>
</td>
I have the following data structure: a list of courses, and for every course, a list of semesters. I need to build a table with a row for every semester of every course, and a column with the course's name which spans all the rows for that course.
I'm trying to use angular to generate the table, but because the data structure is nested I can't simply do ng-repeat in the tr tag. So I tried doing this:
<table border="1">
<div ng-repeat="course in data">
<tr>
<td rowspan="{{course.semesters.length}}">{{course.name}}/td>
</tr>
<tr ng-repeat="semester in course.semesters">
<td>{{semester.info}}</td>
</tr>
</div>
</table>
This utterly fails - the table is generated outside the repeated div. Seems to me I'm missing something basic about how ng-repeat works.
Try tbody instead of div:
<table border="1">
<tbody ng-repeat="course in data">
<tr>
<td rowspan="{{course.semesters.length}}">{{course.name}}/td>
</tr>
<tr ng-repeat="semester in course.semesters">
<td>{{semester.info}}</td>
</tr>
</tbody>
</table>
I have a page that contains a couple of layers of nested div tags. Within the the 8 or 9 of the divs are tables. How do I iterate through the divs and pick the specific divs that I want and then iterate through the cells in the table (one row) embedded in each of the divs? Here is a representative sample of the page that I want to iterate through.
<div id="TheHouseDiv" class="catbox_m">
<div class="Room1Div">
<table width="900" border="0">
<tbody>
<tr>
<td>I don't care about this value</td>
<td>I WANT THIS VALUE 1!</td>
<td>I WANT THIS VALUE TOO 2!</td>
<td>Another cell I don't want</td>
<td>THIS CELL I WANT ALSO</td>
<tr>
</tbody>
</table>
<table width="900" border="0">
<tbody>
<tr>
<td>Ignore this value in the second table</td>
<td>I WANT THIS VALUE</td>
<td>I WANT THIS VALUE TOO</td>
<td>Ignore this content</td>
<td>GET THIS CELL VALUE</td>
<tr>
</tbody>
</table>
</div>
<div class="Room2Div">
<table width="900" border="0">
<tbody>
<tr>
<td>I don't care about this value</td>
<td>I WANT THIS VALUE 1!</td>
<td>I WANT THIS VALUE TOO 2!</td>
<td>Another cell I don't want</td>
...
You get the idea. So there is one table within each div and multiple divs. There are actually between 8 and 10 divs. None of the tables or cells have IDs so I need to reference the positionally. However I don't want all of the cell nor all of the tables. I only want values from specific cells in each of the tables within each div although I want the same cells from every table. Would I iterate through this or just reference the specific cells I want and if so, how do I select them?
This gives you all the tds which you want. (if you don't understand the selector just post a comment and I will explain it.
$("div#TheHouseDiv > div > table td:not(:nth-child(1)):not(:nth-child(4))")
e.g. to loop over the hrefs of the <a> tags inside these tds
$("div#TheHouseDiv > div > table td:not(:nth-child(1)):not(:nth-child(4)) a")
.each(function(i, ele) {
alert(ele.href);
}
);
e.g. to loop over the text of the <a> tags inside these tds
$("div#TheHouseDiv > div > table td:not(:nth-child(1)):not(:nth-child(4)) a")
.each(function(i, ele) {
alert($(ele).text()); //or ele.innerHTML if no nasty is in the <a> tags
}
);
$('#TheHouseDiv div').eq(1).find('table').eq(2).find('tr').eq(3).find('td').eq(4).text()
A bit verbose, but I believe this retrieves the text of the 4th <td> inside the 3rd <tr> of the 2nd <table> from the first <div> contained in #TheHouseDiv.
You can also use the shortcut .find('tr:first') to match the first one.