programing

jQuery 데이터 테이블:3자를 입력하거나 버튼을 클릭할 때까지 검색 지연

yellowcard 2023. 8. 23. 21:44
반응형

jQuery 데이터 테이블:3자를 입력하거나 버튼을 클릭할 때까지 검색 지연

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

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

참고: 훨씬 이전 버전의 데이터 테이블에 대한 것입니다. jQuery 데이터 테이블 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 사람들이 키 누름과 키업 모두에 구속되는지는 모르겠지만, 저는 키업이 충분하다고 생각하지만 호환성을 유지하기 위해 두 가지 모두를 무시하고 있습니다.

이것이 도움이 되길 바랍니다!

스토니의 답변의 이 확장 버전을 사용해 보는 것은 어떻습니까 :)

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

});

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

도움이 되길 바랍니다.

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

내 데이터 표 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);

    });

이 작업은 DataTable 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();
        }
    });

제이에스아이들

사용자가 검색 상자에 미니넘 문자를 입력한 후 서버 호출을 호출하려면 Allan의 제안을 따릅니다.

필터를 설정하기 전에 문자열 길이에 추가 조건을 추가하도록 fnSetFilteringDelay() 플러그인 API 함수를 사용자 지정합니다. 필터를 지우기 위한 빈 문자열 입력도 고려합니다.

따라서 최소 3자의 경우 플러그인의 #19행을 다음과 같이 변경합니다.

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

여기 데이터 테이블을 확장하는 플러그인과 같은 스크립트가 있습니다.

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

이전의 어떤 해결책도 나에게 효과가 없었기 때문에 나는 데바운스를 추가하는 이 수정된 버전을 만들었습니다.모든 최신 버전에서 완벽하게 작동합니다.

최소 문자 제한 및 시간 초과 값을 변경하거나 제거할 수 있습니다.

jQuery(document).on( 'init.dt', function (e, settings) {
  var dti = jQuery('.dataTables_filter input');
  var api = new jQuery.fn.dataTable.Api( settings );
  var dbn = null;

  dti.off().on('input', function(e) {
    clearTimeout( dbn );
    var str = this.value;
    dbn = setTimeout(function(){
      if(str.length > 2 || e.keyCode == 13) api.search( str ).draw();
      if(str == '') api.search( '' ).draw();
    }, 300);
    return;
  });
});

사용

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

비록 그것이 원래 질문에 답하지는 않지만, 저는 제 데이터 테이블에서 복잡하고 느린 검색을 했습니다.필터 이벤트는 각 키 누름 후에 시작되었습니다. 이는 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;
}

이를 통해 서버에 대한 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 미만이면 아약스 호출을 중지합니다. 그런 방식으로 단어를 쓸 때는 하나의 아약스 호출만 실행되고 입력을 중지할 때만 실행됩니다.지연 파라미터(300)로 '재생'하여 지연을 다소 줄일 수 있습니다.

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

    } );
} );

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

그리고 그것을 X자로 만드는 대신에, 1초 정도 동안 타자를 멈추면 검색이 시작되도록 지연을 사용합니다.

그래서 현재 검색을 트리거하고 있는 키다운/키업 바인딩은 타이머로 수정됩니다.

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

전달되는 데이터의 길이는 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으로 설정합니다.

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

이전 버전을 사용하는 경우에는 이전 버전처럼 보입니다.리차드의 해결책은 잘 작동합니다.하지만 사용할 때는 삭제하지 않고 새로운 이벤트만 추가했습니다.코드가 실행되면 테이블이 아직 생성되지 않기 때문입니다.그래서 fnInitComplete 메서드(테이블 생성 시 fire)가 있다는 것을 발견하고 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());
                    });
                }

onKeyUp 이벤트 핸들러에 연결된 입력 문자열의 길이를 테스트하고 최소 길이에 도달하면 검색 기능을 트리거하는 기능을 직접 작성할 수 있습니까?

다음과 같은 것:

input.onKeyUp(function() {if(input.length > 3) {mySearch 기능();}});

...즉, 유사 코드 같은 방식으로, 그러나 당신은 지스트를 얻습니다.

minlength라는 이름으로 매개 변수를 사용하여 검색을 3자까지 제한할 수 있습니다.

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

여기서 대부분의 답변은 어떤 식으로든 기존 DataTable 이벤트 바인딩을 조작하지만 개인적으로 이 작업을 수행하기 위해 너무 오랜 시간을 소비한 후에 제가 발견한 최상의 접근 방식은 결국 더미 값을 전송하는 것이었습니다.search매개 변수입니다.

// ... denotes expected code for DataTable to function excluded for clarity.
$("#example").dataTable({
  ...
  'ajax': {
    ...
    'data': function (d) {
       d.search.value = d.search.value.length >= 3 ? d.search.value : "##EmptySearch##";
       return JSON.stringify(d);
    }
  }
});

##EmptySearch##문자열은 반환된 데이터와 일치하지 않아야 하는 값으로 작용합니다(사용할 항목은 전적으로 개인적인 선호 사항이지만 데이터와 일치하지 않도록 보장되는 문자열이어야 함).바인딩이 조작되지 않았기 때문에 일반적인 벨과 호루라기는 여전히 작동하지만 검색이 3자 이상이 될 때까지 의미 있는 것은 반환되지 않습니다.분명히 그것은 이상적이지 않습니다. 서버 요청을 전혀 하지 않는 것을 선호합니다. 하지만 제 생각에는 이것이 데이터 테이블 검색의 기존 기능을 손상시키지 않는 가장 간단한 접근 방식입니다.

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는 축소될 것입니다.

이 코드를 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;
            }
        },

첫 번째 쇼에 대해 Input.length() == 0을 검색합니다.

이 기능은 DataTables 버전 1.10.19에서 작동합니다.웹 사이트 템플릿에 js를 포함하면 됩니다. 여러 개의 데이터 테이블이 서로 다른 페이지에 구성된 사이트에 유용합니다.느린 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);

'변경'에 길이만 확인하지 않으려는 이유가 있습니까?

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

언급URL : https://stackoverflow.com/questions/5548893/jquery-datatables-delay-search-until-3-characters-been-typed-or-a-button-clicke

반응형