Column-wise filter

Column-wise filter

ralfeusralfeus Posts: 24Questions: 6Answers: 1

Hi all,
I have a table with custom column-wise filter. It's defined like that:

    <table id="order_products" class="table">
        <thead>
            <tr>
                <td></td>
                <td></td>
                <td><input /></td>
                <td><input /></td>
            </tr>
            <tr>
                <th></th>
                <th scope="col" style="width: 1em;">ID</th>
                <th scope="col" style="width: 1em;">Order ID</th>
                <th scope="col">Customer</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    var table = $('#order_products').DataTable({
        dom: 'lrBtip',  
        ajax: {
            url: '/api/v1/admin/order/product',
            dataSrc: 'data'
        },
        columns: [
            {
                "className":      'details-control',
                "orderable":      false,
                "data":           null,
                "defaultContent": ''
            },
            {data: 'id'},
            {data: 'order_id'},
            {data: 'customer'}
      ],
        select: true,
        serverSide: true,
        processing: true,
        colReorder: true,
        initComplete: function() { init_search(this, g_filter_sources) }
    });

function init_search(table, filter_sources) {
    var promise = $.Deferred();
    var columns_left = table.api().columns().count();
    table.api().columns().every(function() { 
        column = this;
        $('td:nth-child(' + (this.index() + 1) + ') input', 
            $(this.header()).closest('thead'))
            .each((_idx, item) => init_search_input(item, column))
            .val('');
        columns_left--;
        if (!columns_left) {
            promise.resolve();
        }
    });
    return promise;
}

function init_search_input(target, column) {
    $(target).on('keyup change clear', function () {
        if ( column.search() !== this.value ) {
            column
                .search(this.value, false)
                .draw();
            // console.log(column.dataSrc(), this.value);
        }
    });
}

Filtering works fine until the moment I reorder columns. In this case there are two filterable columns: order_id and customer. If I swap them the filter inputs still work as they were on their original places.

I tried to add reorder event handler and reinitialize filtering like that:

table.on('column-reorder', () => { init_search($('#order_products').dataTable(), g_filter_sources) });

but it didn't have any effect.

What could you suggest to overcome it?

Answers

  • kthorngrenkthorngren Posts: 21,301Questions: 26Answers: 4,946

    You probably need to turn of the event listeners before re-applying them, for example:

    function init_search_input(target, column) {
        $(target)
        .off('keyup change clear')
        .on('keyup change clear', function () {
            if ( column.search() !== this.value ) {
    ....
    

    See this example;
    http://live.datatables.net/coxehozu/1/edit

    Otherwise you will hit the event handler more than once after reordering the columns. If this doesn't help please provide a test case replicating the issue so we can help debug.

    Kevin

Sign In or Register to comment.