diff --git a/labs/lab1/JavaScript/main.js b/labs/lab1/JavaScript/main.js index 47d768d..fd62a53 100644 --- a/labs/lab1/JavaScript/main.js +++ b/labs/lab1/JavaScript/main.js @@ -8,12 +8,99 @@ function doInit() { clearFiltersButton.addEventListener("click", (event) => { clearFilters(filter); filterTable(buildings,'list',filter) + resetSort(sort); }) - const applyFiltersButton = document.getElementById("applyFiltersButton"); applyFiltersButton.addEventListener("click", (event) => { filterTable(buildings,'list',filter) + resetSort(sort); }) + + setSortSelects(buildings[0], sort) + + + sort.fieldsFirst.addEventListener("change",()=>{ + changeNextSelect(sort.fieldsFirst,sort.fieldsSecond.id) + }) + + sort.doSortButton.addEventListener("click", ()=>{if (!sortTable('list',sort)){ + clearTable('list'); + createTable(buildings, 'list'); + }}); + sort.resetSortButton.addEventListener("click", ()=>{resetSort(sort); + clearTable('list'); + createTable(buildings, 'list'); + }); + } +// формирование полей элемента списка с заданным текстом и значением + +const createOption = (str, val) => { + let item = document.createElement('option'); + item.text = str; + item.value = val; + return item; +} + +// формирование поля со списком +// параметры – массив со значениями элементов списка и элемент select + +const setSortSelect = (arr, sortSelect) => { + + // создаем OPTION Нет и добавляем ее в SELECT + sortSelect.append(createOption('Нет', 0)); + // перебираем массив со значениями опций + arr.forEach((item, index) => { + // создаем OPTION из очередного ключа и добавляем в SELECT + // значение атрибута VALUE увеличиваем на 1, так как значение 0 имеет опция Нет + sortSelect.append(createOption(item, index + 1)); + }); +} +// формируем поля со списком для многоуровневой сортировки +const setSortSelects = (data, dataForm) => { + + // выделяем ключи словаря в массив + const head = Object.keys(data); + + // находим все SELECT в форме + const allSelect = dataForm.getElementsByTagName('select'); + + for(const item of dataForm.elements){ + // формируем очередной SELECT + setSortSelect(head, item); + + // САМОСТОЯТЕЛЬНО все SELECT, кроме первого, сделать неизменяемым + } + let skipped = false + for(const elem of allSelect){ + if(!skipped){ + skipped = true; + continue; + } + elem.disabled = true; + } +} + +const changeNextSelect = (curSelect, nextSelectId) => { + + let nextSelect = document.getElementById(nextSelectId); + + nextSelect.disabled = false; + + // в следующем SELECT выводим те же option, что и в текущем + nextSelect.innerHTML = curSelect.innerHTML; + + // удаляем в следующем SELECT уже выбранную в текущем опцию + // если это не первая опция - отсутствие сортировки + if (curSelect.value != 0) { + nextSelect.remove(curSelect.value); + } else { + nextSelect.disabled = true; + } +} + +const resetSort = (form)=>{ + form.querySelectorAll(`& select`).forEach((curSelect,index) => {if(index!=0){curSelect.disabled = true} curSelect.value = 0}) +} diff --git a/labs/lab1/JavaScript/sort.js b/labs/lab1/JavaScript/sort.js new file mode 100644 index 0000000..496c9ae --- /dev/null +++ b/labs/lab1/JavaScript/sort.js @@ -0,0 +1,87 @@ +/*формируем массив для сортировки по двум уровням вида + [ + {column: номер столбца, по которому осуществляется сортировка, + direction: порядок сортировки (true по убыванию, false по возрастанию) + }, + ... + ] +*/ +const createSortArr = (data) => { + let sortArr = []; + + const sortSelects = data.getElementsByTagName('select'); + + for (const item of sortSelects) { + // получаем номер выбранной опции + const keySort = item.value; + // в случае, если выбрана опция Нет, заканчиваем формировать массив + if (keySort == 0) { + break; + } + // получаем порядок сортировки очередного уровня + // имя флажка сформировано как имя поля SELECT и слова Desc + const desc = document.getElementById(item.id + 'Desc').checked; + // очередной элемент массива - по какому столбцу и в каком порядке сортировать + sortArr.push( + { + column: keySort - 1, + direction: desc + } + ); + } + return sortArr; +}; + +const numberColumns = [4, 5] + +const sortTable = (idTable, formData) => { + + // формируем управляющий массив для сортировки + const sortArr = createSortArr(formData); + + // сортировать таблицу не нужно, во всех полях выбрана опция Нет + if (sortArr.length === 0) { + clearTable(idTable) + return false; + + } + //находим нужную таблицу + let table = document.getElementById(idTable); + + // преобразуем строки таблицы в массив + let rowData = Array.from(table.rows); + + // удаляем элемент с заголовками таблицы + const headerRow = rowData.shift(); + + //сортируем данные по всем уровням сортировки + rowData.sort((first, second) => { + for (let { column, direction } of sortArr) { + const firstCell = first.cells[column].innerHTML; + const secondCell = second.cells[column].innerHTML; + + // используем localeCompare для корректного сравнения + let comparison = null; + if (numberColumns.includes(column)) { + comparison = Number(firstCell) - Number(secondCell); + } + else { + comparison = firstCell.localeCompare(secondCell); + } + // учитываем направление сортировки + if (comparison !== 0) { + return (direction ? -comparison : comparison); + } + } + return 0; + }); + clearTable(idTable) + //выводим отсортированную таблицу на страницу + + let tbody = document.createElement('tbody'); + rowData.forEach(item => { + tbody.append(item); + }); + table.append(tbody); + return true; +} \ No newline at end of file diff --git a/labs/lab1/JavaScript/table.js b/labs/lab1/JavaScript/table.js index 4ad7a5a..bd8d290 100644 --- a/labs/lab1/JavaScript/table.js +++ b/labs/lab1/JavaScript/table.js @@ -30,7 +30,9 @@ const createHeaderRow = (headers) => { th.innerHTML = header; tr.append(th); }); - return tr; + const thead = document.createElement('thead') + thead.appendChild(tr) + return thead; }; const createBodyRows = (rows) => { diff --git a/labs/lab1/index.html b/labs/lab1/index.html index 057df54..078f47e 100644 --- a/labs/lab1/index.html +++ b/labs/lab1/index.html @@ -9,6 +9,7 @@ +
@@ -61,8 +62,8 @@ по убыванию? - - + +