jQuery DataTables : 3 개의 문자를 입력하거나 버튼을 클릭 할 때까지 검색 지연


82

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

답변:


75

버전 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에서는 먼저 검색 문자열을 설정 한 다음 $ ( ". datatable"). dataTable (). api (). search ( "aaaa2"); $ ( "와 같이 fnDraw ()를 실행해야합니다. ..) "데이터 테이블 데이터 테이블 () fnDraw ()
헤샴 야신

2
keydown 기능 대신 입력이 있었는데 이제 잘 작동합니다. 감사합니다
azza idz 2015-10-22

1
@Maxime 나는 작동하고 잘못된 변수 이름 불일치를 만들지 않은 편집으로 롤백했습니다. 여전히 수정 /주의가 필요하다고 생각되면 알려주세요.
random_user_name

1
@cale_b 1.10.16에서 여전히 작동하는지 확인할 수 있습니다. 감사합니다.
AnotherDeveloper

77

참고 : 이것은 훨씬 이전 버전의 데이터 테이블 용이었습니다. jQuery datatables v1.10 이상에 대한 답변 을 참조하십시오 .


이것은 리턴을 눌렀거나 검색에 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 모두에 바인딩하면 쿼리가 두 번 실행됩니다. 집에서 시청하는 분들은 언 바인드와 바인드에서 둘 중 하나만 꺼내면됩니다.
Thunder Rabbit

1
이 솔루션은 백 스페이스를 누를 때 작동하지 않습니다. @Sam Barnes가 최고의 답변입니다
Idrees Khan

2
Sam Barnes의 훌륭한 답변에 대한 대안으로, 필드를 벗어 났을 때도 실행되는 으로 대체 e.keycode != 13하여 백 스페이스 (및 필드 지우기)를 고려하여이를 수정할 수 있습니다 e.keyCode > 13.
cincodenada 2013 년

2
불행히도 이것은 버전 1.10에서 작동 하지 않습니다
random_user_name 2014 년

@ThunderRabbit의 말에 따라 내가 찾은 가장 좋은 방법은 둘 다 바인딩을 해제하는 것이지만 둘 중 하나만 다시 바인딩하는 것입니다. .unbind('keypress keyup') .bind('keypress', function(e) ...
nageeb

33

이 확장 버전의 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);

});

사용자가 입력을 중지 할 때까지 검색이 지연됩니다.

도움이되기를 바랍니다.


잘 작동합니다. 하지만 데이터 테이블 인스턴스를 참조하려면 oTable.fnFilter (...)를 변경해야합니다.
YudhiWidyatama 2013

이것은 실제로 확장 된 버전이 아니며 완전히 다른 (하지만 유용한) 솔루션입니다. 그러나 setTimeout(function(){...}, 600)함수가 추가 문자에서 다시 실행되지 않는 것처럼 보이기 때문에에서 수행 할 수없는 searchWait 매개 변수가 수행하는 작업에 대해 혼란 스럽습니다 .
cincodenada

@cincodenada 여야합니다. setInterval200 / 600ms마다 다시 실행되고 searchWait가 0으로 재설정되지 않았는지 확인하기 때문입니다. 예를 들어 입력에 계속 입력하면 항상 searchWait를 0으로 재설정하면 검색이 실행되지 않습니다. 그러나 나는 searchWait을 정수로 사용하는 것을 발견했습니다. 사용자 입력이 발생하고 경우에 더 나은 그냥 참 / 거짓 플래그 것 setInterval(600)
r3mark

3
jqueryDatatables 1.10.3부터 다음과 같은 옵션이 있습니다. searchDelay
panmari

1
@panmari-searchDelay는 지정된 시간 동안 검색을 지연시키고 사용자가 대부분의 예상대로 입력을 중지 할 때가 아니라 나중에 테이블을 다시 그립니다 (트리거 ajax).
크리스 Landeza

11

버전 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

내 버전의 datatables 1.10.10

나는 약간의 것을 바꾸었고 지금은 작동합니다. 그래서 나는 공유하고 있는데, 버전 1.10.10에서 작동하도록 만드는 것이 어려웠 기 때문입니다. cale_b, Stony 및 Sam Barnes에게 감사드립니다. 내가 한 일을 보려면 코드를보십시오.

    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 개 이상이면 당신은 "하지 마십시오 또는 입력 키를 누르면?if ( anControl.val().length > 2 || e.keyCode == 13)
제로미 프랑스어에게

네, 그것도 작동합니다. 빈 문자열이 전달되고 Enter 키를 눌러도 아무 일도 일어나지 않도록 유효성 검사 측면에 더 중점을 둡니다.
Christian Noel

6

사용자가 검색 상자에 최소 문자를 입력 한 후 서버 호출을 호출하면 Allan의 제안을 따를 수 있습니다 .

fnSetFilteringDelay () 플러그인 API 함수 를 사용자 정의하여 필터를 설정하기 전에 문자열 길이에 대한 추가 조건을 추가하고 필터를 지우려면 빈 문자열 입력도 고려하십시오.

따라서 최소 3 자의 경우 플러그인의 19 번 줄을 다음과 같이 변경 하십시오 .

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

5

이것은 DataTables 1.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 좋아요. 이것은 데이터 테이블 정의에 잘 통합됩니다. 내 경우에는 전체 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);
        });

이 코드는 키 누르기 사이의 시간이 300ms 미만이면 ajax 호출을 중지합니다. 이렇게하면 단어를 쓸 때 하나의 ajax 호출 만 실행되고 입력을 중지 할 때만 실행됩니다. 더 많거나 적은 지연을 얻기 위해 지연 매개 변수 (300)로 '재생'할 수 있습니다.


2

플러그인을 수정해야 할 것입니다.

X 문자로 만드는 대신 지연을 사용하여 1 초 정도 입력을 중지하면 검색이 시작됩니다.

따라서 현재 검색을 트리거하는 keydown / keyup 바인딩은 타이머로 수정됩니다.

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

1
"플러그인 수정"이란 jquery.dataTables.js 편집을 의미합니까? 그리고 나중에 "최소화"하는 방법을 알고 있습니까?
Alexander Farber 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

이전 버전을 사용하고 있다면 그럴 것 같습니다. Richard의 솔루션은 잘 작동합니다. 하지만 사용할 때 삭제가 아닌 새 이벤트를 추가했습니다. 코드가 실행될 때 테이블이 아직 생성되지 않았기 때문입니다. 그래서 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 
                } );
         }
        } );

답변 중 하나에 표시된 것처럼 키업에 타이머를 추가합니다.

그런 다음이 사이트 http://jscompress.com/으로 이동합니다.

그리고 수정 된 코드를 지나면 js가 축소됩니다.


안녕하세요, 감사합니다.하지만 타이머 대신 $ ( '. input'). length> 3 또는 $ (# input '). length> 3 확인을 추가 할 수 있습니까? 그래도 검색 필드를 참조하는 방법을 모르겠습니다.
Alexander Farber 2011

물론 길이가 3보다 크면 확인할 수 있지만 여전히 타이머가 필요하다고 생각합니다. 데이터가 많은 경우 모든 캐릭터 업데이트 후 계속 필터링되는 것을 원하지 않습니다. 3 자 이상의 길이에 대한 올바른 확인으로 답변을 업데이트했습니다. 타이머를 추가하는 것이 다음 단계입니다.
Tahir Malik 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.