90 votes

Tableaux de données jQuery : Retarder la recherche jusqu'à ce que 3 caractères aient été tapés OU qu'un bouton ait été cliqué

Existe-t-il une option permettant de ne lancer la recherche qu'après avoir saisi 3 caractères ?

J'ai écrit un script PHP-script pour des collègues qui affichent 20 000 entrées et ils se plaignent que lorsque l'on tape un mot, les premières lettres provoquent un blocage.

Une autre solution consisterait à lancer la recherche en cliquant sur un bouton et non en tapant un caractère.

Voici 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'
        }
} );

1 votes

Pour le délai uniquement, essayez ceci dans la table de données config { searchDelay : value } value is an integer of milliseconds

93voto

cale_b Points 5864

Solution pour la version 1.10 -

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

Le code ci-dessous permet de retarder la recherche jusqu'à ce qu'au moins 3 caractères soient saisis :

// 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;
    });

4 votes

Pour ceux d'entre vous qui ont des difficultés à faire fonctionner ce système, essayez de l'utiliser dans le fichier init.dt événement, par exemple $('#yourTable').on('init.dt', function () { ... }); .

0 votes

Dans la version 11, vous devez d'abord définir la chaîne de recherche, puis exécuter fnDraw() comme suit : $(".datatable").dataTable().api().search("aaaa2");$(".datatable").dataTable().fnDraw()

0 votes

@HeshamYassin - c'est ce que cela fait, mais notez que ce code fait référence à l'objet instance renvoyé ( dtable dans le code ci-dessus) pour redessiner, plutôt que de créer une nouvelle instance.

77voto

Stony Points 2137

Note : Il s'agit d'une version beaucoup plus ancienne des tableaux de données. cette réponse pour les tables de données jQuery v1.10 et plus.


Cela modifiera le comportement de la boîte de saisie pour qu'elle ne filtre que si l'on a appuyé sur la touche "retour" ou si la recherche comporte au moins 3 caractères :

$(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 se lient à la fois à keypress et à keyup, mais je les surcharge tous les deux pour rester compatible, même si je pense que keyup est suffisant.

J'espère que cela vous aidera !

2 votes

J'ai également remarqué cela. Le fait d'être lié à la fois à keypress et à keyup signifie que la requête est déclenchée deux fois. Pour ceux qui regardent à la maison, vous devriez simplement enlever l'un ou l'autre des deux liens (unbind et bind).

1 votes

Cette solution ne fonctionne pas lorsque l'on appuie sur l'espace arrière. @Sam Barnes est la meilleure réponse

2 votes

Comme alternative à l'excellente réponse de Sam Barnes, vous pouvez modifier ceci pour tenir compte de l'espacement arrière (et dégager le champ) en remplaçant e.keycode != 13 con e.keyCode > 13 qui se déclenchera également lorsqu'ils tabuleront hors du champ.

32voto

Sam Barnes Points 231

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 cela vous aidera.

0 votes

Fonctionne bien, mais je dois changer oTable.fnFilter(...) pour qu'il fasse référence à mon instance de table de données.

0 votes

Il ne s'agit pas vraiment d'une version étendue, mais d'une solution totalement différente (mais utile). Je me demande cependant ce que le paramètre searchWait fait qui ne pourrait pas être accompli par setTimeout(function(){...}, 600) puisque la fonction ne semble pas être réactivée pour d'autres caractères.

0 votes

@cincodenada il faut que ce soit un setInterval En effet, il se réactive toutes les 200/600 ms et vérifie si searchWait n'a pas été remis à 0. Par exemple, si vous continuez à entrer quelque chose dans le champ d'entrée, vous remettrez toujours searchWait à 0 = la recherche n'est jamais exécutée. Cependant, je trouve l'utilisation de searchWait en tant qu'entier, qui compte jusqu'à 3, plutôt obscure. Il serait préférable d'utiliser un indicateur vrai/faux si l'entrée de l'utilisateur s'est produite et un indicateur setInterval de 600.

13voto

Chad Kuehn Points 240

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;
});

7voto

Christian Noel Points 118

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;
}

l'utilisation :

$('#table').dataTable().fnSetFilteringEnterPress();

0 votes

Ne voulez-vous pas "si la longueur est supérieure à 2 o la touche entrée a-t-elle été activée ? if ( anControl.val().length > 2 || e.keyCode == 13)

0 votes

Oui, cela fonctionne également. Je me concentre davantage sur la validation, de sorte que même si une chaîne vide est transmise et que la touche Entrée a été pressée, rien ne se produit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X