jQuery DataTables:3文字が入力されるか、ボタンがクリックされるまで検索を遅らせます


83

3文字入力してから検索を開始するオプションはありますか?

20,000エントリを表示する同僚向けのPHPスクリプトを作成しましたが、単語を入力すると最初の数文字ですべてがフリーズするという不満があります。

別の方法は、文字の入力ではなく、ボタンをクリックすることで検索を開始することです。

以下は私の現在のコードです:

$("#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'
        }
} );

回答:


76

バージョン1.10のソリューション-

ここで完全な答えを探しても見つからなかったので、これを書きました(ドキュメントのコードといくつかの答えをここに利用します)。

以下のコードは、少なくとも3文字が入力されるまで検索を遅らせるように機能します。

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

3
これを機能させるのに問題があるinit.dt場合は、イベントでこれを使用してみてください$('#yourTable').on('init.dt', function () { ... });
arao6 2014年

バージョン11では、最初に検索文字列を設定してから、fnDraw()を次のように実行する必要があります:$( "。datatable")。dataTable()。api()。search( "aaaa2"); $( "。 datatable ")。dataTable()。fnDraw()
Hesham Yassin

2
キーダウン機能の代わりに入力がありましたが、今はうまく機能しています。ありがとう
azza idz 2015

1
@Maxime動作する編集にロールバックしましたが、これらの誤った変数名の不一致は発生しませんでした。それでも編集/注意が必要だと思われる場合はお知らせください。
random_user_name 2016

1
@cale_bこれが1.10.16でも機能していることを確認できます。ありがとうございました。
AnotherDeveloper 2017年

77

注:これは、はるかに古いバージョンのデータテーブル用でした。jQueryデータテーブルv1.10以降についてはこの回答を参照しください。


これにより、入力ボックスの動作が変更され、returnキーが押された場合、または検索に3文字以上ある場合にのみフィルタリングされます。

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

あなたはそれがここで働いているのを見ることができます:http//jsbin.com/umuvu4/2。dataTablesの人々がkeypressとkeyupの両方にバインドしている理由はわかりませんが、keyupで十分だと思いますが、互換性を維持するために両方をオーバーライドしています。

お役に立てれば!


2
これにも気づきました。keypressとkeyupの両方にバインドすると、クエリが2回実行されます。家で見ている人は、バインド解除とバインドの両方からどちらか一方を取り出すだけです。
サンダーラビット

1
このソリューションは、バックスペースを押すと機能しません。@Sam Barnesがベストアンサーです
Idrees Khan

2
サム・バーンズ優れた解答する代わりに、あなたは置き換えることによって、バックスペース(およびフィールドをクリアする)を考慮するため、これを修正することができe.keycode != 13e.keyCode > 13、その意志も火災時にフィールドのうち、それらのタブ。
cincodenada 2013年

2
残念ながら、これはバージョン1.10では機能しませ
random_user_name 2014年

@ThunderRabbitが言ったことに従って、私が見つけた最善の方法は、両方のバインドを解除することでしたが、どちらか一方のみを再バインドするだけでした。 .unbind('keypress keyup') .bind('keypress', function(e) ...
nageeb 2015

33

ストーニーの答えのこの拡張バージョンを試してみませんか:)

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

});

これにより、ユーザーが入力を停止するまで検索が遅延します。

それが役に立てば幸い。


うまく機能します。ただし、データテーブルインスタンスを参照するには、oTable.fnFilter(...)を変更する必要があります。
yudhiWidyatama 2013

これは実際には拡張バージョンではなく、まったく異なる(しかし便利な)ソリューションです。ただし、searchWaitパラメーターが何をするのかについては混乱していますsetTimeout(function(){...}, 600)。これは、関数がそれ以上の文字で再起動されないように見えるためです。
cincodenada 2013年

@cincodenadaはsetInterval、200 / 600msごとに再起動し、searchWaitが0にリセットされていないかどうかを確認するため、である必要があります。たとえば、入力に何かを入力し続けると、searchWaitは常に0にリセットされます=検索は実行されません。ただし、searchWaitを整数として使用すると、3にカウントされ、かなりあいまいになります。ユーザ入力が起こったとあればより良いだけで、真/偽フラグだろうsetInterval600の
r3mark

3
jqueryDatatables 1.10.3ので、このためのオプションがあります:searchDelay
panmari

1
@ panmari-searchDelayは、指定された時間の検索を遅らせるだけで、ユーザーが入力を停止したときではなく、後でテーブルを再描画します(ajaxをトリガーします)。
Chris Landeza 2016年

12

バージョン1.10のAPI変更でそれを処理する方法は次のとおりです

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

8

私のバージョンのdatatables1.10.10

私は少し変更しました、そしてそれは今働きます。だから、私は共有しています、バージョン1.10.10で動作させるのが難しかったからです。cale_b、Stony、SamBarnesに感謝します。コードを見て、私が何をしたかを確認してください。

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

    });

7

これは、データテーブルを拡張するプラグインのようなスクリプトです。

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

使用法:

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

「長さが2を超える場合、またはEnterキーが押された場合は?if ( anControl.val().length > 2 || e.keyCode == 13)
Jeromy French 2013

うん、それも機能します。空の文字列が渡されてEnterキーが押されても何も起こらないように、検証側に焦点を当てています。
クリスチャンノエル2013年

6

ユーザーが検索ボックスに最小文字を入力した後にサーバー呼び出しを呼び出すと、Allanの提案に従うことができます。

fnSetFilteringDelay()プラグインAPI関数をカスタマイズして、フィルターを設定する前に文字列の長さに条件を追加します。また、空白の文字列入力を考慮してフィルターをクリアします。

したがって、最低3文字の場合は、プラグインの19行目を次のように変更するだけです。

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

6

これはDataTables1.10.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


4

1.10バージョンの場合、オプションでこのコードをJavaScriptに追加します。initCompleteは検索メソッドをオーバーライドし、3文字が書き込まれるまで待機します。私に光を与えてくれたhttp://webteamalpha.com/triggering-datatables-to-search-only-on-enter-key-press/に感謝します

    var dtable= $('#example').DataTable( {
        "deferRender": true,
        "processing": true,
        "serverSide": true,


        "ajax": "get_data.php",
        "initComplete": function() {
            var $searchInput = $('div.dataTables_filter input');

            $searchInput.unbind();

            $searchInput.bind('keyup', function(e) {
                if(this.value.length > 3) {
                    dtable.search( this.value ).draw();
                }
            });
        }

    } );
} );

3

これを使って

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

+1ニース。これは、datatablesの定義にうまく統合されています。ところで、私の場合は、aoData obj全体を返すのではなく、aoData [5] ['value'] ['value'](入力フィールドに入力されたテキスト)だけを返すだけで十分でした。
Werner

3

元の質問には答えられませんが、データテーブルを複雑でゆっくりと検索しました。フィルタイベントは、キーを押すたびに発生していました。つまり、10文字後にかなりの遅延が発生しました。そのため、キーを押してからフィルターイベントが発生するまでに短い遅延を導入し、その後のキーを押すとカウンターがリセットされて前の検索が妨げられるようにすることで、検索をはるかに高速に見せることができました。他の人はこれが役に立つと思うかもしれません。

私はこれを作るために石とキリスト教のノエルからの答えを使用しました:

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

3

これにより、サーバーへのajax呼び出しを遅らせることができます

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

このコードは、キーを押すまでの時間が300ミリ秒未満の場合、ajax呼び出しを停止します。このように、単語を書くと、ajax呼び出しは1回だけ実行され、入力を停止したときにのみ実行されます。多かれ少なかれ遅延を得るために、遅延パラメータ(300)で「遊ぶ」ことができます


2

おそらくプラグインを変更する必要があります。

また、X文字にする代わりに、遅延を使用して、1秒ほど入力を停止すると検索が開始されるようにします。

したがって、現在検索をトリガーしているキーダウン/キーアップバインディングはタイマーで変更されます...

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

1
「プラグインを変更する」とは、jquery.dataTables.jsを編集することを意味しますか?そして、後でそれを「最小化」する方法を知っていますか?
アレクサンダーファーバー2011

2

APIを使用し、「入力」のバインドを正しく解除するデータテーブル1.10.12のバージョンを修正しました。また、文字数制限の下のバックスペースで検索クリアを追加しました。

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

2

古いバージョンを使用している場合は、そのように見えます。リチャードのソリューションは正常に機能します。しかし、それを使用するときは、削除するのではなく、新しいイベントを追加するだけです。コードを実行しても、テーブルはまだ作成されていないためです。そこで、fnInitCompleteメソッド(テーブルが作成されたときに起動する)があることがわかり、それをRicardのソリューションに適用しました。ここにあります

$("#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());
                    });
                }

2

Medtronicデータテーブルまたは他のコードでこのコードを使用して、3文字を使用した後に検索できます。

        onDataLoad: function (RequestGrid) {
            // execute some code on ajax data load
            var searchInput = $('div.dataTables_filter input').val();
            if (searchInput.length() > 3 || searchInput.length() ==0) {
                alert(searchInput);
                dt.draw();
            }
            else {
                return false;
            }
        },

searchInput.length()== 0最初のショー。


1

onKeyUpイベントハンドラーにアタッチされた入力文字列の長さをテストし、最小の長さに達したら検索関数をトリガーする独自の関数を作成できますか?

次のようなもの:

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

...つまり、疑似コードのような方法ですが、要点はわかります。


1

検索を3文字まで制限するために、minlengthという名前のパラメーターを使用できます。

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

1

data.currentTarget.value.lengthを使用して、渡されるデータの長さを取得できます。以下を参照してください。

$('[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);
            }
        });

そして明らかに、テキストを削除するときにこのコードを実行したいので、値を0に設定します


0

これは、DataTablesバージョン1.10.19で機能します。ウェブサイトのテンプレートにjsを含めるだけで済みます。これは、異なるページに複数のdataTableが設定されているサイトに役立ちます。xhrの読み込みが遅いテーブルにも役立ち、現在実行中のすべてが終了するまで新しいxhrリクエストを許可しません。使用される検索機能は、プラグインが最初に検索機能を設定する方法と非常によく似ています。

(function(window, document, $){
var xhring = 0;

$(document).on( 'preXhr.dt', function () {
    xhring++;
} );
$(document).on( 'xhr.dt', function () {
    xhring--;
} );

//at a minimum wait the full freq, and wait for any pending XHR requests to finish before calling fn
function choke( fn, freq ) {
    var
        frequency = freq !== undefined ? freq : 200,
        last,
        timerFn,
        timer;

    return function () {
        var
            that = this,
            args = arguments;

        timerFn = function () {
            if (xhring || +new Date() < last + frequency) {
                clearTimeout( timer );
                timer = setTimeout( timerFn, frequency);
            } else {
                fn.apply( that, args );
            }
        }
        last = +new Date();

        clearTimeout( timer );
        timer = setTimeout( timerFn, frequency );
    };
}

//See https://github.com/DataTables/DataTables/blob/156faa83386460c578e00c460eca9766e38a0c5f/media/js/jquery.dataTables.js
//See https://github.com/DataTables/Plugins/blob/master/features/searchHighlight/dataTables.searchHighlight.js
$(document).on( 'preInit.dt', function (e, settings, json) {
    var previousSearch = settings.oPreviousSearch;

    var searchFn = function() {
        /* Update all other filter input elements for the new display */
        var val = !this.value ? "" : this.value; // mental IE8 fix :-(

        /* Now do the filter */                                                                                                  
        if ( val != previousSearch.sSearch && (val.length >= 3 || val == "")) {
            $.fn.dataTable.ext.internal._fnFilterComplete( settings, {
                "sSearch": val,
                "bRegex": previousSearch.bRegex,
                "bSmart": previousSearch.bSmart ,
                "bCaseInsensitive": previousSearch.bCaseInsensitive
            } );

            // Need to redraw, without resorting
            settings._iDisplayStart = 0;
            $.fn.dataTable.ext.internal._fnDraw( settings );
        }
    };

    var searchDelay = settings.searchDelay !== null ?                                                                            
        settings.searchDelay :
        $.fn.dataTable.ext.internal._fnDataSource( settings ) === 'ssp' ?
            700 :
            200;

    var jqFilter = $( 'input', settings.aanFeatures.f )
        .off('keyup.DT search.DT input.DT paste.DT cut.DT')
        .on('keyup.DT search.DT input.DT paste.DT cut.DT', choke(searchFn, searchDelay))
        ;
} );

})(window, document, jQuery);

-1

「変更」で長さをチェックしない理由はありますか?

$('.input').change(function() {
  if( $('.input').length > 3 ) {
     //do the search
  }
});

2
DataTablesはすでにこれにバインドされており、自動的に検索を呼び出すためです。バインディングをインターセプト/変更する必要があります。
random_user_name 2014年

-1

jquery.datatables.jsを変更する必要があります

-----もちろん更新され、長さ> 3をチェックできますが、それでもタイマーが必要だと思います。大量のデータがある場合は、文字を更新するたびにデータをフィルタリングし続けたくありません。

このメソッド内:

jqFilter.keyup( function(e) {
            if ( **this.value**.length > 3) {
                var n = oSettings.aanFeatures.f;
                for ( var i=0, iLen=n.length ; i<iLen ; i++ )
                {
                    if ( n[i] != this.parentNode )
                    {
                        $('input', n[i]).val( this.value );
                    }
                }
                /* Now do the filter */
                _fnFilterComplete( oSettings, { 
                    "sSearch": this.value, 
                    "bRegex":  oSettings.oPreviousSearch.bRegex,
                    "bSmart":  oSettings.oPreviousSearch.bSmart 
                } );
         }
        } );

回答の1つに示されているように、キーアップにタイマーを追加します。

次に、このサイトhttp://jscompress.com/にアクセスします。

そして、変更したコードを過ぎると、jsは縮小されます。


こんにちは、ありがとう-しかし、タイマーの代わりに$( '。input')。length> 3または$(#input ')。length> 3チェックを追加できますか?ただし、検索フィールドを参照する方法がわかりません。
アレクサンダーファーバー2011

もちろん、長さが3を超える場合はチェックできますが、それでもタイマーが必要だと思います。大量のデータがある場合は、文字を更新するたびにデータをフィルタリングし続けたくありません。3文字を超える長さを正しくチェックして回答を更新しました。タイマーを追加することは、次の貴重なステップです。
Tahir Malik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.