Static/sticky Header Using Dynamic Table
Remove
<body onload="initialisePage('LW')">
and useDOMContentLoaded
instead as it happens much sooner than the documentload
event.load
is only fired after ALL resources/content has been loaded, including "non-essential" (non-DOM) content like images and external content like ad-banners, which means theload
event may be fired tens-of-seconds afterDOMContentLoaded
which makes theload
event kinda useless today).
Change your CSS to this:
table > thead > tr > th {
position: sticky;
top: 0;
z-index: 10;
}
table > tbody > tr.floated {
color: '#ffffff';
background-color: 'blue';
}
table > tbody > tr.broken {
background-color: '#00ff00';
}JavaScript uses
camelCase
for functions, values (variables and parameters) and properties, notPascalCase
.- Avoid
var
and useconst
andlet
in scripts where appropriate instead. Note thatconst
means "unchanging reference" (kinda like C++); it does not mean "immutable" or "compile-time constant value". I think this definition ofconst
was a mistake by the JavaScript language designers, but that's just, like, my opinion, man. - Use CSS classes via
classList
instead of setting individual style properties using.style
. - The current JavaScript ecosystem also generally uses 1TBS instead of the Allman style.
- Prefer
===
(exactly-equals) instead of==
(equals) because JavaScript's type coercion can be surprising). - Avoid using
innerHTML
wherever possible. Use.textContent
for setting normal text content (and avoid using.innerText
too). Misuse ofinnerHTML
leads to XSS vulnerabilities. - It's 2020. STOP USING JQUERY!!!!!!!!!!
- Cite
- Cite
- Cite
- Cite
- DONT USE ALL-CAPS IN YOUR JAVASCRIPT COMMENTS BECAUSE IT LOOKS LIKE THE AUTHOR IS SHOUTING AT YOU NEEDLESSLY AND IT GETS QUITE ANNOYING FOR OTHER READERS ARRRRGGGHHHHH
- You need to handle HTTP request responses correctly (e.g. to check for succesful responses with the correct
Content-Type
). - Avoid using
j
as an iterable variable name because it's too visually similar toi
. Change your JavaScript to this:
<script>
// You should put all of your own application-specific top-level page script variables in their own object so you can easily access them separately from the global `window` object.
const myPageState = {
loop : null,
fileName: null,
table : null
};
window.myPageState = myPageState; // In the top-level function, `const` and `let`, unlike `var`, do not create a global property - so you need to explicitly set a property like so: `window.{propertyName} = ...`.
window.addEventListener( 'DOMContentLoaded', onDOMLoaded );
function onDOMLoaded( ev ) {
window.myPageState.fileName = "LW";
window.myPageState.loop = setInterval( refreshTable, 500 );
}
async function refreshTable() {
if( typeof window.myPageState.fileName !== 'string' || window.myPageState.fileName.length === 0 ) return;
const url = "http://10.142.32.72/dashboard/" + window.myPageState.fileName + ".json";
const resp = await fetch( url );
if( resp.status === 200 && resp.headers['ContentType'] === 'application/json' ) {
const deserialized = await resp.json();
ceateAndPopulateTableFromJSONResponse( deserialized );
}
else {
// Error: unexpected response.
// TODO: error handling
// e.g. `console.error` or `throw new Error( "Unexpected response." )`, etc.
}
}
function ceateAndPopulateTableFromJSONResponse( myBooks ) {
// TODO: Verify the `myBooks` object layout (i.e. schema-verify `myBooks`).
const columnTitles = ["Page", "Slug", "Pres 1", "Pres 2", "CAM", "Format", "Clip Dur", "Total", "Backtime"];
const columnNames = ["page-number", "title", "pres1", "pres2", "camera", "format", "runs-time", "total-time", "back-time"];
const table = window.myPageState.table || document.createElement( 'table' );
if( window.myPageState.table !== table ) {
window.myPageState = table;
document.getElementById("showData").appendChild( table );
}
// Create the <thead>, if nnecessary:
if( table.tHead === null )
{
table.tHead = document.createElement( 'thead' );
const tHeadTR = table.tHead.insertRow(-1);
for( let i = 0; i < columnNames.length; i++ ) {
const th = document.createElement('th');
th.textContent = columnTitles[i];
tHeadTR.appendChild( th );
}
}
// Clear any existing tbody:
while( table.tBodies.length > 0 ) {
table.removeChild( table.tBodies[0] );
}
// Populate a new <tbody>:
{
const tbody = document.createElement('tbody');
for( let i = 0; i < myBooks.length; i++ ) {
const tr = table.insertRow(-1);
tr.classList.toggle( 'floated', myBooks[i]["floated"] === "true" );
tr.classList.toggle( 'broken' , myBooks[i]["break" ] === "true" && myBooks[i]["floated"] === "false" );
for( let c = 0; c < columnNames.length; c++ ) {
const td = tr.insertCell(-1);
const colName = columnNames[c];
td.textContent = myBooks[i][ colName ];
}
}
table.appendChild( tbody );
}
console.log( "Refreshed: " + window.myPageState.fileName );
}
</script>
How to Create HTML table with fixed header but dynamic column
You want something like this:
HTML
<div id="table">
<table>
<thead>
<tr>
<th>Column A</th>
<th id="flex-header">Column B</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<button value="3">3</button>
<button value="7">7</button>
JS
$(function () {
$("button").click(function (e) {
var cols = $(this).val();
// You'll want to do something here to get the column data
var data = $("<tr></tr>").append($("<td>Col 0</td>"));
for (i = 0; i < cols; i++) {
data.append($("<td>Col " + (i + 1) + "</td>"));
}
$("#flex-header").prop("colspan", cols);
$("#table table tbody").html("").append(data);
});
});
jsfiddle
This will allow you to change around the number of columns easily. Of course, there are other ways to do it (like the other answer with toggling tbody elements) but this should give you a little flexibility with the column counts.
EDIT
Here is an updated jsfiddle with the table toggle behavior.
CSS - HTML Table with dynamic width and ellipsis in header
If you are able to add an extra wrapper you can do like below. Using contain: inline-size
you tell the browser to ignore its content when defining the inline-size (the width in your case).
table,
tr > * {
border: 1px solid;
}
span {
display: block;
contain: inline-size; /* the content won't affect the size */
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
<table>
<thead>
<tr>
<th><span>Col 1</span></th>
<th><span>Column 2 header</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>Column 1 content</td>
<td>Column 2</td>
</tr>
</tbody>
</table>
How do I create an HTML table with a fixed/frozen left column and a scrollable body?
If you want a table where only the columns scroll horizontally, you can position: absolute
the first column (and specify its width explicitly), and then wrap the entire table in an overflow-x: scroll
block. Don't bother trying this in IE7, however...
Relevant HTML & CSS:
table {
border-collapse: separate;
border-spacing: 0;
border-top: 1px solid grey;
}
td,
th {
margin: 0;
border: 1px solid grey;
white-space: nowrap;
border-top-width: 0px;
}
div {
width: 500px;
overflow-x: scroll;
margin-left: 5em;
overflow-y: visible;
padding: 0;
}
.headcol {
position: absolute;
width: 5em;
left: 0;
top: auto;
border-top-width: 1px;
/*only relevant for first row*/
margin-top: -1px;
/*compensate for top border*/
}
.headcol:before {
content: 'Row ';
}
.long {
background: yellow;
letter-spacing: 1em;
}
<div>
<table>
<tr>
<th class="headcol">1</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">2</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">3</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">4</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">5</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
<tr>
<th class="headcol">6</th>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
<td class="long">QWERTYUIOPASDFGHJKLZXCVBNM</td>
</tr>
</table>
</div>
Related Topics
Horizontally Center <P> Within a Div While Keeping The Text Left-Aligned
How to Rotate a Font Icon 45 Degrees
100% Div Height Without Scrollbar
Prevent Highlighter Cursor in CSS
How to Get Bootstrap Tour to Work with a Jquery Dialog
CSS Color Names + Alpha Transparency
Using CSS Approach How to Set an Image to Fill a Path in Svg
Hiding Text Using "Text-Indent"
Text Gets Cut When Using <Select>
Less CSS Background with Relative Path
Styling Email Link/Href="Mailto:" with CSS
CSS Selector for Custom Qt Class
How to Make Bootstrap Icon Display Inline with Text in a Tag
Change The Color Profile of a Page in CSS
Angular 5: Fade Animation During Routing (CSS)
How to Apply Text-Align Left in The First Column and Text-Align Right in The Others