Created
October 12, 2021 14:53
-
-
Save AndreasLonn/513e4432f7b502b8cbf897cd123e7ee8 to your computer and use it in GitHub Desktop.
A serverless HTML checklist that is run locally. Checked items are stored in localstorage in the web browser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is a serverless checklist that is run locally. Checked items are | |
stored in localstorage in the web browser. | |
The content is stored as a javascript array for quick interpretation. | |
The indentation of the array is ignored. The number first number in the | |
array in the list array represents the indentation, while the string | |
is the text to be displayed. The strings are NOT escaped, so the strings | |
can contain HTML elements like links. | |
--> | |
<!DOCTYPE html> | |
<html lang="sv"> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<!-- English: Checklist --> | |
<title>Checklista</title> | |
<style> | |
html { | |
font-family: Arial, Helvetica, sans-serif; | |
} | |
body { | |
margin: 0; | |
} | |
button { | |
position: fixed; | |
top: 20px; | |
right: 20px; | |
padding: 5px 10px; | |
} | |
ol { | |
display: flex; | |
flex-direction: column; | |
padding: 0; | |
} | |
ol li { | |
display: grid; | |
grid-template-columns: max-content auto; | |
padding: 0; | |
} | |
ol li:nth-child(2n) { | |
background-color: #ddd; | |
} | |
ol li.checked { | |
background-color: #0f06; | |
} | |
input[type="checkbox"] { | |
width: 20px; | |
height: 100%; | |
margin: 0; | |
} | |
label { | |
padding: 10px; | |
font-size: 20px; | |
} | |
@media (min-width: 1000px) { | |
body { | |
padding: 0 40px 40px 40px; | |
} | |
button { | |
right: 40px; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<!-- English: Checklist --> | |
<h1>Checklista</h1> | |
<!-- English: Clear --> | |
<button id="clear">Rensa</button> | |
<ol id="checklist"> | |
</ol> | |
<!-- The data file --> | |
<script src="data.js"></script> | |
<script> | |
/** | |
* Short for document.querySelector | |
*/ | |
function $(elem) { | |
return document.querySelector(elem); | |
} | |
// Set the title to the one supplied in data.js | |
document.title = titel; | |
$("h1").innerText = titel; | |
var checklist = $("#checklist"); | |
var localstorage = window.localStorage; | |
// Listen to checkboxes | |
checklist.addEventListener("input", event => { | |
// Make sure that the event is about checkboxes by | |
// checking that the ID start with "checkbox" | |
if(event.target.id.indexOf("checkbox") != 0) return; | |
// Update localstorage | |
localstorage.setItem(event.target.id, event.target.checked); | |
// Add or remove the "checked" class to the entire element | |
event.target.checked ? | |
event.target.parentElement.classList.add("checked") : | |
event.target.parentElement.classList.remove("checked"); | |
// Update the list children (not HTML children) when a parent element is updated. | |
let children = checklist.children; | |
// Start at the checked element and go through all elements while the indentation | |
// is less than the originally checked element | |
for(let i = event.target.id.substr(9) - 1 + 2; | |
(i < children.length && | |
children[i].getAttribute("data-i") > | |
event.target.parentElement.getAttribute("data-i")); i++) { | |
// Add or remove the "checked" class to the entire element | |
event.target.checked ? | |
children[i].classList.add("checked") : | |
children[i].classList.remove("checked"); | |
// Check or uncheck the checkbox | |
children[i].firstChild.checked = event.target.checked; | |
// Update localstorage | |
localstorage.setItem(children[i].firstChild.id, event.target.checked); | |
} | |
}); | |
// Handle clicks on the clear button | |
$("#clear").addEventListener("click", () => { | |
// English: "Do you really want to clear the checkmarks? (The list itself won't be affected)" | |
if(confirm("Vill du verkligen rensa kryssen? (Själva punkterna finns kvar)")) { | |
// Clear localstorage and reload the page | |
localstorage.clear(); | |
location.reload(); | |
} | |
}); | |
// Go through the array in data.js | |
list.forEach((element, i) => { | |
// Create the element | |
let newElement = document.createElement("li"); | |
// Read from localstorage | |
let checked = localstorage.getItem('checkbox_' + i) == "true"; | |
// Check the checkbox if localstorage says so | |
if(checked) newElement.classList.add("checked"); | |
// Set the indentation | |
newElement.setAttribute("data-i", element[0]); | |
// Fill the element with a checkbox and label | |
// As said at the top of the file, the list can contain HTML elements, | |
// so be careful what you put there, and ONLY use trusted data.js files | |
newElement.innerHTML = | |
`<input type="checkbox" ${checked ? "checked " : ""}id="checkbox_${i}" style="margin-left: ${element[0] * 50 + 10}px" /> | |
<label for="checkbox_${i}">${element[1]}</label>`; | |
// Add the element to the list | |
checklist.appendChild(newElement); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var titel = "Checklist"; | |
var list = [ | |
[0, "This is a sample data.js file"], | |
[0, "You can have indentation:"], | |
[1, "This is level one indentation"], | |
[2, "This is level 2"], | |
[3, "This is level 3"], | |
[5, "This is level 5"], | |
[0, "You have to \"escape\" some characters like \" and \\. This is done by putting a \\ in front: \\\" and \\\\"], | |
[0, "If you check me, my children will be checked as well"], | |
[1, "Hello! I'm a child"], | |
[2, "Hello! I'm another child"], | |
[0, "You can also put HTML elements inside the list elements <a href=\"\" onclick=\"alert('Hello!')\">like this link that displays an alert dialog when clicked</a>"], | |
[0, "You can do a lot with links, like email addresses <a href=\"mailto:[email protected]?subject=You can even set the subject!&body=And the body!\">Click here to open the email app!</a>"] | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment