Skip to content

Instantly share code, notes, and snippets.

@xdpirate
Last active February 24, 2025 01:30
Show Gist options
  • Save xdpirate/dd978ecc9f314d199543556c78259079 to your computer and use it in GitHub Desktop.
Save xdpirate/dd978ecc9f314d199543556c78259079 to your computer and use it in GitHub Desktop.
HTML/JS template for making checklists. Download the file, edit the variables `checklistName`, `footerInformationHTML` and `checklists`, then open the HTML in your browser. Checklist states will be saved and can be cleared by clicking the link at the bottom of the page.
<html>
<head>
<title>Checklister</title>
<style>
html, body {
color: #e5e9f0;
background-color: #3b4252;
font-family: Arial, Helvetica, sans-serif;
}
h1, h2, h3, h4, h5 {
margin: 0;
width: 100%;
text-align: center;
}
.checklistArea {
border: 1px solid #d8dee9;
padding: 1em;
width: fit-content;
margin: 1em;
border-radius: 1em;
float: left;
}
ul {
list-style-type: none;
padding-left: 1em;
padding-right: 1em;
}
#footer, #clearDataDiv {
width: 100%;
text-align: center;
font-size: small;
clear: both;
}
a, a:visited {
color: #fff;
}
input[type="checkbox"]:checked + label {
text-decoration: line-through;
color: #888;
}
</style>
</head>
<body>
<script>
document.body.onload = function() {
// Define checklist name and sections
let checklistName = "Best. Checklist. Ever.";
let footerInformationHTML = `Made by somebody`;
let checklists = {
"Example Checklist": [
"Item",
"Another item",
"Yet another item",
],
"Chores": [
"Cook",
"Clean",
"Laundry",
"Dishes",
],
"The Gang": [
"Charlie",
"Dee",
"Mac",
"Dennis",
"Frank",
],
"Shopping" : [
"Chicken",
"Lettuce",
"Tomato sauce",
"Bacon",
"Cheese",
],
"Games to play": [
"Elden Ring",
"The Legend of Zelda: Tears of the Kingdom",
"Astro Bot",
"Pokemon Emerald Version",
"Shower With Your Dad Simulator"
]
};
// Build and populate checklists
document.getElementById("header").innerText = checklistName;
document.getElementById("footer").innerHTML = footerInformationHTML;
document.title = checklistName;
if(Object.keys(checklists).length > 0) {
let counter = 0;
let finalHTML = "";
// For each checklist...
for(let currentChecklist in checklists) {
let currChecklistHTML = `<div class="checklistArea"><h2><input type="checkbox" id="allcheckbox${counter}"><label for="allcheckbox${counter}">${currentChecklist}</label></h2><ul>`;
// For each checkbox within each checklist...
for(let i = 0; i < checklists[currentChecklist].length; i++) {
currChecklistHTML += `<li><input type="checkbox" id="checkbox${counter}_${i}"><label for="checkbox${counter}_${i}">${checklists[currentChecklist][i]}</label></li>`;
}
currChecklistHTML += `</ul></div>`;
finalHTML += currChecklistHTML;
counter++;
}
document.getElementById("checklistWrapper").innerHTML = finalHTML;
// For each checklist, assign handlers to the 'all' checkbox
for(let i = 0; i < counter; i++) {
document.getElementById(`allcheckbox${i}`).addEventListener("change", function() {
let currCheckboxes = document.querySelectorAll(`input[id^='checkbox${i}_']`);
for(let j = 0; j < currCheckboxes.length; j++) {
currCheckboxes[j].checked = this.checked;
currCheckboxes[j].dispatchEvent(new Event("change")); // Make sure state gets saved by individual checkbox handlers
}
});
}
}
// Load and pre-check saved checkboxes
let savedCheckboxes = [];
if(localStorage.savedCheckboxes) {
savedCheckboxes = JSON.parse(localStorage.savedCheckboxes);
for(let i = 0; i < savedCheckboxes.length; i++) {
let elem = document.getElementById(savedCheckboxes[i]);
if(elem) {
elem.checked = true;
}
}
}
document.querySelectorAll("input[type='checkbox']").forEach(checkbox => {
checkbox.addEventListener("change", function() {
if(this.checked) {
savedCheckboxes.push(this.id);
} else {
let index = savedCheckboxes.indexOf(this.id)
if(index > -1) {
savedCheckboxes.splice(index, 1);
}
}
localStorage.savedCheckboxes = JSON.stringify(savedCheckboxes);
});
});
}
</script>
<h1 id="header"></h1>
<div id="checklistWrapper"></div>
<div id="footer"></div>
<div id="clearDataDiv"><a href="#" onclick="localStorage.clear(); location.reload();">Clear data</a></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment