Simple Javascript Timetable (Free Download)

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!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

 

DOWNLOAD & DEMO

Firstly, here is the download link to the example code as promised.

 

QUICK NOTES

If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

EXAMPLE CODE DOWNLOAD

Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

HOW TO USE & DEMO

js-timetable.html
<!-- (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>

 

  1. Load the CSS and Javascript. Captain Obvious at your service.
  2. Create an empty <div> for the timetable.
  3. 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 that row: 1 and col: 1 are reserved for the headers.
    • gridX Manually specify the column width. Defaults to equal columns repeat(N, 1fr) if not specified.
    • gridY The height of each header row. Defaults to auto if not specified.

 

 

JAVASCRIPT TIMETABLE

All right, let us now get into more details on how the Javascript timetable works. This is for you guys who want to “deep customize” it.

 

PART 1) THE JAVASCRIPT

1A) CONTAINER CSS

js-timetable.js
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

js-timetable.js
// (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

js-timetable.js
// (C) FIRST ROW - EMPTY CELL | HEADER FOR X
celler("&nbsp;", "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("&nbsp;", "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

js-timetable.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 and grid-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.

 

 

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

This example will work on all modern “Grade A” browsers.

 

LINKS & REFERENCES

 

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!

Leave a Comment

Your email address will not be published. Required fields are marked *