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();