I've a three level folder structure implemented to resemble hierarchical levels in a Angular Project and trying to achieve drag & drop on this folder structure to merge them on dragging & dropping onto each other.
I've tried adding HTML Drag & Drop APi's but that doesn't help in merging the content of dropped folder ideally.
<table class="table table-bordered table-striped">
<ng-container *ngFor="let content of contents">
<tr class="top-row">
<td class="parent"><i id="parentFolder" class="fa fa-folder-open"></i>{{content.title}}</td>
</tr>
<ng-container *ngFor="let subFolder of contents['subfolder']">
<tr class="object-row">
<td class="child"><i id="childFolder" class="fa fa-folder-open"></i>{{subFolder.title}}</td>
</tr>
<tr *ngFor="let product of subfolder['innerFolder']">
<td class="secondchild"><i class="fa fa-folder"></i>{{product.title}}</td>
</tr>
</ng-container>
</ng-container>
</table>
I was able to achieve this using Angular 2 Drag-and-Drop without dependencies.(https://github.com/akserg/ng2-dnd)
it has draggable & droppable directives to replicate the native HTML DnD APIs as well as restricting drop zones as well as callback functions to allow the drop functions
<table class="table table-bordered table-striped">
<ng-container *ngFor="let content of contents">
<tr class="top-row">
<td class="parent"><i id="parentFolder" class="fa fa-folder-open"></i>{{content.title}}</td>
</tr>
<ng-container *ngFor="let subFolder of contents['subfolder']">
<tr class="object-row" ***dnd-draggable [dragEnabled]="true"***>
<td class="child" **dnd-droppable (onDropSuccess)="simpleDrop=$event"**><i id="childFolder" class="fa fa-folder-open"></i>{{subFolder.title}}</td>
</tr>
<tr *ngFor="let product of subfolder['innerFolder']">
<td class="secondchild"><i class="fa fa-folder"></i>{{product.title}}</td>
</tr>
</ng-container>
</ng-container>
</table>
Related
I'm trying to use the Angular CDK table in an Angular 7 project in Visual Studio 2017. When I follow the official code sample from here it works perfectly but I get these warnings from visual studio: Element 'td'/'th' cannot be nested inside element 'table'.
Below is the code for reference:
<table cdk-table [dataSource]="masterIds">
<ng-container cdkColumnDef="name">
<th cdk-header-cell *cdkHeaderCellDef> Name </th>
<td cdk-cell *cdkCellDef="let id"> {{ ws[id].Name }} </td>
</ng-container>
<ng-container cdkColumnDef="code">
<th cdk-header-cell *cdkHeaderCellDef> Code </th>
<td cdk-cell *cdkCellDef="let id"> {{ ws[id].Code }} </td>
</ng-container>
<tr class="small" cdk-header-row *cdkHeaderRowDef="['name', 'code']"></tr>
<tr cdk-row *cdkRowDef="let id; columns: ['name', 'code']" [routerLink]="['./', id]"></tr>
</table>
Any idea how to get rid of these warnings? They are poking me in the eye. Thanks
UPDATE
Here is a picture of the warnings:
And the green squiggles :
I just found a way which "seems" to work; wrap all the column definitions inside an invisible <tr> element and that's that:
<table cdk-table [dataSource]="masterIds">
<tr style="display:none!important">
<ng-container cdkColumnDef="name">
<th cdk-header-cell *cdkHeaderCellDef> Name </th>
<td cdk-cell *cdkCellDef="let id"> {{ ws[id].Name }} </td>
</ng-container>
<ng-container cdkColumnDef="code">
<th cdk-header-cell *cdkHeaderCellDef> Code </th>
<td cdk-cell *cdkCellDef="let id"> {{ ws[id].Code }} </td>
</ng-container>
</tr>
<tr class="small" cdk-header-row *cdkHeaderRowDef="['name', 'code']"></tr>
<tr cdk-row *cdkRowDef="let id; columns: ['name', 'code']" [routerLink]="['./', id]"></tr>
</table>
A th should be inside a tr, you should have something like :
<table>
<tr>
<th></th>
<th></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
For your updated question
That's because of the Visual studio compiler itself, you can search for How to suppress VS studio compiler warnings (try this), and a tip: switch to VsCode for your frontend dev.
So, my problem is so basic but i cant solve it.
I'm trying to create dynamic table header with *ngFor.
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<div *ngFor="let data of datas">
<th>A little text again</th>
<th>A little text again</th>
</div>
</tr>
</table>
Anyway, this solution suicide themself at that point. If datas length more than 1, div tag is underscoring th tag in same cell.
If i try another solution like this;
<table>
<tr>
<th>Entry Warehouse</th>
<th colspan="2" *ngFor="let data of datas">
SomeText
</th>
</tr>
<tr>
<th>More Text</th>
<th *ngFor="let data of datas">A little text again</th>
<th *ngFor="let data of datas">A little text again</th>
</tr>
</table>
it looks like works but actually not. Because at this time the next th tag doesnt start before the previous loop ends.
In angular 2+ you can use<ng-container> tags
<ng-conatiner *ngFor="let i of items">
<th>i</th>
</ng-conatiner>
What would be the best way to dynamically add an HTML element, such as another column onto a basic HTML table?
I want to have a button below the table, and if the user were to click the button, the event would add the same amount of rows already in the table and add another column. I would want to support about 5 extra columns being added to the table.
Here's my HTML table as of right now:
<table>
<thead>
<tr>
<th id="row-tag"></th>
<th id="option-column">Option 1</th>
</tr>
</thead>
<tbody>
<tr>
<td id="row-tag">P</td>
<td id="option-column">{{ p }}</td>
</tr>
<tr id="row-tag">
<td>
<app-a-p (saveButtonClick)="toggleAP($event)"
[modModalValues]="modModalValues">
</app-a-p>
</td>
<td id="option-column">
<div class="input-group input-group-sm">
$<input
*ngIf="toggleAP==true"
type="text"
name="aP"
size="10"
disabled
value=""
/>
<input
*ngIf="toggleAP==false"
type="text"
name="aP"
size="10"
[ngModel]="con.pA"
(ngModelChange)="con.pA = $event" appFormatP
(blur)="checkAP($event.target.value);
inputTracker.addModifiedValue('Option 1', $event.target.value)"
/>
</div>
</td>
</tr>
<tr>
<td id="row-tag">L</td>
<td id="option-column">${{l}}</td>
</tr>
<tr>
<td id="row-tag">R</td>
<td id="option-column">${{r}}</td>
</tr>
</tbody>
</table>
I think in Angular, you define table based on your data. for example, you have fields array defining columns, and data array defines the what's actually in the table.
<table >
<thead>
<tr>
<th *ngFor='let key of this.fields'>{{key}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let row of this.data ' >
<td scope="row" *ngFor='let key of this.fields'> {{row[key]}} </td>
</tr>
</tbody>
</table>
when you need a new column, just push a new field into fields. like
fields.push('newcolumn');
when you need a new row, just do:
data.push({col1: '', col2:'', newcolumn: ''});
Look into the insertRow() and insertCell() functions in JavaScript. This alongside an onClick function that you write will let you edit the table.
A good way of generating a table on UI when using angular would be to use 2D-array (row*column) use can have a button using which you can dynamically add values to this array and have another row/column to the table.
I'm trying to align the html table correctly but it comes off. The challenge that I have is with respect to the inner loop (modification) which is a list inside of Revision (in other words Revision 'has a' modification list.
While the result on screen are correct, the table is completely off. I speculate the problem is in the 2 *ngFor loop. Any pointer?
<table class="table table-striped">
<thead>
<tr>
<th>Revision No</th>
<th>Date</th>
<th>Username</th>
<th>Field</th>
<th>Old Value</th>
<th>New Value</th>
</tr>
</thead>
<tbody>
<tr>
<div *ngFor="let r of revisions">
<div *ngFor="let m of r.modifications">
<td>{{r.revision}}</a></td>
<td>{{r.date}}</td>
<td>{{r.username}}</td>
<td>{{m.forItem}}<td>
<td>{{m.oldInfo}}<td>
<td>{{m.newInfo}}</td>
</div>
</div>
</tr>
</tbody>
</table>
Nothing can go between your tr and td. Put the first ngfor in a tbody wrapped around your tr. Then put your second ngfor on the tr
You can't have a <div> at that position inside a table
Use
<ng-container *ngFor="let r of revisions">
instead of
<div *ngFor="let r of revisions">
Seems to be the same requirement like AngularJS "Vertical" ng-repeat but solution doesn't work for *ngFor
I have this object array that I am trying to bind to an HTML table. Its format is something like below:
[
{
"Animal":"Dog",
"Country":"France",
"Food":"Tofu",
"Car":"Nano",
"Language":"TypeScript"
}
]
Now this can simply be formatted in the default HTML horizontal table way like this:
<table>
<tr>
<th>Animal</th>
<th>Country</th>
<th>Food</th>
<th>Car</th>
<th>Language</th>
</tr>
<tr *ngFor="let data of datas">
<td>{{data.Animal}}</td>
<td>{{data.Country}}</td>
<td>{{data.Food}}</td>
<td>{{data.Car}}</td>
<td>{{data.Language}}</td>
</tr>
</table>
This would create table like below(Please ignore the data in the table;its just to give an idea.):
But how would I create a structure like this with dynamic data(kind of a vertical table):
In Component:
this.arrayOfKeys = Object.keys(this.datas[0]);
html:
<table>
<tr *ngFor="let key of arrayOfKeys">
<th>{{key}}</th>
<td *ngFor="let data of datas">
{{data[key]}}
</td>
</tr>
</table>
Use ng-container if You have data structure similar to groups[].items[].name
So, if You want to add row
<table>
<ng-container *ngFor="let group of groups">
<tr>
<td>{{group.name}}</td>
</tr>
<tr *ngFor="let item of group.items">
<td>{{item.name}}</td>
</tr>
</ng-container>
</table>
Source: https://stackoverflow.com/a/44086855/1840185