preparar misa: easier sharing and PDF generation

This commit is contained in:
Carlos Galindo 2026-01-23 21:00:25 +01:00
commit fbb5432c36

View file

@ -35,6 +35,17 @@ span.songSelector {
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
column-gap: 0.3em; column-gap: 0.3em;
}
input[type="button"].copy-success,
input[type="button"].copy-error {
color: white;
transition-duration: 0s;
}
input[type="button"].copy-success {
background-color: #4d9800;
}
input[type="button"].copy-error {
background-color: #e96857;
} }
</style> </style>
</head> </head>
@ -42,9 +53,7 @@ span.songSelector {
{% include "header.html" %} {% include "header.html" %}
<main> <main>
<h1>Preparar una misa</h1> <h1>Preparar una misa</h1>
<p>A continuación puedes crear una web con una lista de canciones y <p>A continuación puedes crear una web con una lista de canciones y compartirla copiando el enlace.</p>
<input type="button" onclick="shareList(event)" value="compartirla">.</p>
<p>Si prefieres crear un PDF, <a href="https://cgj.es/cancionero-generador/">pulsa aquí</a>.</p>
<p> <p>
<label class="forCheckbox"><input class="init" id="controlsCheckbox" type="radio" name="mode" onchange="toggleControls(event)" checked> Modificar la lista</label> <label class="forCheckbox"><input class="init" id="controlsCheckbox" type="radio" name="mode" onchange="toggleControls(event)" checked> Modificar la lista</label>
<label class="forCheckbox"><input class="init" id="previewCheckbox" type="radio" name="mode" onchange="togglePreview(event)"> Ver las canciones</label> <label class="forCheckbox"><input class="init" id="previewCheckbox" type="radio" name="mode" onchange="togglePreview(event)"> Ver las canciones</label>
@ -70,11 +79,8 @@ span.songSelector {
<button class="icon" onclick="clearSongs()"><img class="redFilter" src="svg/trash.svg"> Borrar todas</button> <button class="icon" onclick="clearSongs()"><img class="redFilter" src="svg/trash.svg"> Borrar todas</button>
</p> </p>
<div id="songlist"></div> <div id="songlist"></div>
<input type="button" onclick="shareList(event)" value="Compartir enlace al cancionero"> <input type="button" onclick="shareLink(event)" value="Copiar enlace al cancionero">
<dialog id="sharedialog"> <input type="button" onclick="sharePDF(event)" value="Crear un PDF ⤴">
<p>Copia y comparte el enlace: <a id="sharelink" href="">tus canciones</a></p>
<input type="button" onclick="event.target.parentElement.close()" value="Cerrar">
</dialog>
<template id='songtemplate'> <template id='songtemplate'>
<div><span class="controls songSelector"><select name="songs[]" required onchange="songSelect(event)"> <div><span class="controls songSelector"><select name="songs[]" required onchange="songSelect(event)">
<option value="">Selecciona una canción</option>{% for category, songs in categorized_songs %} <option value="">Selecciona una canción</option>{% for category, songs in categorized_songs %}
@ -121,6 +127,7 @@ function songDelete(event) {
const li = event.target.parentElement.parentElement; const li = event.target.parentElement.parentElement;
const ol = li.parentElement; const ol = li.parentElement;
ol.removeChild(li); ol.removeChild(li);
regenHash();
} }
function songSelect(event) { function songSelect(event) {
@ -133,11 +140,21 @@ function songSelect(event) {
} else { } else {
div.innerHTML = ""; div.innerHTML = "";
} }
if (loadComplete) regenHash();
}
function regenHash() {
const list = getSongList();
if (list.length == 0)
history.replaceState(null, "", window.location.pathname + window.location.search);
else
history.replaceState(null, "", "#" + getSongList().join(","));
} }
function clearSongs() { function clearSongs() {
const ol = document.getElementById("songlist"); const ol = document.getElementById("songlist");
ol.replaceChildren(); ol.replaceChildren();
regenHash();
} }
function selectRandomizeOptions(select, optionParent) { function selectRandomizeOptions(select, optionParent) {
@ -214,17 +231,36 @@ function toggleMode(controls) {
} }
} }
function shareList(event) { function shareLink(event) {
const res = getSongList(); const button = event.target;
if (res.length > 0) { const oldvalue = button.value;
let hash = res.join(","); button.style.width = button.offsetWidth + "px";
document.getElementById("sharelink").href = "#" + hash; if (location.hash != "") {
document.getElementById("sharedialog").showModal(); navigator.clipboard.writeText(window.location.href)
.then(() => {
button.value = "¡Copiado!";
button.classList.add("copy-success");
}, () => {
button.value = "Error al copiar";
button.classList.add("copy-error");
});
} else { } else {
alert("Tu cancionero no tiene canciones..."); button.value = "¡No hay canciones!";
button.classList.add("copy-error");
} }
setTimeout(() => {
button.value = oldvalue;
button.classList.remove("copy-success", "copy-error");
button.style.width = '';
}, 2000);
} }
function sharePDF(event) {
window.location.href = "https://cgj.es/cancionero-generador/" + window.location.hash;
}
var loadComplete = false;
window.addEventListener("load", function () { window.addEventListener("load", function () {
for (let e of document.getElementsByClassName("init")) { for (let e of document.getElementsByClassName("init")) {
e.dispatchEvent(new Event("change")); e.dispatchEvent(new Event("change"));
@ -240,10 +276,8 @@ window.addEventListener("load", function () {
let preview = document.getElementById("previewCheckbox"); let preview = document.getElementById("previewCheckbox");
preview.checked = true; preview.checked = true;
preview.dispatchEvent(new Event("change")); preview.dispatchEvent(new Event("change"));
let showChords = document.getElementById("showChords");
showChords.checked = false;
showChords.dispatchEvent(new Event("change"));
} }
loadComplete = true;
}); });
</script> </script>
{% include "footer.html" %} {% include "footer.html" %}