How to set pause before ajax send searching request to server, for exxclude spam

How to set pause before ajax send searching request to server, for exxclude spam

shuba_ivanshuba_ivan Posts: 8Questions: 4Answers: 0

I use "datatables.net-bs4": "^1.10.21", and I faced with problem when user fill some thing in search input I faced with many requests to server, looks like for each keyup created separate ajax reuest to server, this is a lot, I user quicly typing I had a lot requests, hot to set some time out for sending ajax request, example send ajax reaust to server one time in 3 second ?

I have global searching("searching": true) input and filter by separate column, I need some pasue before ajsx sen request for both approach and global and for seaparate column

var table = $('#empTable').DataTable({
                initComplete: function () {
                    // Apply the search
                    this.api().columns(separate_filter_column_keys).every( function () {
                        var that = this;

                        $( 'input', this.footer() ).on( 'keyup change clear', function () {
                            if ( that.search() !== this.value ) {
                                that
                                    .search( this.value )
                                    .draw();
                            }
                        } );
                    } );

                    this.api().columns(decline_reason_key).every( function () {
                        var column = this;
                        var select = $('<select><option value=""></option></select>')
                            .appendTo( $(column.footer()).empty() )
                            .on( 'change', function () {
                                var val = $.fn.dataTable.util.escapeRegex(
                                    $(this).val()
                                );

                                column
                                    .search( val ? val : '', false, false )
                                    .draw();
                            } );
                        $.each(data, function( key, value ) {
                            // console.log(key, value);
                            select.append( '<option value="'+value+'">'+value.substr( 0, 10 )+'</option>' )
                        });
                    } );
                },
                'responsive': true,
                'fixedHeader': true,
                'processing': true,
                'serverSide': true,
                'serverMethod': 'post',
                'ajax': {
                    'url':collectionData,
                },
                columns: th_keys,
                "columnDefs": common_defs
            });

I thought maybe like this way with timer setTimeout, but it's not works, server nothing got request

                    // Apply the search
                    this.api().columns(separate_filter_column_keys).every( function () {
                        var that = this;
                        function delay(callback, ms) {
                            var timer = 0;
                            return function() {
                                var context = this, args = arguments;
                                clearTimeout(timer);
                                timer = setTimeout(function () {
                                    callback.apply(context, args);
                                }, ms || 0);
                            };
                        }
                        $( 'input', this.footer() ).on( 'keyup change clear', function () {
                            if ( that.search() !== this.value ) {
                                let value = this.value;
                                delay(function (e) {
                                    that
                                        .search( value )
                                        .draw();
                                }, 1)

                            }
                        } );
                    } );

Answers

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954
    edited September 2020

    Without trying it I'm not sure how that code works but I suspect its supposed to delay the keyup ajax request. The 1 (1 ms) in line 21 is probably not long enough to notice a difference. Maybe make it 300 or something. If this doesn't help please provide a link to your page or a test case so we can debug the code.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    There have been similar discussion on the forum for the default search. Search the forum for search debounce to find other options. Or maybe you can find suggestions on Stack Overflow.

    Kevin

  • shuba_ivanshuba_ivan Posts: 8Questions: 4Answers: 0
    edited September 2020

    I found some solution, I create separate input and create keyup event for it, where I call delay function, but now I have two search input, what you advice about that, maybe just set display none ? I was try add bFilter equal false, but still faced with search input.. Only what I found for that use custom css like that:

    .dataTables_filter {
      display: none;
    }
    

    my js

            var table = $('#empTable').DataTable({
                "searching": true,
                "bFilter": false,
                initComplete: function () {
                    // Apply the search
                    this.api().columns(separate_filter_column_keys).every( function () {
                        var that = this;
    
                        $( 'input', this.footer() ).on( 'keyup change clear', function () {
                            if ( that.search() !== this.value ) {
                                that
                                    .search( this.value )
                                    .draw();
                            }
                        } );
                    } );
    
                    this.api().columns(decline_reason_key).every( function () {
                        var column = this;
                        var select = $('<select><option value=""></option></select>')
                            .appendTo( $(column.footer()).empty() )
                            .on( 'change', function () {
                                var val = $.fn.dataTable.util.escapeRegex(
                                    $(this).val()
                                );
    
                                column
                                    .search( val ? val : '', false, false )
                                    .draw();
                            } );
                        $.each(data, function( key, value ) {
                            // console.log(key, value);
                            select.append( '<option value="'+value+'">'+value.substr( 0, 10 )+'</option>' )
                        });
                    } );
                },
                'responsive': true,
                'fixedHeader': true,
                'processing': true,
                'serverSide': true,
                'serverMethod': 'post',
                'ajax': {
                    'url':collectionData,
                },
                columns: th_keys,
                "columnDefs": common_defs
            });
    
            function delay(callback, ms) {
                var timer = 0;
                return function() {
                    var context = this, args = arguments;
                    clearTimeout(timer);
                    timer = setTimeout(function () {
                        callback.apply(context, args);
                    }, ms || 0);
                };
            }
    
            $('#search_input').keyup(delay(function (e) {
                table.search( this.value ).draw();
            }, 2000));
        }
    

    But in this case it's works like that: user start fill some word in input search, and after user stop execute function delay, but this is not good, when user waiting 2 second after finished fill some search data... But without clearTimeout(timer); this is not make sense, could you advice something please, how to optimization requests spam ?

  • kthorngrenkthorngren Posts: 21,343Questions: 26Answers: 4,954

    I create separate input and create keyup event for it, where I call delay function, but now I have two search input, waht you advice about that,

    Sorry, I thought you were trying to delay the footer search inputs. You can use the searchDelay option with the default search input. Or if you want to use your own, use the dom option to remove the Datatables elements, for example: dom: 'ltrip',.

    Remove the line "bFilter": false,. I believe that is the legacy option to turn of table filtering.

    but this is not good, when user waiting 2 second after finished

    Did you try my suggestion of 300?

    could you advice something please, how to optimization requests spam ?

    Did you search the forum for search debounce? Here is one of the threads you might be interested in:
    https://datatables.net/forums/discussion/comment/169726/#Comment_169726

    As I said if you need help with this then please provide a test case we can work with. You can start with one of the serverside processing templates:
    https://datatables.net/manual/tech-notes/9#Server-side-processing

    Kevin

This discussion has been closed.