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;