Hej!
Chcę wyświetlić na stronie dane w postaci tabeli, która posiada opcję wyboru kolumny, po której dane mają zostać posortowane.
Po zmianie sortowania (np. przez kliknięcie w strzałkę obok nazwy kolumny) nie ma się przeładowywać cała strona, lecz sama tabela ma się wyświetlić ponownie, ale z już zmienionym sortowaniem.
Jak by to można najlepiej zrobić?
Tabela na stronie z sortowaniem po wskazanej kolumnie
- Rejestracja: dni
- Ostatnio: dni
- Postów: 81
- Rejestracja: dni
- Ostatnio: dni
- Postów: 358
Jak wyślesz dane na frontend i potem chcesz je posortować według kolumny, to musisz połączyć php z jakimś surowym js lub jakimś frameworkime, który zrobi to po drugiej stronie.
Jeśli pierwszy etap zrobiłeś dobrze i działa, wysłałeś dane w jakiejś postaci typu json? czy po prostu wyrenderowaną stronę wysłałeś?
Jeśli pierwsze to sortujesz w js i renderujesz w drugim przypadku jak już wyrenderowaną stronę masz, to musisz elementy strony brać jako podstawowe elementy, odwoływać się do ich wartości name i na podstawie tego robić kopie, usuwać i wstawiać w odpowiednie miejsce, tak jest trochę trudniej, bo tu modyfikujesz już zrenderowaną stronę, jakbyś przesłał jsonem dane do renderowania to możesz je w js obrobić i oddać do widoku.
Też nic kodu nie podałeś to ci mówię, co będzie pewnie trzeba zrobić, może jeszcze coś innego bo nie dokońca wiadomo jak to u ciebie działa, nie dałeś kodu.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 81
Dzięki za odpowiedź. Nie mam jeszcze kodu, bo pytam, by poznać właściwą koncepcję na to rozwiązanie.
czy po prostu wyrenderowaną stronę wysłałeś?
Sortowanie chciałbym wykonać po stronie bazy danych, a nie przez manipulowanie JSON-em w JS. Myślę, że to dobre, bo warstwa danych będzie oddzielona od warstwy prezentacji. Tak więc wyrenderowaną stronę bym już wysyłał.
Tak więc po kliknięciu w strzałkę w celu zmiany sortowania danych, musi iść request do bazy, aby zwróciła dane posortowane w inny sposób.
Czy warto zaprzęgać tu OOP (programowanie obiektowe)? Wszędzie, gdzie czytam o OOP, piszą, że to najlepszy sposób programowania. Jeśli warto, to jakie obiekty można by tu rozważać?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 351
Jeśli założymy, że całą tabelą masz w HTML to poniżej masz przykład dodania stortowania tabeli, która już jest po stronie klienta(html)
Drzewo DOM jest wystarczająco dobrze zorganizowane aby móc na nim swobodnie pracować bez konieczności renderowania danych z JSON.
Nie jest to być może najdoskonalsze rozwiązanie ale dzięki poniższej klasie JS możesz dodać sorowanie do dowolnej tabeli na strownie WWW.
Przykład online: https://jsfiddle.net/cj03zreh/
Kod:
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Przykładowa Sortowalna Tabela</title>
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
}
th {
cursor: pointer;
position: relative;
}
.sort-indicator {
margin-left: 5px;
}
</style>
</head>
<body>
<h1>Przykładowa Tabela</h1>
<table id="moja-tabela">
<thead>
<tr>
<th>Imię</th>
<th>Nazwisko</th>
<th>Wiek</th>
<th>Miasto</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jan</td>
<td>Kowalski</td>
<td>28</td>
<td>Warszawa</td>
</tr>
<tr>
<td>Anna</td>
<td>Nowak</td>
<td>34</td>
<td>Kraków</td>
</tr>
<tr>
<td>Piotr</td>
<td>Wiśniewski</td>
<td>22</td>
<td>Gdańsk</td>
</tr>
<tr>
<td>Maria</td>
<td>Wójcik</td>
<td>45</td>
<td>Poznań</td>
</tr>
<tr>
<td>Paweł</td>
<td>Kozłowski</td>
<td>31</td>
<td>Wrocław</td>
</tr>
</tbody>
</table>
<script>
class SortableTable {
constructor(tableElement) {
this.table = tableElement;
this.sortDirections = [];
this.init();
}
init() {
const headers = this.table.querySelectorAll('thead th');
headers.forEach((header, index) => {
this.sortDirections[index] = 1; // 1 dla rosnąco, -1 dla malejąco
header.style.cursor = 'pointer';
// Tworzenie elementu do wyświetlania wskaźnika sortowania
const headerContent = document.createElement('span');
headerContent.textContent = header.textContent;
header.textContent = ''; // Czyszczenie istniejącej zawartości
header.appendChild(headerContent);
const sortIndicator = document.createElement('span');
sortIndicator.classList.add('sort-indicator');
header.appendChild(sortIndicator);
header.addEventListener('click', () => {
this.sortDirections[index] *= -1; // Przełączanie kierunku sortowania
this.sortByColumn(index);
this.updateSortIndicators(headers, index);
});
});
}
sortByColumn(columnIndex) {
const tbody = this.table.tBodies[0];
const rows = Array.from(tbody.querySelectorAll('tr'));
const sortDirection = this.sortDirections[columnIndex];
const sortedRows = rows.sort((a, b) => {
const aText = a.cells[columnIndex].innerText;
const bText = b.cells[columnIndex].innerText;
const aValue = this.parseCellValue(aText);
const bValue = this.parseCellValue(bText);
if (aValue < bValue) {
return -1 * sortDirection;
}
if (aValue > bValue) {
return 1 * sortDirection;
}
return 0;
});
// Czyszczenie tbody i dodawanie posortowanych wierszy
while (tbody.firstChild) {
tbody.removeChild(tbody.firstChild);
}
sortedRows.forEach(row => {
tbody.appendChild(row);
});
}
parseCellValue(value) {
// Próba parsowania jako liczba, jeśli się nie uda, zwróć oryginalny tekst
const number = parseFloat(value.replace(',', '.'));
return isNaN(number) ? value.toLowerCase() : number;
}
updateSortIndicators(headers, activeIndex) {
headers.forEach((header, index) => {
const sortIndicator = header.querySelector('.sort-indicator');
if (index === activeIndex) {
const direction = this.sortDirections[index] === 1 ? '▲' : '▼';
sortIndicator.textContent = direction;
} else {
sortIndicator.textContent = '';
}
});
}
}
document.addEventListener('DOMContentLoaded', () => {
const tabela = document.querySelector('#moja-tabela');
const sortable = new SortableTable(tabela);
});
</script>
</body>
</html>
- Rejestracja: dni
- Ostatnio: dni
- Postów: 81
@4w0rX4t4X Sprawnie to działa dla 5 wierszy. Czy jednak będzie podobnie szybko. gdy ilość wierszy wzrośnie do np. 500 lub 1000?
Czy wtedy nie lepiej ponownie zapytać bazę o posortowanie inaczej dane?
- Rejestracja: dni
- Ostatnio: dni
- Postów: 351
Blackhole napisał(a):
@4w0rX4t4X Sprawnie to działa dla 5 wierszy. Czy jednak będzie podobnie szybko. gdy ilość wierszy wzrośnie do np. 500 lub 1000?
Czy wtedy nie lepiej ponownie zapytać bazę o posortowanie inaczej dane?
- Skoro jesteś na tyle leniwy, że nie chce Ci się sprawdzić gotowca robiąc jedynie ctrl+c i ctrl+v to nie oczekuj, że ja to zrobię za Ciebie.
- Prawie zawsze lepiej zapytać o takie coś baze danych.
- Rejestracja: dni
- Ostatnio: dni
- Postów: 81
Zrobiłem Ctrl+C Ctrl+V (jak już zadałem pytanie) i dla ~700 działało równie sprawnie (tak mi się przynajmniej zdawało).
Takie "proste" sortowanie jest jednakże ograniczające w ten sposób, że prezentowane są zawsze te same dane. Nie ma tu np. opcji "grupowania wierszy" - tzn. nie wyświetlania za każdym razem wartości kolumny, po której jest sortowanie, jeśli wartość ta nie różni się od wartości w wierszu poprzednim.
Przykładowo: Jeśli sortuję po osobie (imię i nazwisko jako 1 dana) to wiersz z tą osobą mógłby być prezentowany 1 raz (tylko na początku grupy wierszy, która go zawiera) z odpowiednim atrybutem colspan, aby zajmował cały wiersz tabeli. Kolejny wiersz z danymi osoby pojawiłby się dopiero, gdy osoba będzie inna.
Czy mogę prosić Cię o nawiązanie do mojej uwagi o OOP (w PHP)? Co tu mogłoby być klasą PHP? Nie za bardzo się orientuję w tym jeszcze...
- Rejestracja: dni
- Ostatnio: dni
IMHO, fetch-em odpytaj backend według zadanego przez użytkownika na stronie kryterium, niech sql zrobi robotę sortowania, przyślij tylko gotowy kod html wierszy i zamień kod w tbody tabeli.
Czy jednak będzie podobnie szybko. gdy ilość wierszy wzrośnie do np. 500 lub 1000?
możesz użyć paginacji dla zwracanych wyników, aby ograniczyć ich ilość wyświetlanych na stronie, aby uzyskać sensowną długość tabeli.
Jest to technika, która polega na podzieleniu dużych zbiorów wyników na mniejsze strony, np. po 10, 50 czy 100 wyników, aby ułatwić przeglądanie i zarządzanie danymi.
W kontekście programowania lub projektowania stron internetowych, paginacja jest często używana w połączeniu z bazami danych, gdzie zapytania SQL mogą ograniczać wyniki przy użyciu klauzul takich jak LIMIT i OFFSET. W interfejsach użytkownika paginacja jest zwykle reprezentowana przez numerowane linki do stron lub przyciski „Dalej”/„Poprzednia”.