Создание детерминированного автомата js

Пример таблицы, красное r - rows, синее c - cols - Пример таблицы, которая должна выводится на экран: красное r - rows, синее c - cols. Создаётся два inputs в которые вписывается количество столбцов и количество рядов в этом автомате. Помогите пожалуйста сделать так, чтобы при нажатии на кнопку создавалась таблица из inputs в которую пользователь может вводить информацию сам либо рандомно при нажатии на кнопку.

const $random = document.querySelector('#random');
const $inputsContainer = document.querySelector('.inputs-container');
const $inputsCount = document.querySelector('#inputs-count');
const $out = document.querySelector('#out');
const $showValues = document.querySelector('#show-values');

const makeElement = (tag, className, childrens = []) => {
  const el = document.createElement(tag);
  el.className = className;
  el.append(...childrens);
  return el;
};

const makeInput = () => {
  const el = makeElement('input', 'input');
  el.type = 'text';
  return el;
};

const createElements = (count, constructor) => {
  return Array(count).fill().map(constructor);
};

const showInputsText = () => {
  const inputs = $inputsContainer.querySelectorAll('input');
  const values = [...inputs].reduce((acc, element) => {
    return `${acc} ${element.value}`;
  }, '');
  $out.textContent = values;
};

$showValues.addEventListener('click', showInputsText);

$random.addEventListener('click', () => {
  const count = parseInt($inputsCount.value);

  const inputs = createElements(count, makeInput);
  const $row = makeElement('div', 'mb-1', inputs);
  $inputsContainer.append($row);
});



const $random1 = document.querySelector('#random1');
const $inputsContainer1 = document.querySelector('.inputs-container1');
const $inputsCount1 = document.querySelector('#inputs-count1');
const $out1 = document.querySelector('#out1');
const $showValues1 = document.querySelector('#show-values1');


const showInputsText1 = () => {
  const inputs1 = $inputsContainer1.querySelectorAll('input');
  const values1 = [...inputs1].reduce((acc, element) => {
    return `${acc} ${element.value}`;
  }, '');
  $out1.textContent = values1;
};

$showValues1.addEventListener('click', showInputsText1);

$random1.addEventListener('click', () => {
  const count1 = parseInt($inputsCount1.value);

  const inputs1 = createElements(count1, makeInput);
  const $row1 = makeElement('div', 'mb-2', inputs1);
  $inputsContainer1.append($row1);
});
<div class="mb-1">
  Inputs count r: <input type="text" id="inputs-count" value="2" />
  <button id="random">Push</button>
  <button id="show-values">cout</button>
</div>
<div class="inputs-container"></div>

<div class="mb-2">
  Inputs count c: <input type="text" id="inputs-count1" value="2" />
  <button id="random1">Push</button>
  <button id="show-values1">cout</button>
</div>
<div class="inputs-container1"></div>

<div class="mb-1" id="out"></div>
<div class="mb-2" id="out1"></div>


Ответы (2 шт):

Автор решения: Aleksandr Belous

Надеюсь это то, что вы хотели

const $createTable = document.getElementById('create-table');
const $inputsTable = document.getElementById('inputs-table');

const makeInput = () => {
  const $el = document.createElement('input');
  $el.type = 'text';
  return $el;
};

const makeTable = (cols, rows) => {
  const $table = document.createElement('div');
  const inputs = Array(rows)
    .fill([...Array(cols)])
    .map((row) => {
      const $row = document.createElement('div');
      $row.append(...row.map(makeInput));
      return $row;
    });
  $table.append(...inputs);
  return $table;
};

const parse = (formData) => {
  const result = {};
  formData.forEach((value, key) => {
    result[key] = parseInt(value);
  });
  return result;
};

$createTable.addEventListener('submit', (ev) => {
  ev.preventDefault();

  const {
    cols,
    rows
  } = parse(new FormData($createTable));

  $inputsTable.replaceChildren(makeTable(cols, rows));
});
.mb-1 {
  margin-bottom: 1rem;
}
<form class="mb-1" id="create-table">
  <input type="text" placeholder="columns count" name="cols" required>
  <input type="text" placeholder="rows count" name="rows" required>
  <button type="submit">Make table of inputs</button>
</form>

<div id="inputs-table"></div>

<script src="./index.js"></script>

→ Ссылка
Автор решения: DiD

// Простой хелпер для querySelectorAll
const $$ = (...qs) => qs.reduce((a, q, i, t) => !a ? null : typeof q != 'string' ? q : a['querySelector' + (i < t.length - 1 ? '' : 'All')](q), document);
// Простой хелпер для создания элемента
const _ = (name, target) => {
  let el = document.createElement(name);
  if (target) target.appendChild(el);
  return el;
}
// Обработчик submit формы
form.onsubmit = e => {
  // отменяем submit
  e.preventDefault();
  // На каждой строке
  for (let tr of $$(table, 'tr')) {
    // получаем количество ячеек
    let exists = $$(tr, 'td').length - 1;
    // если ячеек столько, сколько нужно, то выходим
    if (exists == cols.value) break;
    // пока ячеек будет не хватать, по одной будем создавать
    while (exists++ < cols.value) _('td', tr);
    // а если ячеек на строке - перебор
    if (exists > cols.value) {
      // то лишние ячейки удалим
      [...$$(tr, 'td')].splice(+cols.value + 1).forEach(td => td.remove());
    }
  }
  // получаем количество строк
  let exists = $$(table, 'tr').length - 1;
  // пока строк будет не хватать
  while (exists++ < rows.value) {
    // по одной будем создавать
    let tr = _('tr', table);
    // в каждую строку наполним ячейками
    for (let x = 0; x <= cols.value; x++) _('td', tr);
  }
  // а если строк в табло - перебор
  if (exists > rows.value) {
    // то лишние строки удалим
    [...$$(table, 'tr')].splice(+rows.value + 1).forEach(tr => tr.remove());
  }
  // на каждой ячейке первой строки пусть будет надпись
  let tds = $$(table, 'tr:nth-child(1) td');
  for (let x = 1; x <= cols.value; x++) {
    tds[x].innerHTML = `q<sub>${x}</sub>`;
    tds[x].setAttribute('contenteditable', 'false');
  }
  // на каждой строке в первой ячейке пусть будет надпись
  let trs = $$(table, 'tr td:nth-child(1)');
  for (let y = 1; y <= rows.value; y++) {
    trs[y].innerHTML = `X<sub>${y}</sub>`;
    trs[y].setAttribute('contenteditable', 'false');
  }
  // Переберём все ячейки кроме первого стобца и первой строки
  for(let x = 1; x <= cols.value; x++)
    for(let y = 1; y <= rows.value; y++){
      // Найдем заданую ячейку
      let cell = table.querySelector(`tr:nth-child(${y+1})>td:nth-child(${x+1})`);
      // Событие срабатывает при наведении курсора мыши
      cell.onmouseenter = e => { 
        // Подсветим строку
        for(let rowCell of $$(table,`tr:nth-child(${y+1})>td`))
          rowCell.classList.add('highlight');
        // Подсветим столбик
        for(let rowCell of $$(table,`tr>td:nth-child(${x+1})`))
          rowCell.classList.add('highlight');
      };
      // Событие срабатывает при уведении курсора мыши
      cell.onmouseleave = e => { 
        // Потушим строку
        for(let rowCell of $$(table,`tr:nth-child(${y+1})>td`))
          rowCell.classList.remove('highlight');
        // Потушим столбик
        for(let rowCell of $$(table,`tr>td:nth-child(${x+1})`))
          rowCell.classList.remove('highlight');
      };
      
    }
}

// обработчик клика кнопки random
random.onclick=(e)=>{
  e.preventDefault();
  // рандомная строка (от 1 до rows.value включительно)
  let randRow = ~~(Math.random() * (rows.value))+1;
  // рандомная строка (от 1 до cols.value включительно)
  let randCol = ~~(Math.random() * (cols.value))+1;
  // рандомное число (от 0 до 1023 включительно)
  let randVal = ~~(Math.random() * 2**10);
  // Найти ячейку со строкой randRow+1 и колонкой randCol+1
  let cell = table.querySelector(`tr:nth-child(${randRow+1})>td:nth-child(${randCol+1})`);
  // Заменить значение ячейки
  cell.innerHTML = randVal;
  // Включить анимированный переход
  cell.classList.add('animated');
  requestAnimationFrame(()=>{
    // Пусть ячейка зажжется
    cell.classList.add('flash');
    // И через 100мс начнет гаснуть
    setTimeout(()=>cell.classList.remove('flash'),100);
    // И через 200мс выключим анимированый переход
    setTimeout(()=>cell.classList.remove('animated'),200);
  });
};
form {
  margin-bottom: 1rem;
}

label {
  display: inline-block;
  width: 3rem;
}

input {
  width: 3rem;
  text-align: right;
}

table {
  border-collapse: collapse;
}

td {
  text-align: center;
  min-width: 5rem;
}

tr:nth-child(1) td,
tr td:nth-child(1) {
  background: #ccc;
}

tr:nth-child(1) td:nth-child(1) {
  background: #fff;
}

.highlight {
background: #cfc;
}

.animated {
  transition: all 0.1s;
}

.flash{
  background: #00f;
  color: #fff;
}
<form id="form">
  <label for="cols">Cols</label>
  <input id="cols" type="number" value="0" min="0" />
  <label for="rows">Rows</label>
  <input id="rows" type="number" value="0" min="0" />
  <button type="submit">Update</button>
  <button id="random">Random</button>
</form>

<table id="table" contenteditable="true" border="1">
  <tr>
    <td></td>
  </tr>
</table>

→ Ссылка