Создание детерминированного автомата js
- Пример таблицы, которая должна выводится на экран: красное 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>