diff --git a/js/rulesAssistant/conditionEditor.js b/js/rulesAssistant/conditionEditor.js index eda0f1d63f27463f00e35e01595f1b3ef8caa342..349009179603ded4ffdfc94634288bb557f6a601 100644 --- a/js/rulesAssistant/conditionEditor.js +++ b/js/rulesAssistant/conditionEditor.js @@ -533,19 +533,22 @@ App.RA.Activation.Editor = (function() { /** * @typedef {"sub" | "div" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte"| "substr"} RulePairComparators - * @type {Map<RulePairComparators, string>} + * @typedef {object} RulePairComparatorDisplay + * @property {string} key + * @property {string} name + * @type {RulePairComparatorDisplay[]} */ - const rulePairComparators = new Map([ - ["eq", "="], - ["neq", "≠"], - ["lt", "<"], - ["gt", ">"], - ["lte", "⩽"], - ["gte", "⩾"], - ["sub", "-"], - ["div", "/"], - ["substr", "Contains"], - ]); + const rulePairComparators = [ + {key: "eq", name: "="}, + {key: "neq", name: "≠"}, + {key: "lt", name: "<"}, + {key: "gt", name: ">"}, + {key: "lte", name: "⩽"}, + {key: "gte", name: "⩾"}, + {key: "sub", name: "-"}, + {key: "div", name: "/"}, + {key: "substr", name: "Contains"}, + ]; class RulePair extends RuleContainer { /** @@ -574,30 +577,11 @@ App.RA.Activation.Editor = (function() { this._conditionalDropLocation(div, this._child1, child => this.child1 = child); // operator - let matchFound = false; - const select = document.createElement("select"); - for (const [key, name] of rulePairComparators) { - const el = document.createElement("option"); - el.value = key; - el.textContent = name; - if (this.mode === key) { - el.selected = true; - matchFound = true; - } - select.append(el); - } - if (!matchFound) { - select.selectedIndex = -1; - } - select.onchange = () => { - /** @type {HTMLSelectElement} */ + div.append(App.UI.DOM.makeSelect(rulePairComparators, this.mode, mode => { // @ts-ignore - const option = select.children.item(select.selectedIndex); - // @ts-ignore - this.mode = option.value; + this.mode = mode; refreshEditor(); - }; - div.append(select); + })); // element 2 this._conditionalDropLocation(div, this._child2, child => this.child2 = child); @@ -930,35 +914,21 @@ App.RA.Activation.Editor = (function() { App.UI.DOM.appendNewElement("span", span, this.mode === "assignment" ? "Assignment" : "Slave", ["rule-right-margin"]); // values - let matchFound = false; - let select = document.createElement("select"); - for (const [key, value] of this._getterMap) { - if (value.visible && !value.visible()) { - continue; - } - let el = document.createElement("option"); - el.value = key; - el.textContent = value.name; - if (value.enabled) { - el.disabled = !value.enabled(); - } - if (this.key === key) { - el.selected = true; - matchFound = true; + /** + * @type {selectOption[]} + */ + const options = []; + this._getterMap.forEach((getter, key) => { + if (!getter.visible || getter.visible()) { + options.push({ + key: key, name: getter.name, enabled: !getter.enabled || getter.enabled() + }); } - select.append(el); - } - if (!matchFound) { - select.selectedIndex = -1; - } - select.onchange = () => { - /** @type {HTMLSelectElement} */ - // @ts-ignore - const option = select.children.item(select.selectedIndex); - this.key = option.value; + }); + span.append(App.UI.DOM.makeSelect(options, this.key, key => { + this.key = key; refreshEditor(); - }; - span.append(select); + })); return span; } diff --git a/js/ui/select.js b/js/ui/select.js index 5de606ff1e3ce635f6085944c848a075864f1c9b..4eb0e69d4a075fc963ec377e59cc18e8eb8bc203 100644 --- a/js/ui/select.js +++ b/js/ui/select.js @@ -1,13 +1,19 @@ +/** + * @typedef {object} selectOption + * @property {string} key + * @property {string} name + * @property {boolean} [enabled] + */ + /** * Creates a new dropdown with available and unavailable options. - * @param {Array<{value: string, name: string}>} options A list of options to display, where `value` sets the property and `name` is displayed. - * @param {string} selected The property to change upon selection. - * @param {function():void} [onchange] Any custom function to run upon selection. - * @param {Object} [object] Any object `property` belongs to, if not the default `V`. + * @param {Array<selectOption>} options A list of options to display + * @param {string} selected + * @param {function(string):void} onchange * * @returns {HTMLSelectElement} */ -App.UI.DOM.makeSelect = function(options, selected, onchange, object = V) { +App.UI.DOM.makeSelect = function(options, selected, onchange) { const select = document.createElement("select"); let matchFound = false; @@ -15,13 +21,17 @@ App.UI.DOM.makeSelect = function(options, selected, onchange, object = V) { const option = document.createElement("option"); option.text = choice.name; - option.value = choice.value; + option.value = choice.key; - if (object[selected] === choice.value) { + if (selected === choice.key) { option.selected = true; matchFound = true; } + if ("enabled" in choice && !choice.enabled) { + option.disabled = true; + } + select.append(option); } @@ -29,13 +39,7 @@ App.UI.DOM.makeSelect = function(options, selected, onchange, object = V) { select.selectedIndex = -1; } - select.onchange = () => { - object[selected] = select.options[select.selectedIndex].value; - - if (onchange) { - onchange(); - } - }; + select.onchange = () => onchange(select.value); return select; }; diff --git a/src/events/RE/reNickname.js b/src/events/RE/reNickname.js index af3d36373850c43e77799fb260cc78b22848b317..80e0e7aba13a95a981762d5932067214e1a37341 100644 --- a/src/events/RE/reNickname.js +++ b/src/events/RE/reNickname.js @@ -81,48 +81,28 @@ App.Events.RENickname = class RENickname extends App.Events.BaseEvent { function selectCategory(cheat) { const el = new DocumentFragment(); if (cheat) { - const choice = App.UI.DOM.appendNewElement("span", el, `Select a category of nicknames `); - const select = App.UI.DOM.appendNewElement("select", choice); - let matchFound = false; + App.UI.DOM.appendNewElement("span", el, `Select a category of nicknames `); + const options = []; for (const category of qualifiedNicknames.keys()) { - const option = App.UI.DOM.appendNewElement("option", select, category); - option.value = category; - if (option.value === seed) { - option.selected = true; - matchFound = true; - } - } - if (!matchFound) { - select.selectedIndex = -1; + options.push({key: category, name: category}); } - select.onchange = () => { - const O = select.options[select.selectedIndex]; - seed = O.value; + el.append(App.UI.DOM.makeSelect(options, seed, value => { + seed = value; jQuery(intro).empty().append(introPassage()); - }; + })); } return el; } function selectNickname(cheat) { const el = new DocumentFragment(); if (cheat) { - const select = App.UI.DOM.appendNewElement("select", el); - let matchFound = false; + const options = []; for (const category of nicknameArray) { - const option = App.UI.DOM.appendNewElement("option", select, `'${category}'`); - option.value = category; - if (option.value === nickname) { - option.selected = true; - matchFound = true; - } - } - if (!matchFound) { - select.selectedIndex = -1; + options.push({key: category, name: `'${category}'`}); } - select.onchange = () => { - const O = select.options[select.selectedIndex]; - nickname = O.value; - }; + el.append(App.UI.DOM.makeSelect(options, nickname, name => { + nickname = name; + })); } else { App.UI.DOM.appendNewElement("span", el, `${nickname} `, "pink"); } diff --git a/src/events/randomEvent.js b/src/events/randomEvent.js index 462608e912ef4139484e39d00436f29a9bfeff11..348b86548877ac1767af54ceb3952aeb603fe723 100644 --- a/src/events/randomEvent.js +++ b/src/events/randomEvent.js @@ -456,21 +456,17 @@ App.Events.playRandomIndividualEvent = function() { if (V.RIESkip.length > 0) { countPara.append(` An event has already played for ${toSentence(V.RIESkip.map(s => SlaveFullName(getSlave(s))))}, so they are not eligible to play another.`); } + const slaveDiv = App.UI.DOM.appendNewElement("div", d, "Show events for this slave: "); - const slaveDropdown = App.UI.DOM.appendNewElement("select", slaveDiv); + const options = []; const startingSlave = eligibleSlaves.random(); for (const s of eligibleSlaves) { - const choice = App.UI.DOM.appendNewElement("option", slaveDropdown, SlaveFullName(s)); - choice.value = s.ID.toString(); - if (s.ID === startingSlave.ID) { - choice.selected = true; - } + options.push({key: s.ID.toString(), name: SlaveFullName(s)}); } - slaveDropdown.onchange = () => { - const O = slaveDropdown.options[slaveDropdown.selectedIndex]; - const slaveID = parseInt(O.value); - writeEventList(getSlave(slaveID)); - }; + slaveDiv.append(App.UI.DOM.makeSelect(options, startingSlave.ID.toString(), slaveID => { + writeEventList(getSlave(parseInt(slaveID))); + })); + App.UI.DOM.appendNewElement("p", d, "One of the following individual events would have been chosen for this slave."); const linkList = App.UI.DOM.appendNewElement("div", d, '', "event-section"); diff --git a/src/events/reRecruit.js b/src/events/reRecruit.js index a205f532c2af58e6178ed63e195e9b0cd2aa8ecf..f182c1b76f038dace1f3307d085cd45b975cfbd7 100644 --- a/src/events/reRecruit.js +++ b/src/events/reRecruit.js @@ -112,18 +112,13 @@ App.Events.RERecruit = class RERecruit extends App.Events.BaseEvent { if (V.debugMode && V.debugModeEventSelection) { const el = App.UI.DOM.appendNewElement("span", node); App.UI.DOM.appendNewElement("span", el, `One of the following recruitment events would have appeared: `); - const select = App.UI.DOM.appendNewElement("select", el); const evList = this.eventList.filter(e => App.Events.canExecute(e)); - for (const ev of evList) { - const choice = App.UI.DOM.appendNewElement("option", select, ev.eventName); - choice.value = ev.eventName; - } - select.selectedIndex = -1; - select.onchange = () => { - const O = select.options[select.selectedIndex]; + el.append(App.UI.DOM.makeSelect(evList.map(e => { + return {key: e.eventName, name: e.eventName}; + }), null, e => { el.remove(); - evList.find(ev => ev.eventName === O.value).execute(node); - }; + evList.find(ev => ev.eventName === e).execute(node); + })); } else { // forward execution to the delegate event this.params.event.execute(node); diff --git a/src/facilities/surgery/surgeryPassageExotic.js b/src/facilities/surgery/surgeryPassageExotic.js index d0db94c1977012723fb543181cea8a6d245194ba..01d28af97829faa79bdbfcfe217aba43cc3a2b5b 100644 --- a/src/facilities/surgery/surgeryPassageExotic.js +++ b/src/facilities/surgery/surgeryPassageExotic.js @@ -105,10 +105,10 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) { function retroVirus() { const el = new DocumentFragment(); const slaveGeneList = App.UI.DOM.appendNewElement("ul", el); - const select = App.UI.DOM.makeElement("select", null, "choices"); const canEditGenes = slave.indentureRestrictions === 0 && slave.health.health >= 0; - select.classList.add("rajs-list"); const description = App.UI.DOM.appendNewElement("div", el, null); + + const options = /** @type {selectOption[]} */ []; for (const gene in slave.geneticQuirks) { const geneData = App.Data.geneticQuirks.get(gene); @@ -132,18 +132,13 @@ App.UI.surgeryPassageExotic = function(slave, refreshParent, cheat = false) { continue; } if (canEditGenes) { - const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(geneData.title)); - choice.value = gene; - select.append(choice); + options.push({key: gene, name: capFirstChar(geneData.title)}); } } if (canEditGenes) { - select.selectedIndex = -1; - select.onchange = () => { - // selectedGene = select.options[select.selectedIndex]; - jQuery(description).empty().append(describeGene(select.value)); - }; - el.append(select); + el.append(App.UI.DOM.makeSelect(options, null, gene => { + jQuery(description).empty().append(describeGene(gene)); + })); } return el; diff --git a/src/facilities/toyShop/toyShop.js b/src/facilities/toyShop/toyShop.js index 4e910d977a1da986d7ac2637f112a4c07f12b59d..300d5b90b6cf74ef7047326a836ffa9ff0b19b36 100644 --- a/src/facilities/toyShop/toyShop.js +++ b/src/facilities/toyShop/toyShop.js @@ -326,32 +326,21 @@ App.UI.toyShop = function() { /** * @param {toy} toy * @param {string} itemKey - * @returns {DocumentFragment} + * @returns {HTMLElement} */ function selectDesign(toy, itemKey) { - const el = new DocumentFragment(); - const choice = App.UI.DOM.appendNewElement("span", el, ` or choose an existing design to edit `); - const select = App.UI.DOM.appendNewElement("select", choice); - let matchFound = false; + const choice = App.UI.DOM.makeElement("span", ` or choose an existing design to edit `); + const options = []; for (const [key, values] of V.customItem[itemKey]) { - const option = App.UI.DOM.appendNewElement("option", select, values.name); - option.value = key; - if (option.value === toy.name) { - option.selected = true; - matchFound = true; - } - } - if (!matchFound) { - select.selectedIndex = -1; + options.push({key: key, name: values.name}); } - select.onchange = () => { - const O = select.options[select.selectedIndex]; - toy.selected = O.value; + choice.append(App.UI.DOM.makeSelect(options, toy.name, key => { + toy.selected = key; toy.name = toy.selected; toy.data = V.customItem[itemKey].get(toy.selected); refresh(); - }; - return el; + })); + return choice; } function refresh() { diff --git a/src/futureSocieties/fsPassage.js b/src/futureSocieties/fsPassage.js index dbf0835259b3b482b5b6f69ac1bbf8c17bcb8855..31e77af51fb4d8151f6d1c534f2ce13526773951 100644 --- a/src/futureSocieties/fsPassage.js +++ b/src/futureSocieties/fsPassage.js @@ -372,21 +372,14 @@ App.UI.fsPassage = function() { r.push(`${arc.FSSupremacistRace} superiority.`); } r.push(`Select race:`); - const select = document.createElement("select"); - r.push(select); + const options = []; for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSubjugationistRace)) { // Subjugation race cannot be superior, so remove - const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(race)); - choice.value = race; - if (race === arc.FSSupremacistRace) { - choice.selected = true; - } + options.push({key: race, name: capFirstChar(race)}); } - - select.onchange = () => { - const O = select.options[select.selectedIndex]; - arc.FSSupremacistRace = O.value; + r.push(App.UI.DOM.makeSelect(options, arc.FSSupremacistRace, race => { + arc.FSSupremacistRace = /** @type {FC.Race} */ (race); App.UI.reload(); - }; + })); } else { /* <span class="note"><span style="font-weight:Bold">Racial Supremacism:</span> a belief in the superiority of a chosen race.</span>*/ } @@ -415,22 +408,15 @@ App.UI.fsPassage = function() { r.push(`${arc.FSSubjugationistRace} inferiority.`); } r.push(`Select race:`); - const select = document.createElement("select"); - r.push(select); + const options = []; for (const race of App.Utils.getRaceArrayWithoutParamRace(arc.FSSupremacistRace)) { // Superior race cannot be subj, so remove - const choice = App.UI.DOM.appendNewElement("option", select, capFirstChar(race)); - choice.value = race; - if (race === arc.FSSubjugationistRace) { - choice.selected = true; - } + options.push({key: race, name: capFirstChar(race)}); } - - select.onchange = () => { - const O = select.options[select.selectedIndex]; - arc.FSSubjugationistRace = O.value; + r.push(App.UI.DOM.makeSelect(options, arc.FSSubjugationistRace, race => { + arc.FSSubjugationistRace = race; App.UI.reload(); - }; + })); } else { /* <span class="note"><span style="font-weight:Bold">Racial Subjugationism:</span> a belief in the inferiority of a subject race.</span>*/ } diff --git a/src/gui/options/optionsGroup.js b/src/gui/options/optionsGroup.js index c49892ec2149452801e93eb75c9acdc3e5275a03..b7403c7b291452cc87043757b2b1925de9405f4b 100644 --- a/src/gui/options/optionsGroup.js +++ b/src/gui/options/optionsGroup.js @@ -268,36 +268,21 @@ App.UI.OptionsGroup = (function() { buttonGroup.append(button); } } else { - let matchFound = false; - let select = document.createElement("select"); - - for (const value of this.valuePairs) { - let el = document.createElement("option"); - el.textContent = value.name; - el.value = value.value; - if (this.object[this.property] === value.value) { - el.selected = true; - matchFound = true; + const options = this.valuePairs.map(value => { + return {key: value.value, name: value.name}; + }); + buttonGroup.append(App.UI.DOM.makeSelect(options, this.object[this.property], value => { + if (!isNaN(Number(value))) { + // @ts-ignore + value = Number(value); } - select.appendChild(el); - } - if (!matchFound) { - select.selectedIndex = -1; - } - select.onchange = () => { - const O = select.options[select.selectedIndex]; - if (isNaN(Number(O.value))) { - this.object[this.property] = O.value; - } else { - this.object[this.property] = Number(O.value); - } - const originalObj = this.valuePairs.find(obj => obj.name === O.textContent); + this.object[this.property] = value; + const originalObj = this.valuePairs.find(obj => obj.value === value); if (originalObj && typeof originalObj.callback === "function") { originalObj.callback(originalObj.value); } refresh(); - }; - buttonGroup.append(select); + })); } if (this.textbox) { diff --git a/src/interaction/prostheticConfig.js b/src/interaction/prostheticConfig.js index 44147410af15659fb89f0fca0c1fedfcbf71e45b..9a64ec644b246b8b9dc56fb3a13121a187343c6b 100644 --- a/src/interaction/prostheticConfig.js +++ b/src/interaction/prostheticConfig.js @@ -324,30 +324,19 @@ App.UI.prostheticsConfig = function(slave) { return f; function tailSelect() { - const frag = new DocumentFragment(); - const sortedTails = Array.from(App.Data.modTails.keys()).sort((a, b) => a > b ? 1 : -1); - const select = App.UI.DOM.appendNewElement("select", frag); - let matchFound = false; - for (const shape of sortedTails) { - const option = App.UI.DOM.appendNewElement("option", select, App.Data.modTails.get(shape).animal); - option.value = shape; - if (option.value === slave.tailShape) { - option.selected = true; - matchFound = true; - } - } - if (!matchFound) { - select.selectedIndex = -1; - } - select.onchange = () => { + const sortedTails = Array.from(App.Data.modTails.keys()) + .sort((a, b) => a > b ? 1 : -1) + .map(tail => { + return {key: tail, name: App.Data.modTails.get(tail).animal}; + }); + return App.UI.DOM.makeSelect(sortedTails, slave.tailShape, tail => { V.prostheticsConfig = "attachTail"; slave.tail = "mod"; - slave.tailShape = select.options[select.selectedIndex].value; + slave.tailShape = /** @type {FC.TailShape} */ (tail); slave.tailColor = (slave.tailColor === "none") ? slave.hColor : slave.tailColor; // if color not set yet, match hair. cashX(forceNeg(V.modCost), "slaveMod", slave); App.UI.reload(); - }; - return frag; + }); } } diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js index b8809b420e4f32bab016593c5a7a28d8f927b72d..c1172b62ab8ab6a0ba661320d8bcd29aa35e7357 100644 --- a/src/js/slaveListing.js +++ b/src/js/slaveListing.js @@ -549,10 +549,13 @@ App.UI.SlaveList.sortingLinks = function(passage) { let span = App.UI.DOM.makeElement("span", "Sort by: "); let order = ["devotion", "trust", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome", "health", "weight", "muscles", "intelligence", "sexDrive", "pregnancy", "prestige"]; const orderMap = order.map(so => { - return {value: so, name: textify(so)}; + return {key: so, name: capFirstChar(so)}; }); - div.append(App.UI.DOM.makeSelect(orderMap, 'sortSlavesBy', App.UI.reload)); + div.append(App.UI.DOM.makeSelect(orderMap, V.sortSlavesBy, val => { + V.sortSlavesBy = val; + App.UI.reload(); + })); span = App.UI.DOM.makeElement("span", " Sort direction: "); order = ["descending", "ascending"]; diff --git a/src/markets/specificMarkets/customSlaveMarket.js b/src/markets/specificMarkets/customSlaveMarket.js index 139c7d8a6c366b63b6b118e3c9fdf18381d766f4..a9b76aeb00edf580c1e03fbb0d5dbc2bd51c6b7f 100644 --- a/src/markets/specificMarkets/customSlaveMarket.js +++ b/src/markets/specificMarkets/customSlaveMarket.js @@ -62,33 +62,23 @@ App.Markets["Custom Slave"] = function() { createDescription(el, description, "age"); // Choices - const select = document.createElement("select"); + const options = []; for (let i = 0; i < ages.length; i++) { const high = ages[i]; - const low = (ages[i - 1] + 1 ) || (ages[i] - 1); // First element of array has nothing before it, obviously, so display low as one less than high. + const low = (ages[i - 1] + 1) || (ages[i] - 1); // First element of array has nothing before it, obviously, so display low as one less than high. if (low < V.minimumSlaveAge) { continue; } else if (high > V.retirementAge) { - const option = document.createElement("option"); - option.text = `${low}+`; - option.value = low.toString(); - select.append(option); + options.push({key: low.toString(), name: `${low}+`}); break; } - const option = document.createElement("option"); - option.text = `${low}-${high}`; - option.value = high.toString(); - if (slave.age === high) { - option.selected = true; - } - select.append(option); + options.push({key: high.toString(), name: `${low}-${high}`}); } - select.onchange = () => { - slave.age = Number(select.options[select.selectedIndex].value); + el.append(App.UI.DOM.makeSelect(options, slave.age.toString(), a => { + slave.age = Number(a); jQuery("#age-text").empty().append(description()); - }; - el.append(select); + })); return el; function description() { @@ -297,32 +287,18 @@ App.Markets["Custom Slave"] = function() { function race() { const el = document.createElement("div"); const slaveProperty = "race"; - const choices = new Map([ - ["ethnicity is unimportant", "Ethnicity is unimportant"], - ]); + const choices = [{key: "ethnicity is unimportant", name: "Ethnicity is unimportant"}]; for (const [race, capRace] of App.Data.misc.filterRacesPublic) { - choices.set(race, capRace); + choices.push({key: race, name: capRace}); } createDescription(el, description, slaveProperty); // Choices - - const select = document.createElement("select"); - for (const [value, text] of choices) { - const option = document.createElement("option"); - option.text = text; - option.value = value; - if (slave.race === option.value) { - option.selected = true; - } - select.append(option); - } - select.onchange = () => { - slave.race = select.options[select.selectedIndex].value; + el.append(App.UI.DOM.makeSelect(choices, slave.race, r => { + slave.race = r; jQuery("#race-text").empty().append(description()); - }; - el.append(select); + })); function description() { const el = new DocumentFragment(); @@ -345,31 +321,18 @@ App.Markets["Custom Slave"] = function() { function skin() { const el = document.createElement("div"); const slaveProperty = "skin"; - const choices = new Map([ - ["left natural", "Left natural"] - ]); + const choices = [{key: "left natural", name: "Left natural"}]; for (const skin of App.Medicine.Modification.naturalSkins) { - choices.set(skin, capFirstChar(skin)); + choices.push({key: skin, name: capFirstChar(skin)}); } createDescription(el, description, slaveProperty); // Choices - const select = document.createElement("select"); - for (const [value, text] of choices) { - const option = document.createElement("option"); - option.text = text; - option.value = value; - if (slave.skin === option.value) { - option.selected = true; - } - select.append(option); - } - select.onchange = () => { - slave.skin = select.options[select.selectedIndex].value; + el.append(App.UI.DOM.makeSelect(choices, slave.skin, s => { + slave.skin = s; jQuery("#skin-text").empty().append(description()); - }; - el.append(select); + })); function description() { const el = new DocumentFragment(); @@ -942,38 +905,26 @@ App.Markets["Custom Slave"] = function() { function nationality() { const el = document.createElement("div"); const slaveProperty = "nationality"; - const choices = new Map([ - ["slave", "Slave"], - ["Stateless", "Stateless"], - ["Nationality is unimportant", "Nationality is unimportant"], - ]); + const choices = [{key: "slave", name: "Slave"}, + {key: "Stateless", name: "Stateless"}, + {key: "Nationality is unimportant", name: "Nationality is unimportant"}, + ]; for (const nationality of App.Data.misc.baseNationalities) { - choices.set(nationality, nationality); + choices.push({key: nationality, name: nationality}); } createDescription(el, description, slaveProperty); // Choices - const select = document.createElement("select"); - for (const [value, text] of choices) { - const option = document.createElement("option"); - option.text = text; - option.value = value; - if (slave.nationality === option.value) { - option.selected = true; - } - select.append(option); - } - select.onchange = () => { - slave.nationality = select.options[select.selectedIndex].value; + el.append(App.UI.DOM.makeSelect(choices, slave.nationality, nat => { + slave.nationality = nat; jQuery("#nationality-text").empty().append(description()); - }; - el.append(select); + })); function description() { - for (const [value, text] of choices) { - if (slave.nationality === value) { - return `${text}. `; + for (const choice of choices) { + if (slave.nationality === choice.key) { + return `${choice.name}. `; } } } diff --git a/src/markets/specificMarkets/prestigiousSlave.js b/src/markets/specificMarkets/prestigiousSlave.js index f8e3e6bf4052a2aeec6bc92255159745dd42db2e..20e721233a79f1111bbd254f8d6908fe5d76cf97 100644 --- a/src/markets/specificMarkets/prestigiousSlave.js +++ b/src/markets/specificMarkets/prestigiousSlave.js @@ -49,19 +49,12 @@ App.Markets["Prestigious Slave"] = function() { content.append(passage()); }; const cheatOptions = (V.seeDicks > 0) ? options.concat(...dickOptions) : Array.from(options); - const slaveDropdown = App.UI.DOM.appendNewElement("select", frag); - for (const o of cheatOptions) { - const choice = App.UI.DOM.appendNewElement("option", slaveDropdown, capFirstChar(o)); - choice.value = o; - if (seed === o) { - choice.selected = true; - } - } - slaveDropdown.onchange = () => { - const O = slaveDropdown.options[slaveDropdown.selectedIndex]; - seed = O.value; + frag.append(App.UI.DOM.makeSelect(cheatOptions.map(v => { + return {key: v, name: capFirstChar(v)}; + }), seed, v => { + seed = v; reload(); - }; + })); App.UI.DOM.appendNewElement("span", frag, App.UI.DOM.link(" Refresh slave", reload)); } slave = makeSlave(seed); diff --git a/src/npc/startingGirls/startingGirls.js b/src/npc/startingGirls/startingGirls.js index 0d9ed58d2837caa395ef9ada7e3716877d9f1d40..7fec854b2252b3b7e6cdaddffe3d8cdd14265d4c 100644 --- a/src/npc/startingGirls/startingGirls.js +++ b/src/npc/startingGirls/startingGirls.js @@ -1604,20 +1604,15 @@ App.StartingGirls.makeCareerFilterPulldown = function() { const frag = new DocumentFragment(); frag.append(`Filter by desired bonus: `); - const select = document.createElement("select"); - select.style.fontStyle = "normal"; + const options = []; for (const cat of App.StartingGirls.careerBonusFilters.keys()) { - const choice = App.UI.DOM.appendNewElement("option", select, cat); - if (App.StartingGirls.careerFilter === cat) { - choice.selected = true; - } + options.push({key: cat, name: cat}); } - - select.onchange = () => { - App.StartingGirls.careerFilter = select.value; + frag.append(App.UI.DOM.makeSelect(options, App.StartingGirls.careerFilter, cat => { + App.StartingGirls.careerFilter = cat; App.UI.reload(); - }; - frag.append(select); + })); + return frag; }; diff --git a/src/npc/startingGirls/startingGirlsPassage.js b/src/npc/startingGirls/startingGirlsPassage.js index 9d158c14c4e70a6bfc10cafd181ab34ea1d00071..b6ef844e4bbd59402b0715b4694b5ce8250aa9b4 100644 --- a/src/npc/startingGirls/startingGirlsPassage.js +++ b/src/npc/startingGirls/startingGirlsPassage.js @@ -339,18 +339,20 @@ App.StartingGirls.passage = function() { `Start over with a finalized slave's relative`, () => { const el = new DocumentFragment(); - const select = App.UI.DOM.appendNewElement("select", el); + + const options = []; for (const slave of newSlaves) { - const option = App.UI.DOM.appendNewElement("option", select, `${SlaveFullName(slave)} (${slave.genes}, ${slave.actualAge})`); - option.value = slave.ID.toString(); + options.push({ + key: slave.ID.toString(), + name: `${SlaveFullName(slave)} (${slave.genes}, ${slave.actualAge})` + }); } - select.selectedIndex = -1; - select.onchange = () => { - const ID = Number.parseInt(select.options[select.selectedIndex].value); - const srcSlave = getSlave(ID); + const select = App.UI.DOM.makeSelect(options, null, slaveID => { + const srcSlave = getSlave(Number.parseInt(slaveID)); jQuery(linkDiv).empty().append(relativeLinkStrip(srcSlave, srcSlave)); - }; + }); App.UI.DOM.appendNewElement("div", el, App.UI.DOM.combineNodes(`Relative of slave: `, select)); + const linkDiv = App.UI.DOM.appendNewElement("div", el, ``); App.UI.DOM.appendNewElement("div", el, "Warning: related slaves will influence each others' opinion of you, and may become difficult to control if not properly broken.", "note"); App.UI.DOM.appendNewElement("div", el, App.UI.DOM.passageLink("Back", "Starting Girls")); diff --git a/src/personalAssistant/assistantAppearance.js b/src/personalAssistant/assistantAppearance.js index e713166e86c5b3cec0dcb9fc1afcef2b61a1bae4..27c9f3d2e606b204bc98d0dd94023a6a3bb61af2 100644 --- a/src/personalAssistant/assistantAppearance.js +++ b/src/personalAssistant/assistantAppearance.js @@ -1960,21 +1960,18 @@ globalThis.availableAssistantAppearances = function() { const el = document.createElement("div"); const {hisA} = getPronouns(assistant.pronouns().main).appendSuffix('A'); el.append(`Select ${hisA} appearance: `); - const select = App.UI.DOM.appendNewElement("select", el); + + const options = []; for (const [appearance, obj] of App.Data.Assistant.appearances) { if (obj.requirements) { - const option = App.UI.DOM.appendNewElement("option", select, capFirstChar(appearance)); - option.value = appearance; - if (V.assistant.appearance === appearance) { - option.selected = true; - } + options.push({key: appearance, name: capFirstChar(appearance)}); } } - select.onchange = () => { - const O = select.options[select.selectedIndex]; - V.assistant.appearance = /** @type {assistantAppearance} */ (O.value); + el.append(App.UI.DOM.makeSelect(options, V.assistant.appearance, appearance => { + V.assistant.appearance =/** @type {assistantAppearance} */ (appearance); App.UI.reload(); - }; + })); + return el; }; diff --git a/src/player/electiveSurgery.js b/src/player/electiveSurgery.js index cbf10edda6d16cc2f851a948b245a282766ed020..55fd1e625c7099ed75a3063c5d7ed2106982131d 100644 --- a/src/player/electiveSurgery.js +++ b/src/player/electiveSurgery.js @@ -161,34 +161,22 @@ App.UI.electiveSurgery = function() { App.Events.addNode(p, r, "div"); const choiceDiv = document.createElement("div"); - const choices = new Map([]); + /** + * @type {selectOption[]} + */ + const choices = []; if (V.PC.skin !== V.PC.origSkin) { - choices.set(V.PC.origSkin, capFirstChar(`Restore natural ${V.PC.origSkin}`)); + choices.push({key: V.PC.origSkin, name: capFirstChar(`Restore natural ${V.PC.origSkin}`)}); } for (const skin of App.Medicine.Modification.naturalSkins) { - choices.set(skin, capFirstChar(skin)); + choices.push({key: skin, name: capFirstChar(skin)}); } - const select = document.createElement("select"); - let matchFound; - for (const [value, text] of choices) { - const option = document.createElement("option"); - option.text = text; - option.value = value; - if (V.PC.skin === option.value) { - option.selected = true; - matchFound = true; - } - select.append(option); - } - if (!matchFound) { - select.selectedIndex = -1; - } - select.onchange = () => { - V.PC.skin = select.options[select.selectedIndex].value; + const select = App.UI.DOM.makeSelect(choices, V.PC.skin, value => { + V.PC.skin = value; cashX(forceNeg(2000), "PCmedical"); showDegradation("skinTone"); - }; + }); choiceDiv.append(select, " or custom ", App.UI.DOM.makeTextBox( V.PC.skin, v => {