web-dev-qa-db-fra.com

jQuery DataTables: retarde la recherche jusqu'à ce que 3 caractères aient été saisis OR un bouton cliqué

Existe-t-il une option permettant de lancer la recherche uniquement après la saisie de 3 caractères?

J'ai écrit un script PHP à l'intention de collègues affichant 20 000 entrées. Ils se plaignent du fait que, lors de la saisie d'un mot, les premières lettres gèlent tout.

Une autre solution consisterait à lancer la recherche en cliquant sur un bouton et non en saisissant des caractères.

Ci-dessous mon code actuel:

$("#my_table").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "bAutoWidth": false,
        "aoColumns": [
                /* qdatetime */   { "bSearchable": false },
                /* id */          null,
                /* name */        null,
                /* category */    null,
                /* appsversion */ null,
                /* osversion */   null,
                /* details */     { "bVisible": false },
                /* devinfo */     { "bVisible": false, "bSortable": false }
        ],
        "oLanguage": {
                "sProcessing":   "Wait please...",
                "sZeroRecords":  "No ids found.",
                "sInfo":         "Ids from _START_ to _END_ of _TOTAL_ total",
                "sInfoEmpty":    "Ids from 0 to 0 of 0 total",
                "sInfoFiltered": "(filtered from _MAX_ total)",
                "sInfoPostFix":  "",
                "sSearch":       "Search:",
                "sUrl":          "",
                "oPaginate": {
                        "sFirst":    "<<",
                        "sLast":     ">>",
                        "sNext":     ">",
                        "sPrevious": "<"
                },
                "sLengthMenu": 'Display <select>' +
                        '<option value="10">10</option>' +
                        '<option value="20">20</option>' +
                        '<option value="50">50</option>' +
                        '<option value="100">100</option>' +
                        '<option value="-1">all</option>' +
                        '</select> ids'
        }
} );
66
Alexander Farber

Solution pour la version 1.10 -

Après avoir cherché ici une réponse complète et ne pas en avoir trouvé, je l'ai écrit (en utilisant le code de la documentation et quelques réponses ici).

Le code ci-dessous fonctionne pour retarder la recherche jusqu'à ce qu'au moins 3 caractères soient entrés:

// Call datatables, and return the API to the variable for use in our code
// Binds datatables to all elements with a class of datatable
var dtable = $(".datatable").dataTable().api();

// Grab the datatables input box and alter how it is bound to events
$(".dataTables_filter input")
    .unbind() // Unbind previous default bindings
    .bind("input", function(e) { // Bind our desired behavior
        // If the length is 3 or more characters, or the user pressed ENTER, search
        if(this.value.length >= 3 || e.keyCode == 13) {
            // Call the API search function
            dtable.search(this.value).draw();
        }
        // Ensure we clear the search if they backspace far enough
        if(this.value == "") {
            dtable.search("").draw();
        }
        return;
    });
55
cale_b

Remarque: il s’agissait d’une version beaucoup plus ancienne des tables de données, veuillez consulter cette réponse pour les tableaux de données jQuery v1.10 et supérieurs.


Cela modifiera le comportement de la zone de saisie de manière à ne filtrer que si l'un des retours a été appuyé ou s'il y a au moins 3 caractères dans la recherche:

$(function(){
  var myTable=$('#myTable').dataTable();

  $('.dataTables_filter input')
    .unbind('keypress keyup')
    .bind('keypress keyup', function(e){
      if ($(this).val().length < 3 && e.keyCode != 13) return;
      myTable.fnFilter($(this).val());
    });
});

Vous pouvez le voir fonctionner ici: http://jsbin.com/umuvu4/2 . Je ne sais pas pourquoi les gens de dataTables sont liés à la fois à la frappe et à la frappe, mais je demande à tous les deux de rester compatibles bien que je pense que la touche est suffisante.

J'espère que cela t'aides!

74
Richard

Pourquoi ne pas essayer cette version étendue de la réponse de Stony :)

var searchWait = 0;
var searchWaitInterval;
$('.dataTables_filter input')
.unbind('keypress keyup')
.bind('keypress keyup', function(e){
    var item = $(this);
    searchWait = 0;
    if(!searchWaitInterval) searchWaitInterval = setInterval(function(){
        if(searchWait>=3){
            clearInterval(searchWaitInterval);
            searchWaitInterval = '';
            searchTerm = $(item).val();
            oTable.fnFilter(searchTerm);
            searchWait = 0;
        }
        searchWait++;
    },200);

});

Cela retardera la recherche jusqu'à ce que l'utilisateur ait cessé de taper.

J'espère que ça aide.

30
Sam Barnes

Voici comment le gérer avec le changement d'api dans la version 1.10

var searchbox = $('#promogrid_filter input');
var pgrid = $('#promogrid').DataTable();

//Remove default datatable logic tied to these events
searchbox.unbind();

searchbox.bind('input', function (e) {
   if(this.value.length >= 3) {
      pgrid.search(this.value).draw();
   }
   if(this.value == '') {
      pgrid.search('').draw();
   }
   return;
});
10
Chad Kuehn

Voici un script de type plugin qui étend les tables de données.

jQuery.fn.dataTableExt.oApi.fnSetFilteringEnterPress = function ( oSettings ) {
    var _that = this;

    this.each( function ( i ) {
        $.fn.dataTableExt.iApiIndex = i;
        var
            $this = this, 
            oTimerId = null, 
            sPreviousSearch = null,
            anControl = $( 'input', _that.fnSettings().aanFeatures.f );

            anControl
              .unbind( 'keyup' )
              .bind( 'keyup', function(e) {

              if ( anControl.val().length > 2 && e.keyCode == 13){
                _that.fnFilter( anControl.val() );
              }
        });

        return this;
    } );
    return this;
}

usage:

$('#table').dataTable().fnSetFilteringEnterPress();
6
Christian Noel

Faire est d'appeler l'appel du serveur après que l'utilisateur a tapé les caractères minins dans le champ de recherche, vous pouvez suivre suggestion d'Allan

personnalisez la fonction API du plug-in fnSetFilteringDelay () pour ajouter une condition supplémentaire sur la longueur de la chaîne avant de définir le filtre, également considérer une entrée de chaîne vide pour effacer le filtre

Donc, pour un minimum de 3 caractères, changez simplement la ligne 19 dans le plug-in en:

if ((anControl.val().length == 0 || anControl.val().length >= 3) && (sPreviousSearch === null || sPreviousSearch != anControl.val())) {
6
Marius Butuc

Cela fonctionne sur DataTables 10.0.4:

var table = $('#example').DataTable();

$(".dataTables_filter input")
    .unbind()
    .bind('keyup change', function(e) {
        if (e.keyCode == 13 || this.value == "") {
            table
                .search(this.value)
                .draw();
        }
    });

JSFiddle

5

Ma version des datatables 1.10.10

J'ai changé un peu de choses et ça marche maintenant. Donc, je partage, car il était difficile de le faire fonctionner pour la version 1.10.10. Merci à cale_b, Stony et Sam Barnes. Regardez le code pour voir ce que j'ai fait.

    var searchWait = 0;
    var searchWaitInterval;
    $('.dataTables_filter input')
    .unbind() // leave empty here
    .bind('input', function(e){ //leave input
        var item = $(this);
        searchWait = 0;
        if(!searchWaitInterval) searchWaitInterval = setInterval(function(){
            if(searchWait >= 3){
                clearInterval(searchWaitInterval);
                searchWaitInterval = '';
                searchTerm = $(item).val();
                oTable.search(searchTerm).draw(); // change to new api
                searchWait = 0;
            }
            searchWait++;
        },200);

    });
3
Zante

Utilisez ceci

   "fnServerData": function (sSource, aoData, fnCallback, oSettings) {

            if ($("#myDataTable_filter input").val() !== "" && $("#myDataTable_filter input").val().length < 3)
                return;
            oSettings.jqXHR = $.ajax({
                "dataType": 'json',
                "timeout":12000,
                "type": "POST",
                "url": sSource,
                "data": aoData,
                "success": fnCallback
            });
        }
3
Nitin Bourai

Vous pouvez retarder l'appel ajax au serveur de cette façon

var search_thread = null;
    $(".dataTables_filter input")
        .unbind()
        .bind("input", function(e) { 
            clearTimeout(search_thread);
            search_thread = setTimeout(function(){
                var dtable = $("#list_table").dataTable().api();
                var elem = $(".dataTables_filter input");
                return dtable.search($(elem).val()).draw();
            }, 300);
        });

Ce code arrêtera l'appel ajax si l'intervalle de temps entre deux pressions est inférieur à 300 ms. Ainsi, lorsque vous écrivez un mot, un seul appel est exécuté et uniquement lorsque vous arrêtez de taper . avec le paramètre retard (le 300) afin d'obtenir plus ou moins de retard

2
zion ben yacov

bien que cela ne réponde pas à la question initiale, j’ai effectué une recherche complexe et lente sur mes datatables. l'événement de filtre était déclenché après chaque pression sur une touche, ce qui signifiait un délai perceptible après 10 caractères. Donc, en introduisant un court délai après une pression sur une touche avant le déclenchement de l’événement de filtrage, où une pression ultérieure a réinitialisé le compteur et empêché la recherche précédente, j’ai pu rendre la recherche beaucoup plus rapide. d'autres peuvent trouver cela utile.

j'ai utilisé les réponses de Stony et Christian Noel pour faire ceci:

var dataTableFilterTimeout;
var dataTableFilterWait = 200; // number of milliseconds to wait before firing filter

$.fn.dataTableExt.oApi.fnSetFilteringEnterPress = function ( oSettings ) {
    var _that = this;
    this.each( function ( i ) {
        $.fn.dataTableExt.iApiIndex = i;
        var $this = this;
        var oTimerId = null;
        var sPreviousSearch = null;
        anControl = $( 'input', _that.fnSettings().aanFeatures.f );
        anControl.unbind( 'keyup' ).bind( 'keyup', function(e) {
            window.clearTimeout(dataTableFilterTimeout);
            if ( anControl.val().length > 2 || e.keyCode == 13){
                dataTableFilterTimeout = setTimeout(function(){
                    _that.fnFilter( anControl.val() );
                },dataTableFilterWait);
            }
        });
        return this;
    } );
    return this;
}
2
pgee70

Si vous utilisez l'ancienne version, ça y ressemble. La solution de Richard fonctionne bien. Mais lorsque je l'utilise, j'ai simplement ajouté de nouveaux événements, sans les supprimer. Parce que lorsque le code est exécuté, la table n'est pas encore créée. J'ai donc trouvé la méthode fnInitComplete (feu lorsque la table est créée) et je l'ai appliquée à la solution de Ricard. C'est ici

$("#my_table").dataTable( {
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "bAutoWidth": false,
         ...
         ...,
         "fnInitComplete": function (oSettings, json) {
                    var activeDataTable = $(this).DataTable();
                    $("#my_table_filter input")
                        .unbind('keypress keyup')
                        .bind('keypress keyup', function (e) {

                        if ($(this).val().length < 3 || e.keyCode !== 13) return;
                        activeDataTable.fnFilter($(this).val());
                    });
                }
1
cihancoskun

Version fixe pour les tables de données 1.10.12 utilisant l'API et libérant correctement la 'entrée'. Également ajouté la recherche effacée sur le retour arrière sous la limite de caractères.

    // Create the Datatable
    var pTable = $('#pTable').DataTable();

    // Get the Datatable input box and alter events
    $('.dataTables_filter input')
    .unbind('keypress keyup input')
    .bind('keypress keyup input', function (e) {
        if ($(this).val().length > 2) {
            pTable.search(this.value).draw();
        } else if (($(this).val().length == 2) && (e.keyCode == 8)) {
            pTable.search('').draw();
        }
    });
1
Tino

Vous devrez probablement modifier le plugin.

Et au lieu de définir X caractères, utilisez un délai, de sorte que la recherche commence une fois que la saisie a cessé pendant environ 1 seconde.

Ainsi, la liaison keydown/keyup qui déclenche actuellement la recherche serait modifiée avec une minuterie ...

var timer;
clearTimeout(timer);
timer = setTimeout(searchFunctionName, 1000 /* timeToWaitInMS */);
1
smdrager

Vous pouvez obtenir la longueur des données transmises en utilisant data.currentTarget.value.length, voir ci-dessous.

$('[id$="Search"]').keyup(function (data) {
            if (data.currentTarget.value.length > 2 || data.currentTarget.value.length == 0) {
                if (timoutOut) { clearTimeout(timoutOut); }
                timoutOut = setTimeout(function () {
                    var value = $('[id$="Search"]').val();
                    $('#jstree').jstree(true).search(value);
                }, 250);
            }
        });

et évidemment vous voudriez que ce code soit exécuté lors de la suppression de texte, définissez donc la valeur sur 0

1
Tom McDonough

Pouvez-vous écrire votre propre fonction pour tester la longueur de la chaîne entrée attachée à un gestionnaire d'événements onKeyUp et déclencher la fonction de recherche une fois que la longueur minimale est atteinte?

Quelque chose dans le genre de:

 input.onKeyUp (function () {
 if (input.length> 3) {
 mySearchfunction (); 
} 
}); 

... c'est-à-dire, dans un pseudo-code, mais vous obtenez le Jist.

0
Chris

Vous pouvez utiliser le paramètre nom minlength afin de limiter la recherche à 3 caractères:

function(request, response) {
    $.getJSON("/speakers/autocomplete", {  
        q: $('#keywordSearch').val()
    }, response);
}, minLength: 3
0
Lokesh S