Angular Creating Dynamic Component Inside Desired Component - javascript

I am trying to create a component inside html table's each td child dynamicly.
I created a table component like following code (inside app.component.html)
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col" *ngFor="let column of columns">{{column}}</th>
</tr>
</thead>
<tbody #preGrid id="focusItem">
</tbody>
</table>
</div>
app.component.ts file seems as follow.
ngOnInit() {
let tableItem = document.getElementById("focusItem");
let lastTR;
for (let i = 0; i < 12; i++) {
if (i % this.columns.length == 0) {
let tr = document.createElement("tr");
tableItem.appendChild(tr);
}
lastTR = this.getLastNode(tableItem);
let td = document.createElement("td");
lastTR.appendChild(td);
const factory = this.resolver.resolveComponentFactory(
CustomInputComponent
);
this.container.createComponent(factory);
}
}
I am trying to create angular components by dynamicly using ComponentFactoryResolver.To draw this component, I used ViewContainerRef.But seems, it is not true way to do this.Coz I cannot create my CustomInputComponent inside td component via this way.
What I am trying to do is, embeding CustomInputComponent inside each td elements.You can see what I wrote till now here.

You need to create an array of object which will have the props as well as the type of component you want to render, then in the html portion you can have an ngFor loop to iterate over that array of object. Inside the ngFor loop have multiple ngSwitchCase to render the correct control for the current iteration.
Please see this link : https://codeburst.io/angular-dynamic-forms-ng-switch-approach-4f267c01d2c6

Related

Angular ngFor without an iterable. Need to Build the Iterable

Having an *ngFor in Angular 2+ need to build the iterable (rows) through the creation of an array of n elements:
<table>
<tr *ngFor="let row of rows">
</tr>
</table>
It's there a way of iterate over a number??.
Thanks in advance.
You can generate an array of row indexes with a method of the component class:
public generateRowIndexes(count: number): Array<number> {
let indexes = [];
for (let i = 0; i < count; i++) {
this.indexes.push(i);
}
return indexes;
}
and call it in the template:
<table>
<tr *ngFor="let rowIndex of generateRowIndexes(5)">
...
</tr>
</table>
The code can be tested in this stackblitz.
I suggest you build a custom structure directive just for looping as many times as you want, it is a for-loop wrapped as directive.
The steps to doing this are:
Step-1:
In your module create a loop.directive.ts file.
Step-2: In this directive file paste this code:
import { Directive, Input, TemplateRef, ViewContainerRef } from '#angular/core';
#Directive({
selector: '[appLoop]'
})
export class LoopDirective {
constructor(
private viewContianerRef: ViewContainerRef,
private templateRef: TemplateRef<any>,
) {}
#Input('appLoop') set render(loop: number){
this.viewContianerRef.clear();
for(let i=0; i<loop; i++){
this.viewContianerRef.createEmbeddedView(this.templateRef, {});
}
}
}
Step-3: Now in your template file use *appLoop="5" if you want to loop 5 times or use a variable for example numberOfLines : *appLoop="numberOfLines".
In the code you put in the question it will look like this, where rows is of type number:
<table>
<tr *appLoop="rows">
</tr>
</table>
I would use this syntax to set the index value into an attribute of the HTML element:
<table>
<tr *ngFor="let item of items; let i = index" [attr.data-index]="i"> // data-index attribute will be assigned index
</tr>
</table>

Accessing <td> in HTML Table Using JavaScript

I am trying to attach a row to an editable table using data from an array. In order to do this, I'm adding a row, then utilizing a save feature in order to manipulate the s of the row. My HTML table is:
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody></tbody>
</table>
Being that the array data will be entered into the most recently added row, I've just accessed that using the code below, however now I am struggling to access the actual cells. My current code is:
function UpSave(rowData) {
var tblData = document.getElementById("tblData");
var lastRow = tblData.rows[tblData.rows.length - 1 ];
var tdDate = lastRow.children("td:nth-child(1)");
var tdTime = lastRow.children("td:nth-child(2)");
var tdTreatmentNum = lastRow.children("td:nth-child(3)");
var tdCellNum = lastRow.children("td:nth-child(4)");
console.log(par);
var tdWasteContNum = lastRow.children("td:nth-child(5)");
var tdButtons = lastRow.children("td:nth-child(6)");
tdDate.html(tdDate.children(data[rowData][0]));
tdTime.html(tdTime.children(data[rowData][1]));
tdTreatmentNum.html(tdTreatmentNum.children(data[rowData][2]));
tdCellNum.html(tdCellNum.children(data[rowData][3]));
tdWasteContNum.html(tdWasteContNum.children(data[rowData][4]));
tdButtons.html("<img src='trash.png' class='btnDelete'><img src='pencil.png' class='btnEdit'><img src='up.png' class='btnUp'><img src='down.png' class='btnDown'>");
};
but the .children at the end of the variables are not valid. Any ideas on what to have instead in order to access those cells in the row?
(data is the array containing the text I'm putting into the )
It looks like you never clearly defined the variable tblData by leaving out quotations when you do your original getElementById. Add this to Replace the first line in the function:
var tblData = document.getElementById("tblData");
Adding the quotations will bind the table in the DOM to the variable, then you can do the rest of the stuff.
Revised answer using jQuery:
var $tblData = $("#tblData");
var $lastRow = $tblData.find('tr').last();
var $tdDate = $lastRow.find('td').eq(1);
var $tdTime = $lastRow.find('td').eq(2);
var $tdTreatmentNum = $lastRow.find('td').eq(3);
var $tdCellNum = $lastRow.find('td').eq(4);
//console.log(par);
var $tdWasteContNum = $lastRow.find('td').eq(5);
var $tdButtons = $lastRow.find('td').eq(6);
$tdDate.html(data[rowData][0]);
$tdTime.html(data[rowData][1]);
$tdTreatmentNum.html(data[rowData][2]);
$tdCellNum.html(data[rowData][3]);
$tdWasteContNum.html(data[rowData][4]);
$tdButtons.html("<img src='trash.png' class='btnDelete'/><img src='pencil.png' class='btnEdit'/><img src='up.png' class='btnUp'/><img src='down.png' class='btnDown'/>");
But, if you still want to use pure javascript, try changing the
.children("td:nth-child(x)");
to
.childNodes[x];
Edit note: I changed the inside of the .html(...) function calls so just use the array directly. Previously I had just copy/pasted the OP code for that portion.

Jquery - Access table values (tr children - td) and change them

Found a few posts about this but none answered my question properly.
I want to access some values in my table and change them using a click function in js using jquery. How can I access this and change it without using innerHTML?
<table class="tg">
<tr>
<th class="tg-031e">Race</th>
<th class="tg-031e">space holder lol</th>
</tr>
</table>
var tableArray = $("table").children().children();
$("#input img.Majin").click(function() {
//tableArray[0].innerHTML = "";
});
Use following find function :
$("table").find('classname');

Delete all rows in an HTML table

How can I delete all rows of an HTML table except the <th>'s using Javascript, and without looping through all the rows in the table? I have a very huge table and I don't want to freeze the UI while I'm looping through the rows to delete them
this will remove all the rows:
$("#table_of_items tr").remove();
Keep the <th> row in a <thead> and the other rows in a <tbody> then replace the <tbody> with a new, empty one.
i.e.
var new_tbody = document.createElement('tbody');
populate_with_new_rows(new_tbody);
old_tbody.parentNode.replaceChild(new_tbody, old_tbody)
Very crude, but this also works:
var Table = document.getElementById("mytable");
Table.innerHTML = "";
Points to note, on the Watch out for common mistakes:
If your start index is 0 (or some index from begin), then, the correct code is:
var tableHeaderRowCount = 1;
var table = document.getElementById('WRITE_YOUR_HTML_TABLE_NAME_HERE');
var rowCount = table.rows.length;
for (var i = tableHeaderRowCount; i < rowCount; i++) {
table.deleteRow(tableHeaderRowCount);
}
NOTES
1. the argument for deleteRow is fixed
this is required since as we delete a row, the number of rows decrease.
i.e; by the time i reaches (rows.length - 1), or even before that row is already deleted, so you will have some error/exception (or a silent one).
2. the rowCount is taken before the for loop starts
since as we delete the "table.rows.length" will keep on changing, so again you have some issue, that only odd or even rows only gets deleted.
Hope that helps.
This is an old question, however I recently had a similar issue.
I wrote this code to solve it:
var elmtTable = document.getElementById('TABLE_ID_HERE');
var tableRows = elmtTable.getElementsByTagName('tr');
var rowCount = tableRows.length;
for (var x=rowCount-1; x>0; x--) {
elmtTable.removeChild(tableRows[x]);
}
That will remove all rows, except the first.
Cheers!
If you can declare an ID for tbody you can simply run this function:
var node = document.getElementById("tablebody");
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
Assuming you have just one table so you can reference it with just the type.
If you don't want to delete the headers:
$("tbody").children().remove()
otherwise:
$("table").children().remove()
hope it helps!
I needed to delete all rows except the first and solution posted by #strat but that resulted in uncaught exception (referencing Node in context where it does not exist). The following worked for me.
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>0; x--) {
myTable.deleteRow(x);
}
the give below code works great.
It removes all rows except header row. So this code really t
$("#Your_Table tr>td").remove();
this would work iteration deletetion in HTML table in native
document.querySelectorAll("table tbody tr").forEach(function(e){e.remove()})
Assing some id to tbody tag. i.e. . After this, the following line should retain the table header/footer and remove all the rows.
document.getElementById("yourID").innerHTML="";
And, if you want the entire table (header/rows/footer) to wipe out, then set the id at table level i.e.
How about this:
When the page first loads, do this:
var myTable = document.getElementById("myTable");
myTable.oldHTML=myTable.innerHTML;
Then when you want to clear the table:
myTable.innerHTML=myTable.oldHTML;
The result will be your header row(s) if that's all you started with, the performance is dramatically faster than looping.
If you do not want to remove th and just want to remove the rows inside, this is working perfectly.
var tb = document.getElementById('tableId');
while(tb.rows.length > 1) {
tb.deleteRow(1);
}
Pure javascript, no loops and preserving headers:
function restartTable(){
const tbody = document.getElementById("tblDetail").getElementsByTagName('tbody')[0];
tbody.innerHTML = "";
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="tblDetail" class="table table-bordered table-hover table-ligth table-sm table-striped">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 2</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
a
</td>
<td>
b
</td>
<td>
c
</td>
<td>
d
</td>
</tr>
<tr>
<td>
1
</td>
<td>
2
</td>
<td>
3
</td>
<td>
4
</td>
<tr>
<td>
e
</td>
<td>
f
</td>
<td>
g
</td>
<td>
h
</td>
</tr>
</tr>
</tbody>
</table>
<button type="button" onclick="restartTable()">restart table</button>
If you have far fewer <th> rows than non-<th> rows, you could collect all the <th> rows into a string, remove the entire table, and then write <table>thstring</table> where the table used to be.
EDIT: Where, obviously, "thstring" is the html for all of the rows of <th>s.
This works in IE without even having to declare a var for the table and will delete all rows:
for(var i = 0; i < resultsTable.rows.length;)
{
resultsTable.deleteRow(i);
}
this is a simple code I just wrote to solve this, without removing the header row (first one).
var Tbl = document.getElementById('tblId');
while(Tbl.childNodes.length>2){Tbl.removeChild(Tbl.lastChild);}
Hope it works for you!!.
Assign an id or a class for your tbody.
document.querySelector("#tbodyId").remove();
document.querySelectorAll(".tbodyClass").remove();
You can name your id or class how you want, not necessarily #tbodyId or .tbodyClass.
#lkan's answer worked for me, however to leave the first row, change
from
for (var x=rowCount-1; x>0; x--)
to
for (var x=rowCount-1; x>1; x--)
Full code:
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>1; x--) {
myTable.deleteRow(x);
}
This will remove all of the rows except the <th>:
document.querySelectorAll("td").forEach(function (data) {
data.parentNode.remove();
});
Same thing I faced. So I come up with the solution by which you don't have to Unset the heading of table only remove the data..
<script>
var tablebody =document.getElementById('myTableBody');
tablebody.innerHTML = "";
</script>
<table>
<thead>
</thead>
<tbody id='myTableBody'>
</tbody>
</table>
Try this out will work properly...
Assuming the <table> element is accessible (e.g. by id), you can select the table body child node and then remove each child until no more remain. If you have structured your HTML table properly, namely with table headers in the <thead> element, this will only remove the table rows.
We use lastElementChild to preserve all non-element (namely #text nodes and ) children of the parent (but not their descendants). See this SO answer for a more general example, as well as an analysis of various methods to remove all of an element's children.
const tableEl = document.getElementById('my-table');
const tableBodyEl = tableEl.querySelector('tbody');
// or, directly get the <tbody> element if its id is known
// const tableBodyEl = document.getElementById('table-rows');
while (tableBodyEl.lastElementChild) {
tableBodyEl.removeChild(tableBodyEl.lastElementChild);
}
<table id="my-table">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
</tr>
</thead>
<tbody id="table-rows">
<tr>
<td>Apple</td>
<td>Red</td>
</tr>
<!-- comment child preserved -->
text child preserved
<tr>
<td>Banana</td>
<td>Yellow</td>
</tr>
<tr>
<td>Plum</td>
<td>Purple</td>
</tr>
</tbody>
</table>
Just Clear the table body.
$("#tblbody").html("");
const table = document.querySelector('table');
table.innerHTML === ' ' ? null : table.innerHTML = ' ';
The above code worked fine for me. It checks to see if the table contains any data and then clears everything including the header.

Hide a column in a javascript populated table

I would like to hide the entire age column on this table.
<table id="displayTable">
<tr>
<td class="Name"></td>
<td class="Phone"></td>
<td class="Age"></td>
</tr>
</table>
Javascript follows to hide Age cell -
var table = document.getElementById('displayTable');
var tableRow = table.getElementsByTagName('tr');
for (var row = 0; row < tableRow.length; row++) {
var cells = tableRow[row].getElementsByTagName('td')
cells[2].style.display='none';
}
error says -
"2.style is null or not an object."
What am I missing?
Well, first of all, check your table id. You have it set to 'displayTable' but you're attempting to look it up by 'displayLossTable'.
When i fix that id, and plug your code into jsFiddle, everything works.
what does alert(cells[2]) give you? Alternatively you should try add/remove class instead of inline styles:
el.className+= 'hide'

Categories