Access iterable in sibling tag - html

As stated i want to access an iterable from a sibling tag. Unfortunatly its in a table so i cant just do it by wrapping the stuff with a diff and push the iteration one lvl outside. Also the items are tablerows so i cant make the sibling to a child. I guess this is easier with an example(thats what i want to do):
<table>
<tr v-for="element in elements">
...
</tr>
<tr v-for="hit in element.hits">
...
</tr>
</table>
Obviously this doesnt work since once i close the first tr i drop out of scope. Is there any work around that?
Regardiest regards,
Sean

v-for can be used on <template> that wraps <tr>, in this case it isn't rendered itself:
<template v-for="element in elements">
<tr>
...
</tr>
<tr v-for="hit in element.hits">
...
</tr>
</template>

Related

Using ngIf without an extra element in Angular 2

Can I use ngIf without an extra container element?
<tr *ngFor="...">
<div *ngIf="...">
...
</div>
<div *ngIf="!...">
...
</div>
</tr>
It doesn't work in a table because that would make invalid HTML.
ng-container is preferred over template:
<ng-container *ngIf="expression">
See:
Angular 2 ng-container
https://github.com/angular/angular.io/issues/2303
I found a method for that on: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#star-template.
You can simply use the <template> tag and replace *ngIf with [ngIf] like this.
<template [ngIf]="...">
...
</template>
You can't put div directly inside tr, that would make invalid HTML. tr can only have td/th/table element in it & inside them you could have other HTML elements.
You could slightly change your HTML to have *ngFor over tbody & have ngIf over tr itself like below.
<tbody *ngFor="...">
<tr *ngIf="...">
...
</tr>
<tr *ngIf="!...">
...
</tr>
..
</tbody>
adding brackets resolves this issue
<ng-container *ngIf="(!variable| async)"></ng-container>
You can try this:
<ng-container *ngFor="let item of items;">
<tr *ngIf="item.active">
<td>{{item.name}}</td>
</tr>
</ng-container>
Here, I have iterate loop in ng container so it will not create extra dom and later in tr tag check condition if I want to render or not.

Prevent div wrapper on tr from being ejected

Given the following HTML:
<table>
<div>
<tr><td></td></tr>
</div>
</table>
When it is rendered, the div gets moved out like so:
<div>
</div>
<table>
<tr><td></td></tr>
</table>
Why does this happen, and how can I prevent this from happening?
You can't, the first example is invalid html. You can use a <tbody> instead of the <div> however.
A <div> element is not allowed directly within a <table> element. Only table related elements are allowed (<tr> <thead>...).
There's no way to "make this work". Read the HTML specification and form a valid document.
div tag cannot be inside the table like this.
<table>
<div>
<tr><td></tr></td>
</div>
</table>
You can put it inside the td like this.
<table>
<tr><td><div></div></td></tr>
</table>

Wrapper for multiple <tbody>?

For specific css requirements I'm using multiple <tbody> tags in my table design which looks something like this:
Use of multiple tbody tags
But I also require a wrapper for multiple tbody tags (something like a common tbody parent) such that this wrapper can be scrolled in order achieve the following effect:
A common tbody which can be scrolled
How do I achieve the latter srolling effect in the former one?
(P.S.: I know this can be done through nested table approach, but I'm looking for other alternatives if any)
As mentioned in the comments by FelipeAls and others that a <tbody> tag can be wrapped only by a <table> tag, I tried wrapping <thead> and <tbody>s in separate tables to create the desired effect in the following way:
<table>
<thead>
...
</thead>
</table>
<table>
<tbody>
...
</tbody>
<tbody>
...
</tbody>
<tbody>
...
</tbody>
</table>
This solved the issue.
Here's a Working Demo.
You cannot have a wrapper for tbody elements inside a table. The tbody element itself is a wrapper for tr elements. HTML syntax does not allow any other container for tbody but table. What matters more is that this syntax rules is actually enforced by the way browsers parse HTML.
If you try to use, say, a div element as a wrapper (the most reasonable approach), it will actually create a div element in the DOM, but an empty one, and before the table. All the tbody and tr elements are inserted into the table element; they are effectively extracted from the div element, which thus becomes empty, unless it contains something else than table-related elements.
An illustration, using intentionally invalid markup:
<style>
.x { outline: solid red }
</style>
<table>
<tbody>
<tr><td>foo
</tbody>
<div class=x>
FOO!
<tbody>
<tr><td>foo2
</tbody>
<tbody>
<tr><td>foo3
</tbody>
</div>
<tbody>
<tr><td>The end
</tbody>
</table>
The conclusion is that you need a different approach. The most obvious one is to use just a single tbody element. If this is not feasible, you should explain why, but this would be a topic for a new question.

CSS: Is it possible for a td to infer style from its header or vice versa?

I am formatting my tables, and some of them have hyperlinks in the right hand column which I want right aligned. Is there a way from css to infer that the column has links in it, and right align the whole column, including the header?
Alternatively, is there a way to apply a class to just the header and have it affect the alignment of all of the columns underneath it?
I recognize that I can apply a style to the individual th and td elements, but I was hoping for something a little more elegant.
EDIT: There is only one table.
<table>
<thead>
<tr>
<th>Some Column</th>
<th>actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>Some data</td>
<td>Edit</td>
</tr>
</tbody>
<table>
I am asking if I can apply a style to the element for the actions and write CSS which will cause all of the elements in that column be style a particular way.
This functionality is not part of CSS. Shaun Inman suggested something like a parent selector that would allow parents to inherit from their children, but there are tons of issues with this methodology.
I would suggest, instead, that you try a javascript solution. You could search the table to see if it contains links, then add a class to the table in the case that they do. Something like this:
HTML
<table>
<thead>
<tr>
<th>Normal</th>
<th>Align Me</th>
<th>Normal</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
jQuery
$('td > a').each(function(){
var $td = $(this).parent();
$td.addClass('align-right');
var $th = $td.closest('table').find('th').eq($td.index()).addClass('align-right');
});
Here is a fiddle for you to check out.
CSS can only be applied to child or siblling elements. Children cannot tell their parents what to do.
Applying a class to the TD is the right thing to do.
What you want can not be done with CSS.
But in your special case, you can refer to the fact, that the column with the links is the last one in each row.
There is a special "pseudo-class" in CSS for this: last-child.
th:last-child { ... }
td:last-child { ... }
I came up with a solution, but it only works when the actions are the last column in the table.
<table class="hasActions">
...
</table>
And CSS:
table.hasActions td:last-of-type, table.hasActions th:last-of-type {
text-align: right;
}
Since this doens't work for arbitrary columns, I'll leave the question open for now.

Form tag won't enclose elements inside a table

I've run into a curious problem; I've got a form inside a <tr>, however the form refuses to wrap any tags inside it. I've made a quick JSFiddle here to play around with. Firebug reports that the form isn't wrapping anything:
The <form> element is greyed out and not wrapping anything. The HTML for this test is below
<table>
<form>
<tr>
<td>Input</td>
<td>Another input</td>
</tr>
<tr>
<td colspan="4"><span>Other stuff</span></td>
</tr>
</form>
<tr>
<td>
Rows not affected by the form
</td>
</tr>
<tr>
<td>
Rows not affected by the form
</td>
</tr>
</table>
As can be seen, the form holds two trs in the written markup. I read here that this is invalid, so my question is can I create a form that holds two or more trs and an arbitrary amount of other elements inside a table? The table has other rows in it not associated with the form, so putting a <form> round the entire table is unhelpful, although seeing as the other rows won't have any inputs for the form (POST request), I suppose a form could be put around the entire table.
Which is a better solution; whole-table wrap, or a working fix for just enclosing the needed rows in a form tag? I know I could put a table inside a td > form, but then the column widths wouldn't be the same in the nested table, which is why I came to ask this question.
You cannot interrupt the <table> structure with any tags besides <thead>, <tfoot>, <tbody>, <tr>, <th>, or <td>. You form tags need to be encapsulated between two <td> or your entire <table> needs to be placed within the <form> tag.
<table>
<tr>
<td>
<form>
...form data...
</form>
</td>
</tr>
</table>
..or..
<form>
<table>
...
</table>
</form>
you can only put a form inside a td basically, so you could put those 2 rows inside a new table that you create inside a td
like ...
<table><tr><td><form><table><tr>...</tr><tr>...</tr></table></form></td></tr><tr>...</tr><tr>...</tr></table>
The <form> tag can only be placed inside a <td> element or outside the <table> in this case.
If I were you, I'd just put the <form> around the whole table since you said there won't be any other forms within it.
Or, you could replace the <table> completely with <div>s instead that use display: table; or display: table-cell;.