feat: Fill the character selector with the loaded characters’s list
This commit is contained in:
78
index.html
78
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
|
||||
<span id="warn-no-local-storage" title="Local Storage is not available. You can import/export data, but the app won’t save it between sessions!">!</span>
|
||||
</h1>
|
||||
<div id="cont-character-roster" class="box">
|
||||
<select id="inp-character-roster"><option value="">Choose a character to load</option></select>
|
||||
<button id="btn-load-character">Load Character</button>
|
||||
<button id="btn-create-character">Create Character</button>
|
||||
</div>
|
||||
<div id="cont-no-loaded" class="box">
|
||||
No character is loaded.<br>
|
||||
No character is loaded. Load one from the menu above
|
||||
<div class="or">— or —</div>
|
||||
<button id="btn-no-char-create-character">Create one</button>
|
||||
</div>
|
||||
<div id="cont-character-sheet">
|
||||
@@ -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();
|
||||
|
Reference in New Issue
Block a user