Side filters

Example with Side filters

Sometimes you need to provide to the user more control over the queryset used to populate the table, using interactive and specific filters.

In those cases, you can easily add a sidebar with the required widgets, then collect and apply user selections at every table refresh.

How it works

First, add to the template all required input widgets, and schedule a table redraw whenever a filter has been changed (or when you believe is more appropriate)

<div class="col-sm-2 filters">
    <h4>Filters</h4>
    <label for="from_year">From year:</label><input type="number" id="from_year">
    <label for="to_year">To year:</label><input type="number" id="to_year">
    ...
    
$(document).ready(function() {

    $('.filters input').on('change paste keyup', function() {
        // redraw the table
        $('#datatable').DataTable().ajax.reload(null, false);
    });

});
    

At table initialization, register in the "extra data" section the callbacks needed to collect user selections

$(document).ready(function() {

    AjaxDatatableViewUtils.initialize_table(
        ...
        }, {
            // extra_data
            from_year: function() { return $('input#from_year').val() },
            to_year: function() { return $('input#to_year').val() },
            check_year_null: function() { return $("input[name='check_year_null']:checked").val() }
        },
    );

});
    

Those "extra data" values will be sent to the AjaxDatatableView with every request; you can take advantage of those by filtering the queryset in the `get_initial_queryset()` override.

class AlbumAjaxDatatableView(AjaxDatatableView):

    ...

    def get_initial_queryset(self, request=None):

        def get_numeric_param(key):
            try:
                value = int(request.POST.get(key))
            except:
                value = None
            return value

        queryset = super().get_initial_queryset(request=request)

        check_year_null = get_numeric_param('check_year_null')
        if check_year_null is not None:
            if check_year_null == 0:
                queryset = queryset.filter(year=None)
            elif check_year_null == 1:
                queryset = queryset.exclude(year=None)

        from_year = get_numeric_param('from_year')
        if from_year is not None:
            queryset = queryset.filter(year__gte=from_year)

        to_year = get_numeric_param('to_year')
        if to_year is not None:
            queryset = queryset.filter(year__lte=to_year)

        return queryset
    

Filters