bingo-card-maker/index.html

220 lines
5.5 KiB
HTML
Raw Normal View History

2024-06-21 16:01:51 +00:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bingo Card Maker</title>
<style>
#bingo-cards table {
box-sizing: border-box;
border-collapse: collapse;
width: 100%;
height: 100%
table-layout: fixed;
}
#bingo-cards td {
border: 2px solid black;
height: 1in;
text-align: center;
font-size: 16pt;
}
#bingo-cards h1 {
text-align: center;
}
#words-input {
height: 30em;
width: 20em;
}
#title-input {
width: 20em;
}
.pagesep {
color: gray;
}
@media screen {
.noshow {
display: none;
}
}
@media print {
#bingo-controls {
display: none;
}
#bingo-cards .pagesep {
display: none;
}
#bingo-cards .bingo-card {
page-break-after: always;
}
}
</style>
<script>
function showError(msg) {
window.alert(msg);
}
function shuffle(arr) {
// Returns a random int n where 0 ≤ n < max
function randomInt(max) {
return Math.floor(Math.random() * max);
}
for (var i = arr.length - 1; i > 0; i--) {
var randi = randomInt(i+1);
var tmp = arr[i];
arr[i] = arr[randi];
arr[randi] = tmp;
}
}
function makeCard(title, words, includeFree, freeText) {
var width = 5;
var height = 5;
var freeIndex = 12;
var card = document.createElement("div");
card.className = "bingo-card";
card.innerHTML += "<div class='pagesep'>PAGE BREAK</div>";
card.innerHTML += "<h1>" + title + "</h1>";
var table = document.createElement("table");
var row;
for (var i=0; i < width * height; i++) {
if (i % width === 0) {
row = document.createElement("tr");
table.appendChild(row);
}
var cell = document.createElement("td");
cell.style.width = (100 / width) + "%";
if (includeFree) {
if (i === freeIndex) {
cell.innerText = freeText;
} else if (i < freeIndex) {
cell.innerText = words[i];
} else {
cell.innerText = words[i - 1];
}
} else {
cell.innerText = words[i];
}
row.appendChild(cell);
}
card.appendChild(table);
return card;
}
document.addEventListener("DOMContentLoaded", function() {
var titleInput = document.getElementById("title-input");
var wordsInput = document.getElementById("words-input");
var freeInput = document.getElementById("free-input");
var freeTextInput = document.getElementById("free-text-input");
var numberInput = document.getElementById("number-input");
var showInput = document.getElementById("show-input");
var createButton = document.getElementById("create-button");
var cards = document.getElementById("bingo-cards");
function updateShowCards() {
if (showInput.checked) {
cards.classList.remove("noshow");
} else {
cards.classList.add("noshow");
}
}
updateShowCards();
createButton.addEventListener("click", function() {
var wordsNeeded = 25;
if (freeInput.checked) {
wordsNeeded--;
}
// Validate free space text input
if (freeInput.checked && freeTextInput.value === "") {
showError("No free space text given");
return;
}
// Validate words input
var words = wordsInput.value.split("\n");
for (var i=0; i < words.length; i++) {
words[i] = words[i].trim();
}
words = words.filter(function(s) {
return s != "";
});
console.log(words.length)
if (words.length < wordsNeeded) {
showError("Not enough words");
return;
}
//Validate # of cards input
if (!numberInput.checkValidity() || isNaN(numberInput.valueAsNumber)) {
showError("Invalid number of cards");
return;
}
cards.innerHTML = "";
for (var i=0; i < numberInput.valueAsNumber; i++) {
shuffle(words);
var card = makeCard(titleInput.value, words, freeInput.checked, freeTextInput.value);
cards.appendChild(card);
}
window.print();
});
freeInput.addEventListener("change", function() {
freeTextInput.disabled = !freeInput.checked;
});
showInput.addEventListener("change", updateShowCards);
});
</script>
</head>
<body>
<div id="bingo-controls">
<h1>Bingo Card Maker</h1>
<p>
By Brandon Dyck<br>
Distributed under the terms of the <a href="https://opensource.org/licenses/BSD-3-Clause" target="_blank">3-clause BSD license</a>.
<p>
<label for="title-input">Title:</label><br>
<input id="title-input"></input>
</p>
<p>
<label for="words-input">Words:<br>(one per line; at least 24 w/ free space, or 25 otherwise)</label><br>
<textarea id="words-input"></textarea>
</p>
<p>
<input type="checkbox" id="free-input"></input>
<label for="free-input">Include free space</label>
</p>
<p>
<label for="free-text-input">Free space text:</label>
<input type="text" id="free-text-input" value="FREE" disabled></input>
</p>
<p>
<label for="number-input"># of cards (1100):</label>
<input type="number" min="1" max="100" value="1" id="number-input">
</p>
<p>
<input type="checkbox" id="show-input"></input>
<label for="show-input">Show cards</label>
</p>
<p>
<button id="create-button">Create & Print</button>
</p>
</div>
<div id="bingo-cards"></div>
</body>
</html>