Динамическая замена данных по выбору из select
Друзья, нужна помощь специалистов!
Итак, есть у меня несколько выпадающих списков, которые сделаны через select:
<table>
<tr>
<td class="cell4 cell1">
<select name="Gender" class="sum2 sum3">
<option value="X">All</option>
<option value="0">Male</option>
<option value="1">Female</option>
</select>
</td>
<td class="cell4 cell1">
<select name="Social status" class="sum2 sum3">
<option value="X">All</option>
<option value="1">Free</option>
<option value="0">Slave</option>
</select>
</td>
<td class="cell4 cell1">
<select name="Adult" class="sum2 sum3">
<option value="X">All</option>
<option value="1">Adult</option>
<option value="0">Children</option>
</select>
</td>
<td class="cell4 cell1">
<span id="qualityTotal"></span>
</td>
</tr>
</table>
а есть у меня обьект, который содержит в себе данные:
const ADULT_YES = 1,
ADULT_NO = 0;
const WORK_YES = 1,
WORK_NO = 0;
const MEN = 0,
FEMALE = 1;
//ALL = X;
const SLAVE = 0,
FREE = 1,
ALL_SOC = 2;
let summary = {
'TOTAL': 1,
[`${MEN}`]:0,//0
[`${MEN}${SLAVE}`]:0,//00
[`${MEN}${SLAVE}${ADULT_YES}`]:0,//001
[`${MEN}${SLAVE}${ADULT_NO}`]:0,//000
[`${MEN}${SLAVE}${ADULT_YES}${WORK_YES}`]:0,//0011
[`${MEN}${SLAVE}${ADULT_YES}${WORK_NO}`]:0,//0010
[`${MEN}${SLAVE}${ADULT_NO}${WORK_YES}`]:0,//0001
[`${MEN}${SLAVE}${ADULT_NO}${WORK_NO}`]:0,//0000
[`${MEN}${FREE}`]:0,//01
[`${MEN}${FREE}${ADULT_YES}`]:0,//011
[`${MEN}${FREE}${ADULT_NO}`]:0,//010
[`${MEN}${FREE}${ADULT_YES}${WORK_YES}`]:0,//0111
[`${MEN}${FREE}${ADULT_YES}${WORK_NO}`]:0,//0110
[`${MEN}${FREE}${ADULT_NO}${WORK_YES}`]:0,//0101
[`${MEN}${FREE}${ADULT_NO}${WORK_NO}`]:0,//0100
[`${ALL}${ALL}${ALL}${ALL}`]: 0,
};
И вот какая задача: как сделать так, чтобы в <span id="qualityTotal"></span> автоматически выводилось содержимое конкретного параметра обьекта, когда меняется выбор в select, чтобы получалось что-то вроде такого:

Там где красная 10 должно выводиться количество из summary в соотвествии выборов select-элементов без каких-либо дополнительных телодвижений.
По идее вывод в <span id="qualityTotal"></span> должен иметь какой-то такой вид:
let gen = document.querySelector('[name="Gender"]').value
let soc = document.querySelector('[name="Social status"]').value
let adult = document.querySelector('[name="Adult"]').value
document.querySelector('qualityTotal').innerHTML = summary[`${gen}${soc}${adult}${WORK_NO}`]
Здесь значения value совпадают с константами в summary, таким образом, я могу выбрать конкретный тип данных, но как это сделать автоматическим я ума не приложу.
Кроме того, есть еще одна проблема, которая касается параметра ALL, то есть я не представляю, как призвести вывод лишь по одному параметру, а не всем трем. Например, мне нужно выбрать только мужчин, без учета их социального статуса или возраста... Как это можно реализовать в данном примере?
Вот пример того, что я имею ввиду:
По идее здесь идет обращение к ['${MEN}${WORK_NO}']:0,, то есть мне нужно учесть все возможные варианты в ${soc}${adult} в конструкции summary['${MEN}${soc}${adult}${WORK_NO}']:0,. Как такое можно провернуть?
Ответы (1 шт):
Решение данной проблемы оказалось довольно простым, но трудоемким.
Для начала, нам понаботься еще одна константа, которая будет обозначать вариант без выбора, я назвал ее ALL.
Далее необходимо было привести к единому виду обьект summary, чтобы по нему можно было делать перебор по нужному количеству переменных.
Например, если у нас 4 поля select, то и количество полей в ключе обьекта summary должно быть 4 штуки.
[`${MEN}${ALL}${ALL}${ALL}`]:0,//0ХХХ
[`${MEN}${SLAVE}${ALL}${ALL}`]:0,//00ХХ
[`${MEN}${SLAVE}${ADULT_YES}${ALL}`]:0,//001Х
[`${MEN}${SLAVE}${ADULT_NO}${ALL}`]:0,//000Х
[`${MEN}${SLAVE}${ADULT_YES}${WORK_YES}`]:0,//0011
[`${MEN}${SLAVE}${ADULT_YES}${WORK_NO}`]:0,//0010
[`${MEN}${SLAVE}${ADULT_NO}${WORK_YES}`]:0,//0001
[`${MEN}${SLAVE}${ADULT_NO}${WORK_NO}`]:0,//0000
Все поля, которые исключаются из поиска, получают значение ALL. Таким образом, мы получаем единый стандарт для всех переменных. Так, если нам нужны "мужчины", то мы выбираем не ['${MEN}']:0, а ['${MEN}${ALL}${ALL}${ALL}']:0,.
Дальше уже дело техники.
Мы делаем небольшую функцию, которая считывает значения из наших элементов select и формирует из них "переменную", которая соответсвует конкретному ключу обьекта summary, после чего, полученный итог, публикуем в нужном месте:
let func = function(e) {
let gen = document.querySelector('[name="Gender"]').value
let soc = document.querySelector('[name="Social status"]').value
let ad = document.querySelector('[name="Adult"]').value
let work = document.querySelector('[name="Work"]').value
document.getElementById('qualityTotal').innerText = summary[`${gen}${soc}${ad}${work}`]
}
document.getElementById('info_workers').addEventListener("change", func, false)
На саму таблицу вешаем addEventListener, чтобы он отслеживал изменения элементов select.
Если возник вопрос, почему на таблицу, а не, например, на элементы select, поясняю: проблема в том, что select-элементов в таблице может быть много, а значит, чтобы отслеживать изменения на всех элементах, данную функцию нужно будет подцепить на все элементы. Это лишний код, лишние проверки и лишняя загрузка памяти.
Поэтому, намного проще установить addEventListener на элемент, который будет родителем для всех элементов select.
Как итог, получаем таблицу, где можно выбрать нужные параметры и узнать значения, которые хранятся в них без лишних телодвижений.
===============================================
P.S. Может показаться, что такая система организации данных слишком не рациональна, однако, в конечном итоге, она позволила очень сильно и довольно легко упростить сам исполняющий код программы. Мне потребовалось всего одна строчка кода, чтобы найти нужный элемент и вывести его, если бы данные были организованы по иному принципу, данная задача потребовала куда-более сложных программных решений.
Однако недостаток этого подхода так же вполне очевиден, так как в списке возможных вариантов обьекта summary пришлось учесть вообще все возможные варианты, которые, возможно, никогда и не понадобятся, однако для корректности работы программы они должны были быть учтены. Соответственно, чем больше возможных вариантов, тем более обширным будет обьект summary, поэтому, такой вариант уместен, если возможных вариантов не сильно много, если же их, скажем, больше 100, то есть смысл рассмотреть другие варианты решения данной проблемы.
