diff --git a/index.html b/index.html index 0aca890..123b55c 100644 --- a/index.html +++ b/index.html @@ -184,12 +184,28 @@ border-color: var(--box-border); } + /* Character roster box */ + + #cont-character-roster { + text-align: center; + } + + #btn-create-character { + display: none; + } + /* No character loaded box (AKA the welcome screen) */ #cont-no-loaded { text-align: center; } + div.or { + font-weight: bold; + text-transform: uppercase; + margin: .5em 0; + } + /* Character sheet */ #cont-character-sheet { @@ -268,8 +284,14 @@ Cypher Player Assistant ! +
+ + + +
- No character is loaded.
+ No character is loaded. Load one from the menu above +
— or —
@@ -371,9 +393,11 @@ const containerCharacter = document.getElementById("cont-character-sheet"); const containerCharacterID = document.getElementById("cont-character-id"); + const btnCreateCharacter = document.getElementById("btn-create-character"); const btnNoCharCreateCharacter = document.getElementById("btn-no-char-create-character"); const btnSaveCharacter = document.getElementById("btn-save-character"); + const inpCharacterRoster = document.getElementById("inp-character-roster"); const inpCampaignName = document.getElementById("inp-campaign-name"); const inpCharacterName = document.getElementById("inp-character-name"); const inpMaxEffort = document.getElementById("inp-max-effort"); @@ -429,6 +453,7 @@ const loadCharacter = (characterID) => { containerNoCharacter.style.display = "none"; containerCharacter.style.display = "initial"; + btnCreateCharacter.style.display = "initial"; clearSheet(); @@ -521,6 +546,55 @@ characterRoster[currentCharacter] = sheetToObject(); saveCharacterRoster(); + fillCharacterRoster(); + }; + + const fillCharacterRoster = () => { + var characterIDs = Object.keys(characterRoster).toSorted((idA, idB) => { + // Sort by campaign name first + if (characterRoster[idA].campaign < characterRoster[idB].campaign) return -1; + if (characterRoster[idA].campaign > characterRoster[idB].campaign) return 1; + + // Sort by character name within the same campaign + if (characterRoster[idA].name < characterRoster[idB].name) return -1; + if (characterRoster[idA].name > characterRoster[idB].name) return 1; + + // If all else fails, sort by the character ID + return (idA < idB) ? -1 : (idA > idB) ? 1: 0; + }); + + var placeHolder = inpCharacterRoster.options[0]; + + while (inpCharacterRoster.firstChild) { + inpCharacterRoster.removeChild(inpCharacterRoster.lastChild); + } + + inpCharacterRoster.appendChild(placeHolder); + + var currentGroup = null; + var previousCampaign = null; + + for (var characterID of characterIDs) { + if ((previousCampaign !== null) && (previousCampaign != characterRoster[characterID].campaign)) { + inpCharacterRoster.appendChild(currentGroup); + currentGroup = null; + } + + if (currentGroup === null) { + currentGroup = document.createElement("optgroup"); + currentGroup.label = characterRoster[characterID].campaign; + } + + var newOption = document.createElement("option"); + newOption.value = characterID; + newOption.appendChild(document.createTextNode(characterRoster[characterID].name)); + currentGroup.appendChild(newOption); + previousCampaign = characterRoster[characterID].campaign; + } + + if (currentGroup !== null) { + inpCharacterRoster.appendChild(currentGroup); + } }; const loadCharacterRoster = (doLocalStorageCheck) => { @@ -532,6 +606,7 @@ var newRoster = localStorage.getItem("character-roster"); characterRoster = (newRoster === null) ? {} : JSON.parse(newRoster); + fillCharacterRoster(); }; document.addEventListener( @@ -547,6 +622,7 @@ .forEach((elem) => {elem.addEventListener("change", toggleInputLockedHandler)}); btnNoCharCreateCharacter.addEventListener("click", createCharacter); + btnCreateCharacter.addEventListener("click", createCharacter); btnSaveCharacter.addEventListener("click", saveCurrentCharacter); clearSheet();