Procent od jakiś dwóch lat pisze jakie fajny jest plugin do jQuery o nazwie DataTables. 3 dni temu w końcu miałem okazję się przekonać, jaki on naprawdę jest fajny! :)

Jeżeli jeszcze z niego nie korzystaliście, to zachęcam do zapoznania się z nim. Na stronie dostępne jest wiele przykładów pokazujących co i jak – naprawdę aż dziw bierze, że coś open-source może mieć taką dokumentację.

Tak czy siak, podczas pracy z DataTables, zacząłem korzystać z dwóch klas, które uważam, że mogą się przydać wszystkim. Pierwsza klasa to parametry jakie DataTables przekazuje podczas ładowania danych/stronicowania/sortowania czy filtrowania:

public class DataTablesParamModel
{
    public string sColumns { get; set; } 
    public string sEcho { get; set; }
    public string sSearch { get; set; }
    
    // long not int as nh returns count as long
    // it's easier to work like that
    public long iDisplayLength { get; set; }
    public long iDisplayStart { get; set; }
    
    public int iColumns { get; set; }
    public int iSortingCols { get; set; }
 } 

Niestety, dodanie już kolejnych własności do modelu, wymaga własnego model binder – z tego co się orientuje przynajmniej. Chodzi o to, że część parametrów ma nazwę iSortCol_10 gdzie 10 to numer kolumny w tabeli.

Druga klasa, to wynik jaki oczekuje rozszerzenie:

public class DataTablesResultModel
{
    public string sEcho { get; set; }

    // long not int as nh returns count as long
    public long iTotalRecords { get; set; }
    public long iTotalDisplayRecords { get; set; }

    public IEnumerable<string[]> aaData { get; set; }
}

Mała uwaga, iTotalRecords powinien zawierać liczbę wszystkich rekordów w bazie danych – nie zależnie od filtrowania, zaś iTotalDisplayRecords, liczbę rekordów po filtrowaniu, ale nie liczbę rekordów zwracanych w danym zapytaniu. Więcej informacji na temat parametrów, wraz z ich opisem, można znaleźć tutaj – także tych brakujących w DataTablesParamModel.

Mając te dwie klasy, zrobienie stronicowania i dynamicznego ładowania danych nie mogłoby być prostsze. Tworzymy naszą akcję w kontrolerze na http post, w której robimy operację stronicowania, filtrowania itp. i następnie zwracamy nasz wynik:

[HttpPost]
public virtual ActionResult PagedIndex(DataTablesParamModel model)
{
    // do paging/sorting/filtering etc.

    var result = new DataTablesResultModel
    {
        sEcho = model.sEcho,
        iTotalRecords = list.Count,
        iTotalDisplayRecords = list.Count,
        aaData = list.Select(x => new[]
        {
            x.One, 
            x.Two
        })
    };

    return Json(result);
}

Zaś po stronie klienta piszemy następujący kod JS:

$(document).ready(function () {
    $('#table').dataTable({
        bProcessing: true,
        bServerSide: true,
        sAjaxSource: '/Home/PagedIndex',
        fnServerData: function (sSource, aoData, fnCallback) {
            $.ajax({
                dataType: 'json',
                type: "POST",
                url: sSource,
                data: aoData,
                success: fnCallback
            });
        },
        iDisplayLength: 10,
        aaSorting: [[0, 'desc']],
        aoColumns: [
            { sName: 'One' },
            { sName: 'Two' }
        ]
    });
});

Proste i zarazem super funkcjonalne! Polecam :)

2 KOMENTARZE

  1. Zalecam jednak korzystanie z GET, tak jak datatables robi to domyślnie. Nie dalej jak dwa tygodnie temu spędziłem ponad 5 godzin nad problemem, gdzie IE i Opera ucinały w połowie JSON będący odpowiedzią z serwera i krzyczały, że nie można go sparsować. Miało to miejsce tylko wtedy, gdy nie był podłączony żaden debugger/fiddler itd… i dodatkowo pojawiało się może w 20-30% przypadków. Przez większość czasu wszystko działało, a czasami zonk. GET rozwiązało sprawę.

Comments are closed.