Задать вопрос
@SevSergei

Как реализовать динамическое сравнение массивов на основе чекбоксов?

Есть два вида групп чекбоксов.
Например, первый вид:

checkbox id1 [value_a1]
checkbox id2 [value_a2]
checkbox id2 [value_a3]

Как видно, в первом виде чекбоксов получить значение_а1 просто.

Но есть второй вид чекбоксов:

checkbox id1 [value_a1, value_a2, value_a3]
checkbox id2 [value_b1, value_b2, value_b3]
checkbox id3 [value_c1, value_c2, value_c3]
-----
checkbox id4 [value_a1, value_b1, value_c1]
checkbox id5 [value_a2, value_b2, value_c2]
checkbox id6 [value_a3, value_b3, value_c3]

ИЛИ

checkbox id1 [value_a1]
checkbox id2 [value_b1]
checkbox id3 [value_c1]
-----
checkbox id4 [value_a1, value_b1, value_c1]

Если выбрать чекбоксы id1 и id4, то должно получиться value_a1,
если дополнительно выбрать id5, так же должно добавиться значение value_a2

Если выбрать id1 и id2 - результата не будет.
Сложность в том, что это не радиобатоны и значений чекбоксов может быть много. Также непонятно, как удалять значения, когда чекбоксы снимаются.
  • Вопрос задан
  • 109 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Для хранения выбранных значений можно использовать объект, имена свойств которого соответствуют индексам групп чекбоксов, а значения будут массивами значений, соответствующих чекбоксам выбранной группы (вперемешку, без разделения по конкретным чекбоксам). В обработчике клика чекбокса в зависимости от его checked дописываете или выбрасываете значения группы.

Для вывода значений, выбранных во всех группах берёте массив выбранных значений любой группы, и фильтруете его с условием, что элемент массива присутствует во всех массивах выбранных значений групп.

Выглядеть это может так, например:

class App extends React.Component {
  state = {
    selected: {},
    groups: [
      [
        [ 'value_a1', 'value_a2', 'value_a3' ],
        [ 'value_b1', 'value_b2', 'value_b3' ],
        [ 'value_c1', 'value_c2', 'value_c3' ],
      ],
      [
        [ 'value_a1', 'value_b1', 'value_c1' ],
        [ 'value_a2', 'value_b2', 'value_c2' ],
        [ 'value_a3', 'value_b3', 'value_c3' ],
      ],
    ],
  }

  onChange = (e, groupIndex, itemIndex) => {
    const selectedGroup = this.state.groups[groupIndex][itemIndex];
    const selectedInfo = this.state.selected[groupIndex] || [];

    this.setState({
      selected: {
        ...this.state.selected,
        [groupIndex]: e.target.checked
          ? selectedInfo.concat(selectedGroup)
          : selectedInfo.filter(n => !selectedGroup.includes(n))
      },
    });
  }

  render() {
    const { selected, groups } = this.state;
    const matched = (selected[0] || []).filter(n => {
      return groups.every((group, i) => (selected[i] || []).includes(n));
    });

    return (
      <div>
        {groups.map((group, groupIndex) => (
          <ul>
            {group.map((item, itemIndex) => (
              <li>
                <input
                  type="checkbox"
                  onChange={(e) => this.onChange(e, groupIndex, itemIndex)}
                />
                {item.map(val => <span>{val}</span>)}
              </li>
            ))}
          </ul>
        ))}
        <div>
          {matched.map(val => <span>{val}</span>)}
        </div>
      </div>
    );
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы