Create Time Table Generator Using HTML, CSS, and JavaScript

Faraz

By Faraz -

Learn how to create a time table generator using HTML, CSS, and JavaScript with this easy step-by-step guide. Perfect for beginners and web developers.


create-time-table-generator-using-html-css-and-javascript.webp

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Conclusion
  6. Preview

Creating a time table generator can be a fun and practical project, especially for beginners in web development. With this project, you'll learn how to design a time table layout using HTML, style it with CSS, and add dynamic functionality using JavaScript. Whether you're a student looking to organize your study hours or a developer sharpening your coding skills, this step-by-step guide will help you create a simple yet effective time table generator.

Prerequisites:

Before diving into the project, you should have a basic understanding of:

  • HTML (to structure the page)
  • CSS (to style the page)
  • JavaScript (to add interactivity)

You can use any code editor like Visual Studio Code, and you should be able to run your code in a web browser (Chrome, Firefox, etc.).

Source Code

Step 1 (HTML Code):

The first step is to create the basic structure for your timetable generator. Open your code editor and create an HTML file named index.html.

In this code, we have the basic HTML structure with a heading, a table element to hold the timetable, and links to external CSS and JavaScript files.

Below is an explanation of the key components of the HTML code:

HTML Structure:

  1. <!DOCTYPE html>: This tells the browser that the document is an HTML5 document.
  2. <html lang="en">: Defines the root element of the HTML page and sets the language of the document to English.
  3. <head>:
    • <meta charset="UTF-8">: Sets the character encoding to UTF-8, which supports a wide range of characters.
    • <meta name="viewport" content="width=device-width, initial-scale=1.0">: Ensures the page is responsive and scales correctly on different devices.
    • <title>Timetable Generator</title>: Sets the title of the page, which appears on the browser tab.
    • <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">: Links to the Google Fonts API to use the "Roboto" font family.
    • <link rel="stylesheet" href="styles.css">: Links an external CSS file (styles.css) for styling.
  4. <body>:
    • The body contains the visible content of the page.

Main Content:

  1. <div class="container">: A container for the form and the timetable table.
  2. <h1 class="title">Timetable Generator</h1>: A heading for the page, titled "Timetable Generator."
  3. Form Section (<form id="timetable-form">):
    • Users can input the details of a subject they want to add to the timetable:
      • Subject Field (<input type="text" id="subject">): A text input for entering the subject name.
      • Start and End Time (<input type="time" id="start-time">, <input type="time" id="end-time">): Time inputs to define the start and end times for the subject.
      • Days Checkboxes (<input type="checkbox" value="Monday">): Checkboxes for selecting the days when the subject will be scheduled. Users can choose any combination of days from Monday to Saturday.
    • Button (<button type="submit" class="btn">): A button labeled "Add to Timetable" to submit the form and add the details to the timetable.
  4. Table Section (<table id="timetable">):
    • A table for displaying the timetable with days of the week as columns.
    • The <thead> contains the headers (<th>) for the time slots and the days from Monday to Saturday.
    • The <tbody> is initially empty but will be populated dynamically via JavaScript with the user’s input.

External Files:

  • CSS File (styles.css): The file that defines the styling (not included in this code but linked for customizing the look of the form, table, etc.).
  • JavaScript File (script.js): A script (also not shown here) to handle functionality such as capturing user input, adding data to the table, and managing the timetable entries.

Step 2 (CSS Code):

Next, create a new file named styles.css. In this file, we will add some simple CSS styles to make our time table look clean and organized. Here's an explanation of the CSS code:

Global Styles

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
  • The * selector targets all elements, resetting their default margin and padding to 0 to ensure consistent layout.
  • box-sizing: border-box ensures that padding and borders are included in the element’s total width and height.

Body Styles

body {
  font-family: 'Roboto', sans-serif;
  background-color: #f4f4f9;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  padding: 20px;
}
  • font-family: 'Roboto', sans-serif; applies the Roboto font to the entire page, falling back to a sans-serif font if unavailable.
  • background-color: #f4f4f9; sets a light gray background.
  • display: flex; justify-content: center; align-items: center; centers content horizontally and vertically.
  • height: 100vh; makes the body fill the full height of the viewport.
  • padding: 20px; adds space around the content to prevent it from touching the edges.

Container Styles

.container {
  max-width: 800px;
  background-color: #fff;
  padding: 30px;
  border-radius: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}
  • .container is a centered box with a maximum width of 800px.
  • background-color: #fff; gives it a white background.
  • padding: 30px; adds space inside the container.
  • border-radius: 12px; rounds the corners.
  • box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); adds a subtle shadow for a 3D effect.

Title Styles

.title {
  font-size: 2rem;
  text-align: center;
  margin-bottom: 20px;
  color: #333;
}
  • .title applies to headings.
  • font-size: 2rem; makes the text large.
  • text-align: center; centers the title text.
  • margin-bottom: 20px; adds space below the title.
  • color: #333; sets a dark gray text color.

Form Group Styles

.form-group {
  margin-bottom: 15px;
}
  • .form-group applies spacing to form sections, giving them 15px margin at the bottom.

Label Styles

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
  color: #555;
}
  • .form-group label makes labels block-level elements, ensuring they appear above input fields.
  • margin-bottom: 5px; adds space below the label.
  • font-weight: 500; makes the font slightly bold.
  • color: #555; sets a medium gray text color.

Input and Button Styles

input[type="text"], input[type="time"], .btn {
  width: 100%;
  padding: 10px;
  border-radius: 6px;
  border: 1px solid #ddd;
  font-size: 1rem;
}
  • Targets text, time inputs, and buttons.
  • width: 100%; makes them stretch to fill the width of their container.
  • padding: 10px; adds space inside the elements.
  • border-radius: 6px; rounds the corners slightly.
  • border: 1px solid #ddd; adds a light border.
  • font-size: 1rem; ensures consistent text size.

Checkbox Styles

input[type="checkbox"] {
  margin-right: 10px;
}
  • Adds 10px space to the right of checkboxes, separating them from labels.

Checkbox Group Styles

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
  • .checkbox-group makes checkboxes appear next to each other (flex).
  • gap: 10px; adds space between checkboxes.

Button Styles

.btn {
  background-color: #4CAF50;
  color: #fff;
  border: none;
  cursor: pointer;
  font-weight: 500;
  margin-top: 10px;
}
.btn:hover {
  background-color: #45a049;
}
  • .btn applies to buttons.
  • background-color: #4CAF50; gives the button a green background.
  • color: #fff; sets white text.
  • border: none; removes the default border.
  • cursor: pointer; changes the mouse cursor to a pointer on hover.
  • font-weight: 500; makes the button text bold.
  • margin-top: 10px; adds space above the button.
  • hover state changes the background to a darker green when hovered.

Timetable Styles

.timetable {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}
.timetable th, .timetable td {
  padding: 12px;
  text-align: center;
  border: 1px solid #ddd;
}
.timetable th {
  background-color: #4CAF50;
  color: white;
  font-weight: 500;
}
.timetable tr:nth-child(even) {
  background-color: #f2f2f2;
}
.timetable tr:hover {
  background-color: #ddd;
}
  • .timetable styles tables.
  • border-collapse: collapse; removes space between table cells.
  • th (header) and td (data) cells have padding for spacing, center-aligned text, and light borders.
  • th cells have a green background with white text.
  • Even rows alternate with a light gray background for readability.
  • Rows change color on hover for interactivity.
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Roboto', sans-serif;
  background-color: #f4f4f9;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  padding: 20px;
}

.container {
  max-width: 800px;
  background-color: #fff;
  padding: 30px;
  border-radius: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
}

.title {
  font-size: 2rem;
  text-align: center;
  margin-bottom: 20px;
  color: #333;
}

.form-group {
  margin-bottom: 15px;
}

.form-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: 500;
  color: #555;
}

input[type="text"], input[type="time"], .btn {
  width: 100%;
  padding: 10px;
  border-radius: 6px;
  border: 1px solid #ddd;
  font-size: 1rem;
}

input[type="checkbox"] {
  margin-right: 10px;
}

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.btn {
  background-color: #4CAF50;
  color: #fff;
  border: none;
  cursor: pointer;
  font-weight: 500;
  margin-top: 10px;
}

.btn:hover {
  background-color: #45a049;
}

.timetable {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}

.timetable th, .timetable td {
  padding: 12px;
  text-align: center;
  border: 1px solid #ddd;
}

.timetable th {
  background-color: #4CAF50;
  color: white;
  font-weight: 500;
}

.timetable tr:nth-child(even) {
  background-color: #f2f2f2;
}

.timetable tr:hover {
  background-color: #ddd;
} 

Step 3 (JavaScript Code):

Now, it's time to add functionality using JavaScript. Here's a detailed breakdown:

1. Form Submission Handling

document.getElementById('timetable-form').addEventListener('submit', function (e) {
  e.preventDefault();
  • This line listens for the "submit" event of the form with the ID timetable-form.
  • e.preventDefault(); prevents the form from submitting the traditional way (i.e., reloading the page). Instead, it allows custom JavaScript functionality to run.

2. Form Data Collection

  const subject = document.getElementById('subject').value;
  const startTime = document.getElementById('start-time').value;
  const endTime = document.getElementById('end-time').value;
  const selectedDays = getSelectedDays();
  • It collects values from input fields (subject, start-time, end-time) and stores them in variables.
  • getSelectedDays() is called to retrieve the days selected by the user (checkboxes).

3. Validation Check

  if (subject && startTime && endTime && selectedDays.length > 0) {
      addTimetableEntry(subject, startTime, endTime, selectedDays);
  } else {
      alert("Please fill in all the fields.");
  }
  • Checks if all fields (subject, startTime, endTime, and at least one selected day) are filled.
  • If valid, it calls addTimetableEntry() to add the timetable entry; otherwise, an alert pops up to ask the user to complete all fields.

4. Resetting the Form

  this.reset();
  • Resets the form fields after submission to clear the input for the next entry.

5. Get Selected Days

function getSelectedDays() {
  const days = document.querySelectorAll('#days input[type="checkbox"]:checked');
  return Array.from(days).map(day => day.value);
}
  • This function collects all checked checkboxes (days) from the form.
  • It converts the NodeList of checked checkboxes into an array using Array.from(), then maps this array to return their values (e.g., "Monday", "Tuesday").

6. Add Timetable Entry

function addTimetableEntry(subject, startTime, endTime, selectedDays) {
  const timetableBody = document.querySelector('#timetable tbody');
  let rowExists = false;
  let targetRow;
  • Gets the table body (#timetable tbody) where new timetable entries will be added.
  • Initializes variables rowExists to check if a time slot already exists and targetRow to store the row if found.

7. Check if Time Slot Exists

  Array.from(timetableBody.rows).forEach(row => {
      const rowTime = row.cells[0].textContent;
      if (rowTime === `${startTime} - ${endTime}`) {
          rowExists = true;
          targetRow = row;
      }
  });
  • Loops through existing rows in the timetable and checks if a row with the same startTime and endTime already exists.
  • If found, sets rowExists to true and stores that row in targetRow.

8. Update or Add a New Row

if (rowExists) {
      selectedDays.forEach(day => {
          const dayIndex = getDayIndex(day);
          targetRow.cells[dayIndex].innerHTML = subject;
      });
  } else {
      const newRow = document.createElement('tr');
      newRow.innerHTML = `<td>${startTime} - ${endTime}</td><td></td><td></td><td></td><td></td><td></td><td></td>`;
  • If the time slot already exists, it updates the relevant columns (days) in that row with the subject.
  • If not, it creates a new row with empty day columns and inserts the startTime - endTime into the first cell.

9. Add Subject to Selected Days

      selectedDays.forEach(day => {
          const dayIndex = getDayIndex(day);
          newRow.cells[dayIndex].innerHTML = subject;
      });
  • For each selected day, it finds the corresponding cell (by dayIndex) and fills it with the subject.

10. Insert Row in Order

      insertSortedRow(newRow, startTime, timetableBody);
  }
}
  • Calls insertSortedRow() to ensure the new row is inserted in the correct position based on time.

11. Insert Row Sorted by Time

function insertSortedRow(newRow, startTime, timetableBody) {
  const existingRows = Array.from(timetableBody.rows);
  • Gets all existing rows to compare the time for sorting.

12. Sort and Insert Row

  let inserted = false;
  for (let i = 0; i < existingRows.length; i++) {
      const rowTime = existingRows[i].cells[0].textContent.split(' - ')[0];
      if (compareTimes(startTime, rowTime)) {
          timetableBody.insertBefore(newRow, existingRows[i]);
          inserted = true;
          break;
      }
  }

  if (!inserted) {
      timetableBody.appendChild(newRow); 
  }
}
  • Loops through existing rows, comparing startTime of the new row with existing rows using compareTimes().
  • If a suitable position is found, it inserts the new row before the existing row.
  • If no earlier time is found, it appends the row to the end.

13. Compare Times

function compareTimes(time1, time2) {
  return time1 < time2;
}
  • Simple function that compares two times and returns true if time1 is earlier than time2.

14. Get Day Index

function getDayIndex(day) {
  const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  return days.indexOf(day) + 1;
}
  • Returns the index of the selected day in the array days.
  • Adds 1 because the first column of the row (index 0) is reserved for the time, so Monday starts at column 1.
document.getElementById('timetable-form').addEventListener('submit', function (e) {
  e.preventDefault();

  const subject = document.getElementById('subject').value;
  const startTime = document.getElementById('start-time').value;
  const endTime = document.getElementById('end-time').value;
  const selectedDays = getSelectedDays();

  if (subject && startTime && endTime && selectedDays.length > 0) {
      addTimetableEntry(subject, startTime, endTime, selectedDays);
  } else {
      alert("Please fill in all the fields.");
  }

  this.reset();
});

function getSelectedDays() {
  const days = document.querySelectorAll('#days input[type="checkbox"]:checked');
  return Array.from(days).map(day => day.value);
}

function addTimetableEntry(subject, startTime, endTime, selectedDays) {
  const timetableBody = document.querySelector('#timetable tbody');
  let rowExists = false;
  let targetRow;

  Array.from(timetableBody.rows).forEach(row => {
      const rowTime = row.cells[0].textContent;
      if (rowTime === `${startTime} - ${endTime}`) {
          rowExists = true;
          targetRow = row;
      }
  });

  if (rowExists) {
      selectedDays.forEach(day => {
          const dayIndex = getDayIndex(day);
          targetRow.cells[dayIndex].innerHTML = subject;
      });
  } else {
      const newRow = document.createElement('tr');
      newRow.innerHTML = `<td>${startTime} - ${endTime}</td><td></td><td></td><td></td><td></td><td></td><td></td>`;

      selectedDays.forEach(day => {
          const dayIndex = getDayIndex(day);
          newRow.cells[dayIndex].innerHTML = subject;
      });

      insertSortedRow(newRow, startTime, timetableBody);
  }
}

function insertSortedRow(newRow, startTime, timetableBody) {
  const existingRows = Array.from(timetableBody.rows);

  if (existingRows.length === 0) {
      timetableBody.appendChild(newRow);
  } else {
      let inserted = false;
      for (let i = 0; i < existingRows.length; i++) {
          const rowTime = existingRows[i].cells[0].textContent.split(' - ')[0];
          if (compareTimes(startTime, rowTime)) {
              timetableBody.insertBefore(newRow, existingRows[i]);
              inserted = true;
              break;
          }
      }

      if (!inserted) {
          timetableBody.appendChild(newRow); 
      }
  }
}

function compareTimes(time1, time2) {
  return time1 < time2;
}

function getDayIndex(day) {
  const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
  return days.indexOf(day) + 1;
}

Final Output:

create-time-table-generator-using-html-css-and-javascript.gif

Conclusion:

You've successfully created a basic time table generator using HTML, CSS, and JavaScript. This project helps you understand how to dynamically generate tables with JavaScript and style them with CSS. You can extend this project by allowing users to customize the time slots or subjects. You could even save the table as a downloadable file or make it editable directly on the page.

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post

Please allow ads on our site🥺