Задача №6
Користувач задає кількість оцінок і натискає на кнопку «get table». В результаті формується таблиця з input, куди користувач вводить оцінки. Після цього натискає на кнопку “get sum” і знаходить середнє значення.
Рішення:
'use strict'
const GRADES_ATTRIBUTE = 'grades[]'
/**
* Calculate average value out of all form's inputs.
*
* @param {SubmitEvent} e
*/
function handleSubmit(e) {
e.preventDefault()
const inputElList = e.target.elements[GRADES_ATTRIBUTE]
const gradesSum = [].reduce.call(
inputElList,
(sum, {value}) => sum + Number(value),
0,
)
const averageGrade = gradesSum / inputElList.length
e.target.querySelector('output').innerText = averageGrade.toFixed(1)
}
/**
* @param {string} type - Type of the input
*/
function createInputCell(type) {
const cellEl = document.createElement('td')
const inputEl = document.createElement('input')
inputEl.type = type
inputEl.name = GRADES_ATTRIBUTE
inputEl.placeholder = '0'
inputEl.className = 'u-is-full'
cellEl.append(inputEl)
return cellEl
}
/**
* @param {number} cells - Amount of cells in the row
*/
function createTableRow(cells) {
if (typeof cells !== 'number')
throw new TypeError('Amount of cells must be a number.')
if (cells <= 0) throw new RangeError('Amount of cells must be positive.')
const rowEl = document.createElement('tr')
for (let i = 0; i < cells; i++) {
const cellEl = createInputCell('number')
rowEl.append(cellEl)
}
return rowEl
}
/**
* @param {number} cells - Amount of cells in the table
*/
function createTable(cells, cellsPerRow = 4) {
if (typeof cells !== 'number')
throw new TypeError('Amount of cells must be a number.')
if (cells <= 0) throw new RangeError('Amount of cells must be positive.')
const tableEl = document.createElement('table')
const tBodyEl = document.createElement('tbody')
tableEl.append(tBodyEl)
const rows = Math.ceil(cells / cellsPerRow)
let cellsLeft = cells
for (let i = 0; i < rows; i++) {
const rowEl = createTableRow(Math.min(cellsLeft, cellsPerRow))
cellsLeft -= cellsPerRow
tBodyEl.append(rowEl)
}
return tableEl
}
/**
* @param {number} gradesAmount
*/
function createGradesForm(gradesAmount) {
const formEl = document.createElement('form')
const captionEl = document.createElement('caption')
const tableEl = createTable(gradesAmount)
const submitEl = document.createElement('button')
const outputEl = document.createElement('output')
const footerEl = document.createElement('div')
outputEl.className = 'u-text-bolder u-text-400'
captionEl.innerText = 'Оцінки'
captionEl.className = 'u-mbe-100'
tableEl.prepend(captionEl)
submitEl.innerText = 'Обчислити середнє'
footerEl.className = 'u-flex u-flex-wrap u-gap-200 u-items-center'
footerEl.append(submitEl, outputEl)
formEl.className = 'js-form-average u-flow-200 u-overflow-auto u-pb-500'
formEl.append(tableEl, footerEl)
formEl.addEventListener('submit', handleSubmit)
return formEl
}
// =============================================================================
const buildTableForm = document.querySelector('.js-build-table')
// Create a new tale for calculation of average grade
buildTableForm?.addEventListener('submit', (e) => {
e.preventDefault()
const gradesAmount = +e.target?.elements?.amount?.value
if (!isFinite(gradesAmount) || gradesAmount <= 0) return
const newFormEl = createGradesForm(gradesAmount)
const oldFormEl = document.querySelector('.js-form-average')
oldFormEl?.replaceWith(newFormEl)
})
