Spring Data JPA ve Thymeleaf Kullanarak Tablo İçeriğini Sıralama

Süleyman Can
Kod Gemisi
Published in
4 min readDec 10, 2018

Web tabanlı uygulamalarımızda kullandığımız HTML tablolarının içeriğinin artan veya azalan olarak sıralanabilir olması kullanıcı deneyimi için önemlidir.

User Experience

Bu deneyim için JavaScript temel alınarak oluşturulmuş Footable gibi hazır kütüphaneler mevcuttur. Hazır kütüphaneler varsayılan olarak tabloda o anda bulunan veriyi sıralamaktadır. Bu kütüphanelerin kullanışlı olabilmesi için sunacağımız verinin List gibi veri yapılarıyla tabloya aktarılması gerekmektedir ancak verinin tamamının tabloya aktarılması uygulamaların hızını olumsuz etkileyecektir.

Spring Data JPA, PagingAndSortingRepository interface’i verinin tamamını döndürmek yerine, Pageable yardımıyla URL parametresinde sayfa numarası, veri sayısı ve sıralama seçeneğiyle verinin belirli bir kısmını Page olarak dönmemizi sağlamaktadır.

Hazır kütüphaneler varsayılan olarak tabloda o anda bulunan verileri sıralar demiştik. Tabloya page olarak veri döndüğümüzde Footable sadece döndüğümüz veri üzerinde bir sıralama yapacaktır. Sayfalama ile bir sonraki sayfaya geçtiğimizde bu yeni bir istek oluşturarak farklı verilerin gelmesini sağlayacaktır. Bu durumda Footable eski verileri ve seçtiğimiz sıralama seçeneğini unutacak ve istediğimiz sonucu vermeyecektir.

Bu sorun, Footable’ı JavaScript kodlarıyla manipüle ederek aşılabilir. Kullandığımız kütüphaneyi manipüle etmek, kütüphanenin detaylarına hakim olmayı gerektirir. Bu da ilgili kütüphanenin detaylarını öğrenmek için bir zaman maliyeti getirmektedir.

Sayfalama

Çalıştığımız projeye ekstra bir kütüphane dahil etmeden Thymeleaf ile tablo içeriğine göre sıralama yapmak için mini bir uygulama hazırladım. Bu uygulamada çalışanların workloglarını tabloda görüntüleyeceğiz. Uygulamada kullandığım bazı teknoloji ve bağımlılıklar:
Spring Boot, Data-JPA, Thymeleaf, jFairy (Tabloyu dolduracak test verileri için), Lombok, H2 Database

Burada kod olarak sadece yazının konusunu kapsayan yerleri açıklayacağım. Uygulamanın tamamına yazının sonundaki linkten erişebilirsiniz.

WorkLogController
WorkLogRepository

WorkLogController sınıfındaki index metodu /work-logs endpoint’ine gelen isteği karşılamaktadır. Metot parametresi olarak alınan Pageable, sayfalandırma bilgisi için bir arayüzdür. /work-logs endpoint’ine gelen isteklerde pageable referansı default olarak [number: 0, size:20, sort: UNSORTED] değerlerini alır. Number, bulunduğumuz sayfayı, size sayfada görüntülenecek veri sayısını, sort sıralama seçeneğini tutmaktadır. WorkLogService sınıfındaki getWorkLogs(Pageable pageable) metodu, WorkLogRepository findAll(Pageable pageable) metodunu kullanmakta ve Page<WorkLog> dönmektedir.

WorkLogController index metodunda view olarak “workLogs/index” dönmektedir. Bu view’da sıralama ve sayfalama işlemleri yapılacaktır.

workLogs/index

<tr> tagindeki sortable sınıfı JavaScript’te <th> tagleri için css seçici olarak kullanılmaktadır. Thymeleaf’te @ beanName syntax’ı ile Application Context’teki beanlere erişilebilmektedir. Burada PagingAndSortingService sınıfındaki metotlara erişim sağlanmaktadır. Thymeleaf th:with attribute ile local değişken tanımlanabilmektedir.

PagingAndSortingService

setSorInfoArray metodunun parametre olarak aldığı Page’in getSort() metodu “sorting property: sorting direction” dönmektedir. Bu değer split(“:”) edilerek sortInfoArray değişkenine atanmaktadır. sortInfoArray değişkenini return etmeden önce sorting direction’un önündeki boşluktan kurtulmak için Java 8 yardımıyla trim edilmektedir.

getSortClassName metodu tablonun başlık kısmındaki sembollerin yönünü belirleyecek sınıfları oluşturmaktadır. propertyName, ilgili <th> tagının sıralama ismini tutmaktadır. Bu metottan ilgili if kontrolü sonrası properyName’e göre üç css sınıfı oluşmaktadır: notSorted, sortedASC ve sortedDESC.

Sembol
sortingTable.css

<th> etiketleri içerisindeki data-sort attribute ile, sıralama tercihine göre yapacağımız GET isteklerinin property name değişkenleri tutulmaktadır. Bu değişkenler sortingTable.js’te kullanılmaktadır.

sortingTable.js

if (!location.search), URL’de parametre olup olmadığını kontrol etmektedir. URL’de parametre yoksa ve ilgili <th> tagi sortedASC sınıfına sahipse, data attribute ile gelen property ve DESC (azalan) sıralama tercihi birlikte istek için bir parametre oluşturur. İlgili <th> tagi sortedASC sınıfına sahip değilse, ilgili property ve ASC (azalan) sıralama tercihi birlikte istek için bir parametre oluşturur. Sort parametremiz URL’deki ilk parametre olduğundan ? ile eklendi.

Bu basit uygulamamızda filtreleme seçenekleri yok fakat uygulama filtrelemeyi de destekleyecek biçimde yazıldı. if(!location.search) şartının else kısmı yani URL’de parametre olma durumunda, filtrelemede sort parametresi kullanılmış olabilir. URL’de sort parametresi varsa removeParam metodu bu sort parametresini kaldırmaktadır. Sonraki akış ilk durum ile benzer. URL’de başka parametrelerin olacağı tahmin edildiğinden, sort parametresi & ile eklendi. removeParam metodunun detaylarına uygulamanın kaynak kodundan erişebilirsiniz.

Sayfalama bu yazının ana konusu olmadığı için kod parçalarına yer verilmedi. Örnek uygulamayı inceleyerek sayfalamanın detaylarını inceleyebilirsiniz. PagingAndSortingService sınıfında buildMultiParamUrl metodu ve workLog/index view sayfasının <table> tag’inden sonraki kısım sayfalama için kullanılmaktadır. Sayfa değişikliğinde URL’deki page ve size parametreleri dışındaki parametreler buildMutliParamUrl metodu ile eklenmektedir.

örnek: sort=id,DESC

Uygulamanın github reposuna bu linkten erişebilirsiniz. Uygulama ilerleyen aşamalarda daha da generic (genel) hale getirilip, kütüphane olarak sunulabilir.

Gökhan Birinci, Merve Sarpkaya ve Ersan Ceylan’a katkılarından dolayı teşekkür ederim.

--

--