2011-04-24 75 views
0

我在這裏使用的自動完成:http://blog.idealmind.com.br/geral/simple-autocomplete-jquery-plugin/我autocompelete射擊太多次

它有兩個問題:

1)它不工作的第一次東西進入文本 - 沒有這麼大問題,因爲你真的不想匹配一個字母 2)更令人惱火的是,它發射太多次了。

我的JavaScript是在這裏:

<script type="text/javascript"> 
    function nameAutocomplete(field){ 
    alert($(field).val()); 
$("#name").simpleAutoComplete(
     'Ajax.action', 
     { 'input': $(field).val(), 
      '_eventName': 'getObjectsByAjax' 
     }, 
     function(data){ 
     alert("we're in business"); 
     } 
    ); 
} 
</script> 

的HTML看起來像這樣:

<input type="text" name="name" id="name" size="45" class="medium-text" onkeyup="nameAutocomplete(this);"/> 

這就是插件(下圖),使Ajax調用(這是工作的罰款)的一部分:

  $.get(page, 
       { 'input': thisElement.val(), 
        '_eventName': 'getObjectsByAjax' 
       }, 
        function(res) 
       { 
       $('div.' + classAC).remove(); 
       $("#autocomplete_tooltip").remove(); 
       var r=""; 
       var respObject=eval(res); 
       r+="<ul>"; 
       for(var i in respObject) 
        { 
         r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>"; 
        } 
       r+="</ul>"; 
       autoCompleteList = $('<div>').addClass(classAC).html(r); 

我在這裏打印的整個插件代碼:

(function($){ 
$.fn.extend(
{ 
    simpleAutoComplete: function(page, options, callback) { 
     if(typeof(page) == "undefined") { 
      alert("simpleAutoComplete: Você deve especificar a página que processará a consulta."); 
     } 

     var classAC = 'autocomplete'; 
     var selClass = 'sel'; 
     var attrCB = 'rel'; 
     var thisElement = $(this); 

     $(":not(div." + classAC + ")").click(function(){ 
      $("div." + classAC).remove(); 
      $("#autocomplete_tooltip").remove(); 
     }); 

     thisElement.attr("autocomplete","off"); 

     thisElement.keyup(function(ev) 
     { var getOptions = { input: thisElement.val() } 

      if(typeof(options) == "object") 
      { 
       classAC = typeof(options.autoCompleteClassName) != "undefined" ? options.autoCompleteClassName : classAC; 
       selClass = typeof(options.selectedClassName) != "undefined" ? options.selectedClassName : selClass; 

       attrCB = typeof(options.attrCallBack) != "undefined" ? options.attrCallBack : attrCB; 
       if(typeof(options.identifier) == "string") 
       getOptions.identifier = options.identifier; 

       if(typeof(options.extraParamFromInput) != "undefined") 
       getOptions.extraParam = $(options.extraParamFromInput).val(); 
      } 

      kc = ((typeof(ev.charCode) == 'undefined' || ev.charCode === 0) ? ev.keyCode : ev.charCode); 
      key = String.fromCharCode(kc); 

      console.log(kc, key, ev); 

      if (kc == 27) 
      { 
       $('div.' + classAC).remove(); 
       $("#autocomplete_tooltip").remove(); 
      } 
      if (kc == 13) 
      { 
       $('div.' + classAC + ' li.' + selClass).find(".caption").trigger('click'); 
      } 
      if (key.match(/[a-zA-Z0-9_\- ]/) || kc == 8 || kc == 46) 
      { 
       $.get(page, 
        { 'input': thisElement.val(), 
         '_eventName': 'getObjectsByAjax' 
        }, 
         function(res) 
        { 
        $('div.' + classAC).remove(); 
        $("#autocomplete_tooltip").remove(); 
        var r=""; 
        var respObject=eval(res); 
        r+="<ul>"; 
        for(var i in respObject) 
         { 
          r+='<li id="autocomplete_'+respObject[i].id+'"><table cellspacing=0 width="100%"><tr><td class="icon" width="20" uri="'+respObject[i].uri+'"><a href="/sempedia/Resource.action?id='+respObject[i].id+'" ><img src="images/green-file.png"></a></td><td class="caption">'+respObject[i].name+"</td></tr></table></li>"; 
         } 
        r+="</ul>"; 
        autoCompleteList = $('<div>').addClass(classAC).html(r); 
        if (r != '') 
        { 
         autoCompleteList.insertAfter(thisElement); 

         var position = thisElement.position(); 
         var height = thisElement.height(); 
         var width = thisElement.width(); 

         $('div.' + classAC).css({ 
          'top': (height + position.top + 6) + 'px', 
          'left': (position.left)+'px', 
          'margin': '0px' 
         }); 

         $('div.' + classAC + ' ul').css({ 
          'margin-left': '0px' 
         }); 

         $('div.' + classAC + ' li').each(function(n, el) 
         { 
          el = $(el); 
          el.mouseenter(function(){ 
           $('div.' + classAC + ' li.' + selClass).removeClass(selClass); 
           $(this).addClass(selClass); 
          }); 
          el.find(".caption").click(function() 
          { 
           thisElement.attr('value', el.text()); 

           if(typeof(callback) == "function") 
            callback(el.attr(attrCB).split('_')); 

           $('div.' + classAC).remove(); 
           thisElement.focus(); 
          }); 

          el.hover(function(e) { 
           urlText=$("<div>").attr("id","autocomplete_tooltip").addClass("tooltip").html($(this).find("td").attr("uri")); 

           urlText.css({ 
            position:"absolute", 
            top:(e.pageY+20)+"px", 
            left:(e.pageX+20)+"px" 
            }); 

           $("body").append(urlText); 
          },function() { 
           $("#autocomplete_tooltip").remove(); 
          }); 


         }); 
        } 
       }); 
      } 
      if (kc == 38 || kc == 40){ 
       if ($('div.' + classAC + ' li.' + selClass).length == 0) 
       { 
        if (kc == 38) 
        { 
         $($('div.' + classAC + ' li')[$('div.' + classAC + ' li').length - 1]).addClass(selClass); 
        } else { 
         $($('div.' + classAC + ' li')[0]).addClass(selClass); 
        } 
       } 
       else 
       { 
        sel = false; 
        $('div.' + classAC + ' li').each(function(n, el) 
        { 
         el = $(el); 
         if (!sel && el.hasClass(selClass)) 
         { 
         el.removeClass(selClass); 
         $($('div.' + classAC + ' li')[(kc == 38 ? (n - 1) : (n + 1))]).addClass(selClass); 
         sel = true; 
         } 
        }); 
       } 
      } 
      if (thisElement.val() == '') { 
       $('div.' + classAC).remove(); 
       $("#autocomplete_tooltip").remove(); 
      } 
     }); 
    } 
}); 
    })(jQuery); 
+0

你是什麼意思'太多次'?爲了防止這是您的回覆,每個緩慢輸入的字符(第一個除外)都是自動完成的標準。 – sscirrus 2011-04-24 08:54:18

+0

對不起,「太多次了」。在進一步檢查時,它似乎將其稱爲在會話期間(自上次頁面重新加載以來)添加到文本框的字母總數的多少倍。因此,如果我在添加「w」字符時輸入「erw」,它將執行6個自動完成,一個用於e,然後兩個用於e和r,然後3個用於e,er和erw。 – Ankur 2011-04-24 12:39:36

回答

2

拉,做Ajax調用到的函數部分,然後"debounce"這樣說:

var timeout = thisElement.data('timeout'); 

function debouncedAjax() { 
    if (timeout) { 
    clearTimeout(timeout); 
    } 
    timeout = setTimeout(ajax, 500); 
    thisElement.data('timeout', timeout); 
} 

這樣,你就可以調用debouncedAjax到處現在稱之爲ajax,它會只有在500ms的平靜之後才能打一個電話。調整超時的味道。

0

我結束了使用全局變量來存儲的setTimeout()每一個KEYUP發生了,你清楚這個變量,並與新的Ajax調用重置它,像這一次喊出了Ajax的功能和:

$(document).ready(function() { 
    // Define the global variable 
    $.go = null; 
    // Element keyup 
    $("#YourElementId").keyup(function() { 
     // Clear the global variable with the previous Ajax 
     clearTimeout($.go); 
     // Set the variable with the current Ajax call 
     $.go = setTimeout(function() { 
      FunctionThatCallsTheAjax(); 
     },1000); 
    }); 
}); 
function FunctionThatCallsTheAjax(){ 
    // Ajax Stuff Here 
} 

您可以調整'1000'超時。 它對我很好。