From 74bb057314ca0b4a98b0d9ae26dadc9737a9a2ed Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 2 Jan 2022 18:31:15 -0500 Subject: [PATCH] Implemented range settings --- WebHostLib/static/assets/weighted-settings.js | 131 +++++++++++++++++- .../static/styles/weighted-settings.css | 35 +++++ 2 files changed, 161 insertions(+), 5 deletions(-) diff --git a/WebHostLib/static/assets/weighted-settings.js b/WebHostLib/static/assets/weighted-settings.js index f00d6230..e7d80af1 100644 --- a/WebHostLib/static/assets/weighted-settings.js +++ b/WebHostLib/static/assets/weighted-settings.js @@ -240,20 +240,141 @@ const buildOptionsDiv = (game, settings) => { optionTable.appendChild(tbody); settingWrapper.appendChild(optionTable); - optionsWrapper.appendChild(settingWrapper); break; case 'range': - const settingDescription = document.createElement('p'); - settingDescription.classList.add('setting-description'); - settingDescription.innerText = setting.description.replace(/(\n)/g, ' '); - settingWrapper.appendChild(settingDescription); + const hintText = document.createElement('p'); + hintText.classList.add('hint-text'); + hintText.innerHTML = 'This is a range option. You may enter valid numerical values in the text box below, ' + + `then press the "Add" button to add a weight for it.
Minimum value: ${setting.min}
` + + `Maximum value: ${setting.max}`; + settingWrapper.appendChild(hintText); + + const addOptionDiv = document.createElement('div'); + addOptionDiv.classList.add('add-option-div'); + const optionInput = document.createElement('input'); + optionInput.setAttribute('id', `${game}-${settingName}-option`); + optionInput.setAttribute('placeholder', `${setting.min} - ${setting.max}`); + addOptionDiv.appendChild(optionInput); + const addOptionButton = document.createElement('button'); + addOptionButton.innerText = 'Add'; + addOptionDiv.appendChild(addOptionButton); + settingWrapper.appendChild(addOptionDiv); + optionInput.addEventListener('keydown', (evt) => { + if (evt.key === 'Enter') { addOptionButton.dispatchEvent(new Event('click')); } + }); + + const rangeTable = document.createElement('table'); + const rangeTbody = document.createElement('tbody'); + + Object.keys(currentSettings[game][settingName]).forEach((option) => { + if (currentSettings[game][settingName][option] > 0) { + const tr = document.createElement('tr'); + const tdLeft = document.createElement('td'); + tdLeft.classList.add('td-left'); + tdLeft.innerText = option; + tr.appendChild(tdLeft); + + const tdMiddle = document.createElement('td'); + tdMiddle.classList.add('td-middle'); + const range = document.createElement('input'); + range.setAttribute('type', 'range'); + range.setAttribute('id', `${game}-${settingName}-${option}-range`); + range.setAttribute('data-game', game); + range.setAttribute('data-setting', settingName); + range.setAttribute('data-option', option); + range.setAttribute('min', 0); + range.setAttribute('max', 50); + range.addEventListener('change', updateGameSetting); + range.value = currentSettings[game][settingName][parseInt(option, 10)]; + tdMiddle.appendChild(range); + tr.appendChild(tdMiddle); + + const tdRight = document.createElement('td'); + tdRight.setAttribute('id', `${game}-${settingName}-${option}`) + tdRight.classList.add('td-right'); + tdRight.innerText = range.value; + tr.appendChild(tdRight); + + const tdDelete = document.createElement('td'); + tdDelete.classList.add('td-delete'); + const deleteButton = document.createElement('span'); + deleteButton.classList.add('range-option-delete'); + deleteButton.innerText = '❌'; + deleteButton.addEventListener('click', () => { + range.value = 0; + range.dispatchEvent(new Event('change')); + rangeTbody.removeChild(tr); + }); + tdDelete.appendChild(deleteButton); + tr.appendChild(tdDelete); + + rangeTbody.appendChild(tr); + } + }); + + rangeTable.appendChild(rangeTbody); + settingWrapper.appendChild(rangeTable); + + addOptionButton.addEventListener('click', () => { + const optionInput = document.getElementById(`${game}-${settingName}-option`); + let option = optionInput.value; + if (!option || !option.trim()) { return; } + option = parseInt(option, 10); + if ((option < setting.min) || (option > setting.max)) { return; } + optionInput.value = ''; + if (document.getElementById(`${game}-${settingName}-${option}-range`)) { return; } + + const tr = document.createElement('tr'); + const tdLeft = document.createElement('td'); + tdLeft.classList.add('td-left'); + tdLeft.innerText = option; + tr.appendChild(tdLeft); + + const tdMiddle = document.createElement('td'); + tdMiddle.classList.add('td-middle'); + const range = document.createElement('input'); + range.setAttribute('type', 'range'); + range.setAttribute('id', `${game}-${settingName}-${option}-range`); + range.setAttribute('data-game', game); + range.setAttribute('data-setting', settingName); + range.setAttribute('data-option', option); + range.setAttribute('min', 0); + range.setAttribute('max', 50); + range.addEventListener('change', updateGameSetting); + range.value = currentSettings[game][settingName][parseInt(option, 10)]; + tdMiddle.appendChild(range); + tr.appendChild(tdMiddle); + + const tdRight = document.createElement('td'); + tdRight.setAttribute('id', `${game}-${settingName}-${option}`) + tdRight.classList.add('td-right'); + tdRight.innerText = range.value; + tr.appendChild(tdRight); + + const tdDelete = document.createElement('td'); + tdDelete.classList.add('td-delete'); + const deleteButton = document.createElement('span'); + deleteButton.classList.add('range-option-delete'); + deleteButton.innerText = '❌'; + deleteButton.addEventListener('click', () => { + range.value = 0; + range.dispatchEvent(new Event('change')); + rangeTbody.removeChild(tr); + }); + tdDelete.appendChild(deleteButton); + tr.appendChild(tdDelete); + + rangeTbody.appendChild(tr); + }); break; default: console.error(`Unknown setting type for ${game} setting ${setting}: ${settings[setting].type}`); return; } + + optionsWrapper.appendChild(settingWrapper); }); return optionsWrapper; diff --git a/WebHostLib/static/styles/weighted-settings.css b/WebHostLib/static/styles/weighted-settings.css index 5eb71ecd..4c45e231 100644 --- a/WebHostLib/static/styles/weighted-settings.css +++ b/WebHostLib/static/styles/weighted-settings.css @@ -24,6 +24,26 @@ html{ margin-bottom: 2rem; } +#weighted-settings .setting-wrapper .add-option-div{ + display: flex; + flex-direction: row; + justify-content: flex-start; + margin-bottom: 1rem; +} + +#weighted-settings .setting-wrapper .add-option-div button{ + width: auto; + height: auto; + margin: 0 0 0 0.15rem; + padding: 0 0.25rem; + border-radius: 4px; + cursor: default; +} + +#weighted-settings .setting-wrapper .add-option-div button:active{ + margin-bottom: 1px; +} + #weighted-settings p.setting-description{ font-weight: bold; margin: 0 0 1rem; @@ -46,6 +66,7 @@ html{ #weighted-settings table .td-left{ padding-right: 1rem; + width: 200px; } #weighted-settings table .td-middle{ @@ -55,6 +76,20 @@ html{ padding-right: 1rem; } +#weighted-settings table .td-right{ + width: 4rem; + text-align: right; +} + +#weighted-settings table .td-delete{ + width: 50px; + text-align: right; +} + +#weighted-settings table .range-option-delete{ + cursor: pointer; +} + #weighted-settings #weighted-settings-button-row{ display: flex; flex-direction: row;