jQuery Replace not acting as expected - javascript

$(".rowIWanTtoReplace").replaceWith("<tr><td rowspan='11' class='n'>n</td><td rowspan='8'>n</td><td>t</td><td>n</td></tr><tr><td>u</td><td>n</td></tr><tr><td>v</td><td>n</td></tr><tr><td>w</td><td>n</td></tr><tr><td>x</td><td>n</td></tr><tr><td>y</td><td>n</td></tr><tr><td>z</td><td>n</td></tr>");
td {
border: 1px solid black
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<table class="station-device-table4">
<tr>
<td>x</td>
<td>y</td>
<td>z</td>
</tr>
<tr class="rowIWanTtoReplace">
<td rowspan="11" class="s">foobar</td>
<td rowspan="7">foobar</td>
<td>n</td>
</tr>
</table>
I just wanted to check whether or not this should be the result of a replaceWith() in this situation:
If I have a table and on one row I apply replaceWith(), And What I replace it with is multiple table rows.
Shouldn't that just affect the HTML so when displayed multiple should show in that section?
i.e ------ TR 1 -----------
.replaceWith("<tr>x</tr><tr>y</tr>")
shouldn't the first row replace the other row. And the second row append after?
Or is there an alternative method?
Thanks.
Example code for situation:
<table class="station-device-table4">
<tr>
<td>x</td>
<td>y</td>
<td>z</td>
</tr>
<tr class="rowIWanTtoReplace">
<td rowspan="11" class="s">foobar</td>
<td rowspan="7">foobar</td>
<td>n</td>
</tr>
</table>
JQuery example:
$(".rowIWanTtoReplace").replaceWith("<tr>
<td rowspan="11" class="n">n</td>
<td rowspan="8">n</td>
<td>t</td>
<td>n</td>
</tr>
<tr><td>u</td><td>n</td></tr>
<tr><td>v</td><td>n</td></tr>
<tr><td>w</td><td>n</td></tr>
<tr><td>x</td><td>n</td></tr>
<tr><td>y</td><td>n</td></tr>
<tr><td>z</td><td>n</td></tr>")
Note: This is made from backbone collections and stuff. I have outputted to the screen the html that it using to update. And put the code together as if it was normal jquery.

You cannot have linefeeds in strings unless you use template literals - also you had nested double quotes which also does not work.
In the original code you replaced a header cell with a table row which also did not compute.
This might be what you want:
$(".rowIWanTtoReplace").replaceWith(`<tr>
<td rowspan="11" class="tvmStatus">TVM Status</td>
<td rowspan="8">Component Events</td>
<td>t</td>
<td>n</td>
</tr>
<tr><td>u</td><td>n</td></tr>
<tr><td>v</td><td>n</td></tr>
<tr><td>w</td><td>n</td></tr>
<tr><td>x</td><td>n</td></tr>
<tr><td>y</td><td>n</td></tr>
<tr><td>z</td><td>n</td></tr>`)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="station-device-table4">
<tr>
<td>x</td>
<td>y</td>
<td>z</td>
</tr>
<tr class="rowIWanTtoReplace">
<td rowspan="11" class="s">foobar</td>
<td rowspan="7">foobar</td>
<td>n</td>
</tr>
</table>

Related

How can I split 3 columns into 2 evenly?

I have the following React JSX code for a table:
<table>
<tr>
<td>col1</td>
<td>col2</td>
<td>col3</td>
</tr>
</table>
And I want to add a footer with 2 columns filling up the entire width but I'm having trouble doing that. I tried colspan but its not working as expected. How can I do this?
You can do this with colspan, all you need to take into account is that colspan should be integers (1,2,3) and cannot have something like 1.5.
So the trick is to also use colspan in your first row and give them all a colspan of 2, such that the total is 6 which you can divide by two columns of 3.
<table border="1">
<tr>
<td colspan="2">col1</td>
<td colspan="2">col2</td>
<td colspan="2">col3</td>
</tr>
<tr>
<td colspan="3">footer1</td>
<td colspan="3" >footer2</td>
</tr>
</table>
Just colspan your footer cell on all the 3 cells. Then add a separate table within that footer table and make 2 columns. Don't forget to make that inner table as lean as possible (no border, no margin, .. as you need it)
<table border="1">
<tr>
<td>col1</td>
<td width="400">col2</td>
<td>col3</td>
</tr>
<tr>
<td colspan="3">
<table width="100%">
<tr>
<td width="50%">footer left</td>
<td width="50%">footer right</td>
</tr>
</table>
</td>
</tr>
</table>

How to remove a pattern of table row elements from a table?

If I have the following table, which I can't manually touch, but can apply javascript to...
<table data="customTable">
<tr>
<td>item 1</td>
</tr>
<tr>
<td height="10"></td>
</tr>
<tr>
<td>item 2</td>
</tr>
<tr>
<td height="10"></td>
</tr>
</table>
...when the DOM loads fully, how can I remove every instance of <tr><td height="10"></td></tr> from the above table via jQuery or raw JavaScript? I don't need that row at all and its causing design issues for me. This is my first time trying to learn how to replace a full pattern of elements.
Hopefully, this is doable via JavaScript?
This should do the trick.
jQuery
$('td[height="10"]').parent().remove();
https://jsfiddle.net/uzv3fn2e/1/
Vanilla JS
Array.from(document.querySelectorAll('td[height="10"]')).forEach(td => td.parentNode.remove());
https://jsfiddle.net/t7y6aqc5/
You can use :has() selector to select tr that has td with specific attribute
$("tr:has(td[height='10'])").remove()
$("tr:has(td[height='10'])").remove()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table data="customTable">
<tr>
<td>item 1</td>
</tr>
<tr>
<td height="10"></td>
</tr>
<tr>
<td>item 2</td>
</tr>
<tr>
<td height="10"></td>
</tr>
</table>
without using jquery javascript has also remove()
document.querySelectorAll("td").forEach(el => el.getAttribute("height") === "10" && el.parentNode.remove())
<table data="customTable">
<tr>
<td>item 1</td>
</tr>
<tr>
<td height="10"></td>
</tr>
<tr>
<td>item 2</td>
</tr>
<tr>
<td height="10"></td>
</tr>
</table>

Populate Bootstrap 4 Table From Array?

I'm currently trying to dynamically populate a bootstrap 4 table from an array. I am trying to populate 3 tables that are actually side by side, and then will eventually filter the data from the array to be stored in each corresponding table. So what I am aiming to have is 3 tables that can be populated with a different number of rows each, with data taken directly from an array.
However, whenever I try and populate or create the table dynamically through a function, I either remove the Bootstrap formatting, or end up with some very odd results!
Below is essentially the type of layout I want to achieve, but this is static and I'd love to have something that can acquire these varying rows, based on how much data they retrieve from an array.
<div class="row">
<div class="col-md-4">
<h2 class="sub-header">Test Tab 1</h2>
<div class="table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<td class="col-md-1">Content 1</td>
<td class="col-md-2">Content 1</td>
<td class="col-md-3">Content 1</td>
</tr>
<tr>
<td class="col-md-1">Content 2</td>
<td class="col-md-2">Content 2</td>
<td class="col-md-3">Content 2</td>
</tr>
<tr>
<td class="col-md-1">Content 3</td>
<td class="col-md-2">Content 3</td>
<td class="col-md-3">Content 3</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<h2 class="sub-header">Test Tab 2</h2>
<div class="table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<td class="col-md-1">Content 4</td>
<td class="col-md-2">Content 4</td>
<td class="col-md-3">Content 4</td>
</tr>
<tr>
<td class="col-md-1">Content 5</td>
<td class="col-md-2">Content 5</td>
<td class="col-md-3">Content 5</td>
</tr>
<tr>
<td class="col-md-1">Content 6</td>
<td class="col-md-2">Content 6</td>
<td class="col-md-3">Content 6</td>
</tr>
<tr>
<td class="col-md-1">Content 7</td>
<td class="col-md-2">Content 7</td>
<td class="col-md-3">Content 7</td>
</tr>
<tr>
<td class="col-md-1">Content 8</td>
<td class="col-md-2">Content 8</td>
<td class="col-md-3">Content 8</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-md-4">
<h2 class="sub-header">Test Tab 3</h2>
<div class="table-responsive">
<table class="table table-striped">
<tbody>
<tr>
<td class="col-md-1">Content 9</td>
<td class="col-md-2">Content 9</td>
<td class="col-md-3">Content 9</td>
</tr>
<tr>
<td class="col-md-1">Content 10</td>
<td class="col-md-2">Content 10</td>
<td class="col-md-3">Content 10</td>
</tr>
<tr>
<td class="col-md-1">Content 11</td>
<td class="col-md-2">Content 11</td>
<td class="col-md-3">Content 11</td>
</tr>
<tr>
<td class="col-md-1">Content 12</td>
<td class="col-md-2">Content 12</td>
<td class="col-md-3">Content 12</td>
</tr>
<tr>
<td class="col-md-1">Content 13</td>
<td class="col-md-2">Content 13</td>
<td class="col-md-3">Content 13</td>
</tr>
<tr>
<td class="col-md-1">Content 14</td>
<td class="col-md-2">Content 14</td>
<td class="col-md-3">Content 14</td>
</tr>
<tr>
<td class="col-md-1">Content 15</td>
<td class="col-md-2">Content 15</td>
<td class="col-md-3">Content 15</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
When experimenting with just a single one of these tables to try and get the general concept working, I've just been going around in circles and can't seem to figure out this hierarchy of table elements and how to associate the javascript created rows to the bootstrap classes for design.
Below is my attempt, but it doesn't seem to alter the base bootstrap html or make any changes at all (one of numerous attempts)(credit to Ovidiu for fixing the error):
var testList = ["TestContent1", "TestContent2", "TestContent3", "TestContent4"];
function drawTable1() {
// get the reference for the body
var table1 = document.getElementById('table1Div');
// get reference for <table> element
var tbl = document.getElementById("table1");
// creating rows
for (var r = 0; r < testList.length; r++) {
var row = document.createElement("tr");
// create cells in row
for (var c = 0; c < 3; c++) {
var cell = document.createElement("td");
var cellText = document.createElement('span');
cellText.innerText = testList[r];
cell.appendChild(cellText);
row.appendChild(cell);
}
tbl.appendChild(row); // add the row to the end of the table body
}
table1.appendChild(tbl); // appends <table> into <div>
}
drawTable1();
Edit: To clarify, my question differs from the duplicate as I would still like to retain my bootstrap formatting. Simply creating a dynamic table removes all of the bootstrap classes and formatting that keeps the tables responsive.
Edit 2: Thank you Ovidiu for the working fiddle! This more clearly illustrates my point that the Bootstrap formatting is no longer applied once the table has been populated dynamically!
To add classes from JavaScript use className property:
var div = document.createElement('div');
div.className = 'some-class other-class';
You may also want to avoid using classes like col-md-3 with tables. Bootstrap layoud is float based while tables have their own display types in HTML/CSS and changing them to floats won't work (especially that you are not using row on rows etc.). Either move to purely <div> based layout or use width=8%, width=17% and width=25% respectively. And of course fix the bug of the widths not summing up to 100% (col-md-1 + col-md-2 + col-md-3 = col-md-6 < col-md-12 (12 is 100% row width in Bootstrap)). Or if you really want free space, then either add it explicitly as an empty cell or just set the whole table width to be 50%.
Answer to comment:
If you are going to use table-stripped then you need table to be <table> and not <div>, obviously. However you MUST NOT use col-md-# classes with table cells. Use width="33%" (or other appropriate value) attribute instead. If you create the whole table content dynamically, you may add <colgroup> sections and define columns separately from the content. Also, you should append your rows inside <tbody> not <table>. Appending them to <table> works only due to browser being backward compatibile with HTML 3, but Bootstrap is not and its styling gets broken. Bootstrap expects all the cells to be either in <thead>, <tbody> or <tfoot>, not directly under <table>. Example code:
<table class="table table-striped">
<colgroup>
<col width="17%">
<col width="33%">
<col width="50%">
</colgroup>
<tbody id="table2">
<tr>
<td>Content 4</td>
<td>Content 4</td>
<td>Content 4</td>
</tr>
<!-- etc. --->
</tbody>
</table>

jQuery select various information from different <tr>

I'm working with the following HTML:
<tr class="oddrow">
<td>row1</td>
<td style="text-align:center;">
<table>
<tbody>
<tr>
<td width="50%">-1<br>+1</td>
<td width="50%">WSH: -110<br>SAC: -110</td>
</tr>
</tbody>
</table>
</td>
<td style="text-align:center;">
<table>
<tbody>
<tr>
<td width="50%">202.5</td>
<td width="50%">o: -110<br>u: -110</td>
</tr>
</tbody>
</table>
</td>
<td style="text-align:center;">WSH: 0<br>SAC: 0</td>
</tr>
<tr class="evenrow">
<td>row2</td>
<td style="text-align:center;">
<table>
<tbody>
<tr>
<td width="50%">-1<br>+1</td>
<td width="50%">WSH: -110<br>SAC: -110</td>
</tr>
</tbody>
</table>
</td>
<td style="text-align:center;">
<table>
<tbody>
<tr>
<td width="50%">202.5</td>
<td width="50%">o: -110<br>u: -110</td>
</tr>
</tbody>
</table>
</td>
<td style="text-align:center;">WSH: 0<br>SAC: 0</td>
<!-- The above line is the one I need. --!>
</tr>
There are 2 such rows (row1 and row2), alternating as an oddrow then evenrow. I have the entire HTML as a string in my JavaScript/jQuery code. I also have the information of the two three-letter abbreviations: in this example, WSH and SAC. What I need is the third <td style="text-align:center;"> of the row2 row. I should point out that there are several tables of row1 and row2 on the page, so I need a general selector. What I have been doing is just grabbing all the data in all the rows then parsing it from there, but the inconsistency of the data is making that more difficult. Is there a quick and dirty jQuery that will point me to the data I need?
I was thinking something like $("tr td:contains(" + abbrev + ") td:contains('row2')").text();, but that doesn't get it.
Can anyone help?
Your hierarchy in your selector is wrong, tds with the abbreviation are not an ancestor to the tds with the text of "row2"
You also need to ensure you have apostrophes around your abbrev variable.
Can you try:
$("tr td:contains('row2') td:contains('" + abbrev + "')").text()
Any chance you can add semantic classes instead? These sorts of selectors are gnarly to maintain.

Different number of Columns in rows of a table

Is it possible to create a table with different number of cells in each and every row with the same width and height ..?? If so how it can be done in a simpler way ..???
Note:
Row width and height are same
Cell width differs in each and every row
<table>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td colspan="2"> </td>
<td> </td>
</tr>
<tr>
<td colspan="3"> </td>
</tr>
This is what i have tried using coll span ..Here let's say first row cells width is 30px,30px,30px . if i use coll span , it will be like 60px,30px but i want it as 50px,40px with only 2 cells
I want like this
You can use colspan to create cells that span multiple columns.
jsFiddle
<table>
<tr>
<td> </td>
<td> </td>
<td> </td>
</tr>
<tr>
<td colspan="2"> </td>
<td> </td>
</tr>
<tr>
<td colspan="3"> </td>
</tr>
</table>
If you want all to be the same width and height but only have the number of cells differ you can just not style certain cells in the <table>.
jsFiddle
<table>
<tr>
<td class="content"> </td>
<td></td>
<td></td>
</tr>
<tr>
<td class="content"> </td>
<td class="content"> </td>
<td></td>
</tr>
<tr>
<td class="content"> </td>
<td class="content"> </td>
<td class="content"> </td>
</tr>
</table>
Update
Your update with the image, yes you can accomplish this using colspan:
jsFiddle
<table>
<tr>
<td> </td>
<td colspan="2"> </td>
<td> </td>
</tr>
<tr>
<td colspan="2"> </td>
<td colspan="2"> </td>
</tr>
</table>
This uses four columns, the middle two are smaller than the others, here is an image that illustrates how the columns are set up:
Update #2
Here is an example of more randomly sizes cells. The first row 10%, 90% and the second row 55%, 45%.
jsFiddle
HTML
<table>
<tr>
<td></td>
<td colspan="2"></td>
</tr>
<tr>
<td colspan="2"></td>
<td></td>
</tr>
</table>
CSS
table {
width:100px;
}
td {
border: 1px solid #000;
height:1em;
}
tr:first-child td:first-child {
width:10%;
}
tr:first-child td:last-child {
width:90%;
}
tr:last-child td:first-child {
width:55%;
}
tr:last-child td:last-child {
width:45%;
}
Yes you can, with the colspan attribute for table cells, like this:
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>1</td>
<td colspan="2">2</td>
<td>3</td>
<td>4</td>
<td>5</td>
</tr>
<tr>
<td>1</td>
<td colspan="5">2</td>
</tr>
<tr>
<td colspan="2">1</td>
<td>2</td>
<td colspan="2">3</td>
<td>4</td>
</tr>
</table>
Working example: http://jsfiddle.net/sk5cB/
Not positive that this is what you're looking for, but you could create a table with merged cells by using the colspan attribute in your <td> tags.
HTML colspan Attribute
You may also use and create a table in
<tr> </tr> tags
If you intend to insert content in those cells and prefer to maintain the same cell width then it is impossible using only tables. I've searched for solutions on this problem as well, it looks great when the cells are empty like Daniel Imms presented in his example, but if you add content to those cells their width starts getting bigger and the other cells on the row start getting smaller. Specifying table-layout:fixed doesn't help because then the first row becomes the rule for all following rows.
If you have the possibility to use divs with float left and width in percentage and a clear fix display:table div that wraps them all, just like Bootstrap 3 does in its grid system, then that'll be much more reliable.

Categories

Resources