Bootstrap - How to line up two tbody's properly? - angularjs

I'm having an issue where lining up a table isn't working properly and I was wondering if anyones dealt with something like this before. I looked it up, but couldn't find anything addressing it. I'm using AngularJS and nested ng-repeats which is why I'm having some trouble with this (and need to nest them inside a table). My code is below:
<table class="table table-condensed table-hover table-responsive">
<thead><tr>
<th class="col-sm-4">1</th>
<th class="col-sm-3">2</th>
<th class="col-sm-3">3</th>
</tr></thead>
<tbody ng-repeat="blah in blah">
<tr ng-repeat="blah2 in blah">
<td>......</td>
</tr>
</tbody>
<!--This is the end of "Table 1" in the diagram below-->
<tbody ng-repeat="blah3 in blah4">
<tr ng-repeat="blah5 in blah6">
<td>.........</td>
</tr>
</tbody>
<!--This is the end of "Table 2" in the diagram below-->
</table>
I'm ending up with a result like this (note, I had to draw it due to the fact that the table data I'm using is sensitive information):
How can I pull the second tbody (the smaller one) next to the first?
Thanks

If I understood you correctly, you can simply use Bootstrap's columns as containers for your tables. For instance:
div.col-md-6
Will render two columns together until the screen collapse.
https://jsfiddle.net/DTcHh/11692/

Why not use the grid system of bootstrap ?
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4">.col-md-4</div>
</div>
I don't know what you want to put in the table but you can probably put it into the grid system. link to doc

Related

AngularJS: Display two arrays in separate columns of table

I have two arrays of variable lenghts containing html which need to be displayed side by side in a table by index. So arrayA[0] should be in the same row as arrayB[0], and so on.
I figured I could do this with two ng-repeat-start directives, e.g.:
<table>
<tbody ng-repeat-start="arrayA">
<tr ng-repeat-start="arrayB">
<td bind-html="arrayA.Details"></td>
<td bind-html="arrayB.Details"></td>
<tr ng-repeat-end></tr>
<tbody ng-repeat-end></tbody>
</table>
However this does not seem to work. Any ideas?
Thanks

AngularJS incredibly slow performance when showing a table (1.6.5)

We are building an application to show a table with timetable data.
On the interface the user can set different filters.
I could use a data-grid which would speed up about everything.
I could use a table without grouping and use some sort of lazy fetching which would speed things up.
However we like the layout as is.
The consequence is that the watches are way over 2000 and we are experiencing bottlenecks. It is not that we show hundredths of rows.
How can we make this a bit more performant.
I tried track by, which didn't improve a thing. I tried bind-once but that didn't work either. (Honestly I have no clue how to make it work with key,value objects).
One performance trick might be changing the filters, move and chain them in the controller?
As you also can see, we re-use the same filters a lot, however this is necessary for the group by.
I also haven't seen any lazy-fetching mechanism which works with this kind of custom table / group by.
Hopefully you can help me to point me in the right direction, since I really kinda like the current layout.
The dataset is being displayed in a table and is grouped by date.
Example output:
hrefDateA | hrefDateB | hrefDateC | hrefDateD
DateA
RowA with columns
RowB with columns
RowC with columns
DateB
RowD with columns
RowE with columns
DateC
RowA with columns
RowB with columns
RowC with columns
....
<div ng-if="includeDesktopTemplate" ng-show="whateverdata.length > 0">
<div>
Jump to:
<a ng-href="#tableheader{{$index}}" ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'" class="someclass">
{{key}}
</a>
</div>
<hr />
<table>
<thead>
<tr>
<th class="timetablerow">HeaderA</th>
<th class="timetablerow">HeaderB</th>
<th class="timetablerow">HeaderC</th>
<th class="timetablerow">HeaderD</th>
<th class="timetablerow">HeaderE</th>
<th class="timetablerow">HeaderF</th>
</tr>
</thead>
<tbody ng-repeat="(key, value) in whateverdata | filter:filterA() | filter:filterB() | filter:filterC() | groupBy: 'someproperty'">
<tr>
<td colspan="6" class="desktoptablegroupby" id="tableheader{{$index}}">
{{key}}
</td>
</tr>
<tr>
<td colspan="6">
<hr class="redbackground" />
</td>
</tr>
<tr ng-repeat="row in value | filter:filterA() | filter:filterB() | filter:filterC()" ng-class-odd="'odd'" ng-class-even="'even'">
<td class="timetablerow">
{{row.propertyA}}
</td>
<td class="timetablerow">
{{row.propertyB}}
</td>
<td class="timetablerow">
{{row.propertyC}} - {{row.propertyD}}
</td>
<td class="timetablerow">
{{row.propertyD}}
</td>
<td class="timetablerow">
{{row.propertyE}}
</td>
<td class="timetablerow">
<div ng-show="{{row.propertyF}}">
<md-tooltip md-direction="{{tooltip.tipDirection}}">
{{row.propertyF}}
</md-tooltip>
<md-icon md-svg-src="~/Content/comment.svg">
</md-icon>
</div>
</td>
</tr>
</tbody>
</table>
<br /><br />
</div>
If I include the code below, watches can go from 3k to 6k
<div ng-show="{{row.propertyF}}">
<md-tooltip md-direction="{{tooltip.tipDirection}}">
{{row.propertyF}}
</md-tooltip>
<md-icon md-svg-src="~/Content/comment.svg">
</md-icon>
</div>
Regarding the code above. One column would show an icon with a tooltip which contains the value of an extra field of the dataset, only when the field contains data. But this also gives issues when the filters are being used (so redraw of screen), since other rows are showing the tooltip then, even when the value of the field of the specific row does not contain a value.(DOM/update/filter issue?)
This is a limitation by the way AngularJS handles change detection and rendering. There's really no easy solution - with emphasis on easy. What I've done on several occasions is use a technique often refered to as virtual-scroll/virtual-repeat. What it basically does is that it only renders the elements that can be seen in the viewport, but adds offsets to the top and bottom of the list/table to keep the scrollbar a constant size, regardless of how many elements are actually rendered. Then whenever you scroll, the elements that pop into view is seamlessly rendered before they become visible. This gives the illusion that it's a single long list/table, when it really only renders what is visible.
There are many libraries that implement this technique. I've personally got experience with the one called angular-vs-repeat but you should take a look at a few and evaluation which fits best your use case. I've also on one occasion implemented my own virtual scroll and it was certainly doable (my usecase in that scenario was that I needed virtual scroll to work both vertically and horizontally).

Custom directive version of ng-repeat-start - ng-repeat-end

I have a table that uses ng-repeat-start and ng-repeat-end every two table rows, like this:
<table>
<tr>... // other <tr>'s without ng-repeat
<tr ng-repeat-start="parameter in ctrl.parameters">
<td>Name</td>
<td>{{parameter.name}}</td>
</tr>
<tr ng-repeat-end>
<td>Value</td>
<td>{{parameter.value}}</td>
</tr>
</table>
This AngularJS application is deployed in Karaf as a Hawtio plugin and ng-repeat-start-end part doesn't work. Maybe because it's a plugin. Other table rows (without ng-repeat) works and shows the data binded. The odd thing is, a single entry for the label Name and Value still appears, but without the expression evaluated, whether there is or no data bound to the two element rows. What's the reason behind this?
I'm considering to use a custom directive in the js module instead of placing ng-repeat-start and ng-repeat-end in the html. Could someone show how to do this the custom directive way?
Thanks.
I have solved my own question. Karaf's Hawtio uses AngularJS version 1.1.5 (as of this writing), which do not have ng-repeat-start and ng-repeat-end yet. So, what I did is to enclose the repeating two rows in another <tbody> (multiple <tbody>s is working in HTML5) and put ng-repeat directive there. Like this:
<tbody>
.
.
.
</tbody>
<tbody ng-repeat="entry in data.entries">
<tr>
<td>Name</td>
<td>{{entry.name}}</td>
</tr>
<tr>
<td>Value</td>
<td>{{entry.value}}</td>
</tr>
</tbody>

Angular-tablesort breaks

angular-tablesort is saving me a lot of time, but i'm hitting a bug where I can't get the header to become sortable even though I am following the examples and adding the classes. My code looks like this:
<table class="table" ts-wrapper>
<thead>
<tr>
<th class="tablesort-sortable" ts-criteria="Name|lowercase" ts-default>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items" ts-repeat>
<td>{{item.data.title}}</td>
</tr>
</tbody>
</table>
Solved!
As I was working through how best to present this to you guys I realized that this was an RTFM problem. I was confused by the fact that the example matches the ts-criteria with the div contents and didn't match the ng-repeat contents fully. angular-table actually lets you pass in item.data.title or data.title to get a sortable table.
A little embarrassing, but I'm still going to post this in case someone else comes across the same issue. This has nothing to do with bootstrapped angular applications, which was my first hunch. Changed the title to be more generic (from Angular-tablesort breaks when angular is bootstrapped to Angular-tablesort breaks).

How to generate table tr from multiple overlapping ng-repeat

While replacing legacy javascript with angularjs code, I'm stuck with the following use case (simplified code as follows):
<tr ng-repeat="section in page.sections>
<td>{{section.name}}:</td>
</tr>
<tr ng-repeat="task in section.tasks>
<td>{{task.name}}:</td>
</tr>
The expected result should be a single table, with task rows should follow parent section row.
I understand that the inner loop won't work because of the scope of the section element is not the parent of the inner loop.
Is there a work around (or a best suitable way) to perform this?
The following should work:
<tr ng-repeat-start="section in page.sections">
<td>{{section.name}}:</td>
</tr>
<tr ng-repeat="task in section.tasks">
<td>{{task.name}}:</td>
</tr>
<tr ng-if="false" ng-repeat-end><td>end</td></tr>
See a demo plunkr

Resources