Welcome to a tutorial on how to create a simple Javascript timetable. Yes, there are already plenty of such “Javascript timetable” libraries all over the Internet. So here’s my slightly different sharing, one that is as fuss-free as possible. Read on!
TABLE OF CONTENTS
JAVASCRIPT TIMETABLE
All right, let us now get into more details on how to create a simple HTML timetable with Javascript.
HOW TO USE & DEMO
<!-- (A) LOAD CSS & JS -->
<link rel="stylesheet" href="js-timetable.css">
<script src="js-timetable.js"></script>
<!-- (B) GENERATE TIMETABLE HERE -->
<div id="demo"></div>
<!-- (C) ATTACH TIMETABLE -->
<script>
timetable({
// (C1) REQUIRED
target: document.getElementById("demo"),
x: ["Morning", "Afternoon", "Night"],
y: ["Mon", "Tue", "Wed", "Thur", "Fri"],
data: [
{
txt: "Feed the Doge",
row: "2", col: "2/3",
color: "white", bg: "black",
click : () => { alert("Clicked!"); }
},
{
txt: "Walk the Doge",
row: "4", col: "3/4",
color: "#04ff00", bg: "#090099"
},
{
txt: "Play with Doge",
row: "6", col: "3",
color: "#fff", bg: "#aa18ad"
}
],
// (C2) OPTIONAL
gridX: "100px repeat(3, 1fr)",
gridY : "50px"
});
</script>
For those who just want to use this as a “plugin”, the code download is below, and here is a quick walkthrough:
- Load the CSS and Javascript. Captain Obvious at your service.
- Create an empty
<div>
for the timetable. - Call
timetable()
to generate the timetable.target
Target<div>
to generate the timetable.x
Header of the columns.y
Header of the rows.data
Timetable entries. Just a tiny note thatrow: 1
andcol: 1
are reserved for the headers.gridX
Manually specify the column width. Defaults to equal columnsrepeat(N, 1fr)
if not specified.gridY
The height of each header row. Defaults toauto
if not specified.
PART 1) THE JAVASCRIPT
1A) CONTAINER CSS
function timetable (instance) {
// (A) CSS
instance.target.classList.add("timetable");
if (instance.gridX == undefined) {
instance.gridX = `repeat(${instance.x.length+1}, 1fr)`;
}
instance.target.style.gridTemplateColumns = instance.gridX;
if (instance.gridY) {
instance.target.style.gridAutoRows = instance.gridY;
}
// ...
}
The first part of the script should be pretty self-explanatory. We are just adding CSS styles to the target
container – class="timetable"
, grid-template-columns
, and grid-auto-rows
if necessary.
1B) HELPER CLASS TO GENERATE CELLS
// (B) GENERATE CELLS HELPER FUNCTION
let celler = (data, css) => {
let cell = document.createElement("div");
cell.className = css;
if (typeof data == "string") { cell.innerHTML = data; }
else {
cell.innerHTML = data.txt;
cell.style = `grid-column:${data.col};grid-row:${data.row};color:${data.color};background:${data.bg}`;
if (instance.gridY) { cell.style.height = instance.gridY; }
if (data.click) { cell.onclick = data.click; }
}
instance.target.appendChild(cell);
};
Next, we have a celler()
helper function to create the “cells” for the grid. Not going into too many details, this is essentially just inserting <div class="cell">TEXT</div>
into the target
.
1C) GENERATE CELLS
// (C) FIRST ROW - EMPTY CELL | HEADER FOR X
celler(" ", "cell head");
for (let i of instance.x) { celler(i, "cell head"); }
// (D) FOLLOWING ROWS - HEADER FOR Y | EMPTY CELLS
for (let i=0; i<instance.y.length; i++) {
celler(instance.y[i], "cell head");
for (let j=0; j<instance.x.length; j++) { celler(" ", "cell"); }
}
// (E) ENTRIES
for (let i of instance.data) { celler(i, "cell entry"); }
- (C) Loop through the column header
x
, and generate the cells. - (D) Loop through and generate the rows
y
. - (E) Loop through the
data
entries, and generate the cells accordingly.
Yep, the end.
PART 2) THE CSS
/* (A) WHOLE PAGE */
* {
font-family: arial, sans-serif;
box-sizing: border-box;
}
/* (B) TIMETABLE WRAPPER */
.timetable {
display: grid;
position: relative;
}
/* (C) BLANK & HEADER CELLS */
.cell {
display: flex;
align-items: center;
padding: 10px;
border: 1px solid #efefef;
}
.head {
font-weight: 700;
justify-content: center;
color: #333;
background: #f9f9f9;
}
/* (D) ENTRY CELLS */
.entry {
position: absolute;
right: 0; left: 0; top: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
The “functional” parts of the CSS are:
- (B)
display: grid
to set the container into a grid layout. The number of columns and row height is set in the above Javascript. - (B & D) To overlay the “entry cells” over the existing blank cells.
.timetable { position: relative }
and.entry { position: absolute }
is the basic mechanic that allows the overlapping.right: 0; left: 0;
makes sure that the entry cells retain their “rightful width”, to span across N columns.- Lastly,
grid-column
andgrid-row
of the individual entry cells are specified in the Javascript. This will position where the timetable entry needs to be.
That’s about it. The rest are cosmetics.
DOWNLOAD & NOTES
Here is the download link to the example code, so you don’t have to copy-paste everything.
SORRY FOR THE ADS...
But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.
Buy Me A Coffee Code Boxx eBooks
EXAMPLE CODE DOWNLOAD
Click here for the source code on GitHub gist, just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXTRA BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
COMPATIBILITY CHECKS
- Arrow Functions – CanIUse
- CSS Grid – CanIUse
This example will work on all modern “Grade A” browsers.
LINKS & REFERENCES
- HTML CSS Timetable – Code Boxx
- Example on CodePen – Simple Javascript Timetable
THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!