IE9 - Loading html table into a page with jQuery - javascript

I have built a very simple example, loading a table into a page via ajax from another html page and it works fine in all browsers, except IE9, that seems to nest tables. Replacing table with div isn't an option here.
What would be the workaround for it?
(I'm using jquery-1.8.1)
Here is my code:
index.html
<table id="table_id">
<thead>
<tr>
<th>Sort Column 1</th>
<th>Sort Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 Data 1</td>
<td>Row 1 Data 2</td>
</tr>
<tr>
<td>Row 2 Data 1</td>
<td>Row 2 Data 2</td>
</tr>
</tbody>
</table>
<button>load new data</button>
<script type="text/javascript">
$(document).ready(function () {
var tbl = $('#table_id');
$("button").on("click", function () {
var xhr = $.ajax("table.html")
.done(function (data) {
tbl.html(data);
});
});
});
</script>
table.html
<table id="table_id">
<thead>
<tr>
<th>Sort Heading 1</th>
<th>Sort Heading 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 1 New Data 11</td>
<td>Row 1 New Data 22</td>
</tr>
<tr>
<td>Row 2 New Data 11</td>
<td>Row 2 New Data 22</td>
</tr>
</tbody>
</table>

You can use .replaceWith
$('#table_id').replaceWith(data);
Because .html replaces internal content. In our case, after use .html table look like this
<table id="table_id">
<table id="table_id">
...
</table>
</table>

Related

Is there any direct way to get a minimal HTML node structure in jQuery?

This is the input node structure
<table>
<thead>
<tr style="text-align: left;">
<th class="some_class"><div><div><span>COL1</span></div></div></th>
<th class="some_class"><div><div><span>COL2</span></div></div></th>
<th class="some_class"><div><div><span>COL3</span></div></div></th>
<th class="some_class"><div><div><span>COL4</span></div></div></th>
</tr>
</thead>
<tbody>
<tr>
<td>content 1</th>
<td>content 2</td>
<td>content 3</td>
<td>content 4</td>
</tr>
</tbody>
</table>
And this is the wanted output structure
<table>
<thead>
<tr>
<th>COL1</th>
<th>COL2</th>
<th>COL3</th>
<th>COL4</th>
</tr>
</thead>
<tbody>
<tr>
<td>content 1</th>
<td>content 2</td>
<td>content 3</td>
<td>content 4</td>
</tr>
</tbody>
</table>
I could just remove the elements manually with some mappings or some loops, but I am wondering if there is a better way to just get the minimal HTML possible without attributes
Removing the attributes you can use the removeAttr,.
To get rid of <div><div><span>...,. You could loop the th get the text() and then set using text() again this has the effect of getting rid of the the extra tags.
eg..
const c = $('table').clone();
c.find('*').removeAttr('class style');
c.find('th').each(function() { $(this).text($(this).text()); });
console.log(c[0].outerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr style="text-align: left;">
<th class="some_class"><div><div><span>COL1</span></div></div></th>
<th class="some_class"><div><div><span>COL2</span></div></div></th>
<th class="some_class"><div><div><span>COL3</span></div></div></th>
<th class="some_class"><div><div><span>COL4</span></div></div></th>
</tr>
</thead>
<tbody>
<tr>
<td>content 1</td>
<td>content 2</td>
<td>content 3</td>
<td>content 4</td>
</tr>
</tbody>
</table>
Sure, it's pretty easy...
Here i have a codesandbox for you where this works:
https://codesandbox.io/s/wonderful-star-g8h8f?file=/index.html
$(".noattrs *").each(function() {
// first copy the attributes to remove
// if we don't do this it causes problems
// iterating over the array we're removing
// elements from
var attributes = $.map(this.attributes, function(item) {
return item.name;
});
// now use jQuery to remove the attributes
var el = $(this);
$.each(attributes, function(i, item) {
el.removeAttr(item);
});
})

Sort table in HTML by column with date values desc using only javaScript

Is it possible to make sorting function using only javaScript, without any other library for sorting?
Let's say I have one table, and it's first column that has date values in this format: MM/dd/yyyy. Table has two more columns, like this:
<table id="results" width="360" border="1">
<thead>
<tr>
<th scope="col" width="120">Date Created</th>
<th scope="col" width="120">Name</th>
<th scope="col" width="120">Tests</th>
</tr>
<tr>
<td>07/08/2015</td>
<td>Test Name</td>
<td>Raven</td>
</tr>
<tr>
<td>05/04/2015</td>
<td>Test Name 4</td>
<td>Raven 3</td>
</tr>
<tr/>
<td>01/08/2017</td>
<td>Test Name 2</td>
<td>PCT</td>
</tr>
</thead>
</table>
Would it be possible to lets say add one button, and on click event sort rows by values in Date column?
I have to accomplish this using only plain javaScript and HTML, so no jQuery unfortunately :(
Here's a little something I whipped up to give you some ideas. Obviously you could extend this to sort by other data types.
I've "cheated" on the date comparisons by just changing the string format date directly to an eight-digit number in the form 20140312 from "12/03/2014" - note that I've assumed the date input format is dd/mm/yyyy, so if for some reason you're actually using mm/dd/yyyy you'll have to tweak the convertDate() function.
Also I've introduced a <tbody> into your table so that I can just sort the data rows and completely ignore the header row.
function convertDate(d) {
var p = d.split("/");
return +(p[2]+p[1]+p[0]);
}
function sortByDate() {
var tbody = document.querySelector("#results tbody");
// get trs as array for ease of use
var rows = [].slice.call(tbody.querySelectorAll("tr"));
rows.sort(function(a,b) {
return convertDate(a.cells[0].innerHTML) - convertDate(b.cells[0].innerHTML);
});
rows.forEach(function(v) {
tbody.appendChild(v); // note that .appendChild() *moves* elements
});
}
document.querySelector("button").addEventListener("click", sortByDate);
<table id="results" width="360" border="1">
<thead>
<tr>
<th scope="col" width="120">Date Created</th>
<th scope="col" width="120">Name</th>
<th scope="col" width="120">Tests</th>
</tr>
</thead>
<tbody>
<tr>
<td>04/04/2015</td>
<td>Test Name 2</td>
<td>1</td>
</tr>
<tr>
<td>09/08/2017</td>
<td>Test Name 5</td>
<td>2</td>
</tr>
<tr>
<td>07/08/2015</td>
<td>Test Name 4</td>
<td>3</td>
</tr>
<tr>
<td>05/04/2015</td>
<td>Test Name 3</td>
<td>4</td>
</tr>
<tr>
<td>12/08/2017</td>
<td>Test Name 6</td>
<td>5</td>
</tr>
<tr>
<td>21/03/2014</td>
<td>Test Name 1</td>
<td>6</td>
</tr>
</tbody>
</table>
<button>Sort by date</button>

How to delete the last column in an HTML TABLE using by jquery?

I have an HTML TABLE:
<table id="persons" border="1">
<thead id="theadID">
<tr>
<th>Name</th>
<th>sex</th>
<th>Message</th>
</tr>
</thead>
<tbody id="tbodyID">
<tr>
<td>Viktor</td>
<td>Male</td>
<td>etc</td>
</tr>
<tr>
<td>Melissa</td>
<td>Female</td>
<td>etc</td>
</tr>
<tr>
<td>Joe</td>
<td>Male</td>
<td>etc</td>
</tr>
</tbody>
</table>
<input type="button" onclick="deleteLastColumn();" value="do it"/>
I need a javascript/jquery code, which delete the last column (message) in the table:
function deleteLastColumn() {
$("#theadID tr th:not(:last-child)......
$("#tbodyID tr td:not(:last-child)......
}
So the result should be this:
<table id="persons" border="1">
<thead id="theadID">
<tr>
<th>Name</th>
<th>sex</th>
</tr>
</thead>
<tbody id="tbodyID">
<tr>
<td>Viktor</td>
<td>Male</td>
</tr>
<tr>
<td>Melissa</td>
<td>Female</td>
</tr>
<tr>
<td>Joe</td>
<td>Male</td>
</tr>
</tbody>
</table>
I know there is the ":not(last)" method, but I can't find any example to my problem.
Could anyone help me?
Try
$('#persons tr').find('th:last-child, td:last-child').remove()
Demo: Fiddle
You can use this solution to achieve it easily..
function myFunction() {
var allRows = document.getElementById('my_table').rows;
for (var i=0; i< allRows.length; i++) {
allRows[i].deleteCell(-1);
}
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table id="my_table">
<thead >
<th>Column 1</td>
<th>Column 2</td>
<th>Column 3</td>
</thead >
<tr >
<td>Number 1</td>
<td>String 1</td>
<td>Decimal 1</td>
</tr>
<tr >
<td>Number 2</td>
<td>String 2</td>
<td>Decimal 2</td>
</tr>
<tr >
<td>Number 3</td>
<td>String 3</td>
<td>Decimal 3</td>
</tr>
</table><br>
<button onclick="myFunction()">Remove Last Column</button>
</body>
</html>
In addition to Arun P Johny's answer,
That would let you remove last row each time you click the button. If you just want to remove one column, not others you may try this.
function deleteLastColumn() {
$(document).find('.last').remove()
}
after adding class last to the last td and th of the table.
Demo : Fiddle

Responsive table, possible for nested table cell widths to inherit

I've got a responsive table, which has different content in each row and a concertina mechanism on each row.
The concertina essentially adds another table row beneath that current row, which has a td with a colspan for the amount of cells in the table.
Inside this concertina I have another table which I need the table cells to line up with the parent table. I appreciate this probably isn't possible with HTML/CSS alone and probably needs to be done with JS?
Or is there another way?
I can't post all my code here but here is a screenshot of what I mean
<table class="parent-table">
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
<td>Cell 6</td>
</tr>
<tr>
<td colspan="6" class="concertina">
<div>
<table>
<tr>
<td>Other 1</td>
<td>Other 2</td>
<td>Other 3</td>
<td>Other 4</td>
<td>Other 5</td>
<td>Other 6</td>
</tr>
</table>
</div>
</td>
</tr>
Short answer would be 'No', not possible just with HTML/CSS. I myself am working on a fixed-header, scrollable table with resizable columns, plus double-click column header border to autofit. It's far from complete, and I can tell you if that is roughly the direction you might be heading, you might want to take a deep breath.
UPDATES BELOW
Judging from the screenshot, have you considered revising the HTML structure?
From the markup below, you have multiple <tbody> sections, each with a first <tr> that contains <th> elements. The rest would be showing details data, rows of <tr> that contains typical <td> elements.
In jQuery, you can use $('tr:has(th)') to select the header row, and $('tr:has(td)') to select the data rows.
The last <th> in the header would house your "More/Less" control, which simply shows/hides the subsequent data rows.
Would this work for you instead?
<table class="master-table">
<tbody class="concertina">
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
<th>More</th>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
<td colspan="2">Cell 6</td>
</tr>
</tbody>
<tbody class="concertina">
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
<th>More</th>
</tr>
<tr>
<td>Cell 1</td>
<td>Cell 2</td>
<td>Cell 3</td>
<td>Cell 4</td>
<td>Cell 5</td>
<td colspan="2">Cell 6</td>
</tr>
</tbody>
</table>
Reset your tables using this bit of CSS:
table {
border-collapse: collapse;
border-spacing: 0;
}
Then you will have to set the width of the <td>s

Unexpected Behavior of :even pseudo selector in jquery

I have created this fiddle for problem as you will see there are three tables having zebra strip using jQuery.
Table 1 is showing in correct form as it start tr index from 0 as even. Table 2 is continuing from last table and it is showing 1st row as white instead of dark. I think it is happening due to it is continuing from last table's tr index.
HTML:
<table>
<caption> Table 1</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>
<table>
<caption> Table 2</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>
<table>
<caption> Table 3</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>​
JavaScript:
$('table').find('tr:even').css('background','#d0d0d0');
Fiddle: http://jsfiddle.net/daljir/gryh5/
You can use find() to 'work' with each table separately:
$("table").find("tr:even").css("background", "#d0d0d0");
DEMO: http://jsfiddle.net/gryh5/1/
You are selecting all the <tr> elements in the document, you can use the nth-child to selector to select all the even numbered <tr>s in the document.
$('table tr:nth-child(2n)').css('background','#d0d0d0');
http://jsfiddle.net/Kyle_Sevenoaks/gryh5/7/
This is because you are selecting all the tr's in general (irrespective of the table) and when they are stacked you would get this particular behavior.
Try this:
$('table').find('tr:even').css('background','#d0d0d0');
Check FIDDLE
This works
<table id="t1">
<caption> Table 1</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>
<table id="t2">
<caption> Table 2</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>
<table id="t3">
<caption> Table 3</caption>
<tr>
<th>Table Head 1</th>
<td>Table Data 1</td>
</tr>
<tr>
<th>Table Head 2</th>
<td>Table Data 2</td>
</tr>
<tr>
<th>Table Head 3</th>
<td>Table Data 3</td>
</tr>
</table>
and JS:
$(function(){
$('#t1 tr:even, #t2 tr:even, #t3 tr:even').css('background','#d0d0d0');
});
jsfiddle: http://jsfiddle.net/SnakeEyes/gryh5/2/
http://jsfiddle.net/gryh5/9/
$('table').each(function(){
$(this).find('tr').filter(':even').css('background','#d0d0d0');
});

Categories

Resources