From 4cf18c4895fc859067e0593544b8f72eb06f02be Mon Sep 17 00:00:00 2001
From: OkunElya
Date: Fri, 27 Feb 2026 11:00:27 +1000
Subject: [PATCH] sorting done
---
labs/lab1/JavaScript/main.js | 89 ++++++++++++++++++++++++++++++++++-
labs/lab1/JavaScript/sort.js | 87 ++++++++++++++++++++++++++++++++++
labs/lab1/JavaScript/table.js | 4 +-
labs/lab1/index.html | 5 +-
4 files changed, 181 insertions(+), 4 deletions(-)
create mode 100644 labs/lab1/JavaScript/sort.js
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 @@
по убыванию?
-
-
+
+