sorting done

This commit is contained in:
2026-02-27 11:00:27 +10:00
parent c3996ec6c6
commit 4cf18c4895
4 changed files with 181 additions and 4 deletions

View File

@@ -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})
}

View File

@@ -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;
}

View File

@@ -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) => {

View File

@@ -9,6 +9,7 @@
<script src="JavaScript/main.js"></script>
<script src="JavaScript/table.js"></script>
<script src="JavaScript/filter.js"></script>
<script src="JavaScript/sort.js"></script>
</head>
<body>
@@ -61,8 +62,8 @@
</select>
по убыванию? <input type="checkbox" id="fieldsSecondDesc">
</p>
<input type="button" value="Сортировать">
<input type="button" value="Сбросить сортировку">
<input type="button" value="Сортировать" id="doSortButton">
<input type="button" value="Сбросить сортировку" id="resetSortButton">
</form>
<br>
</div>