2016-07-21 104 views
2

我有一個非常基本的自動建議功能,我的網站每當用戶在我的搜索輸入中輸入內容時都會運行。自動建議下拉不選擇使用箭頭向上/向下鍵

它應該像谷歌搜索自動建議一樣的功能 - 它有點類似。但是,當返回一些建議時,如果用戶點擊其鍵盤上的某個箭頭,則不會選擇任何建議。

這裏是我的JS(對於建議的選擇):

$(document).ready(function(){ 
    var $result = $('li'); 

    $('input').keydown(function(e){ 
     var key = e.keyCode, $selected = $result.filter('.selected'), $current; 
     if(key != 40 && key != 38){ 
      return; 
     } 
     $result.removeClass('selected'); 
     if (key == 40){ 
      if (!$selected.length || $selected.is(':last-child')){ 
       $current = $result.eq(0); 
      } else { 
       $current = $selected.next(); 
      } 
     } else if (key == 38){ 
      if (!$selected.length || $selected.is(':first-child')){ 
       $current = $result.last(); 
      } else { 
       $current = $selected.prev(); 
      } 
     } 

     $current.addClass('selected'); 
    }); 
}); 

這裏是我的Ajax:

function findmatch(){ 
    if(window.XMLHttpRequest){ 
     xmlhttp = new XMLHttpRequest(); 
    } else { 
     xmlhttp = new ActiveXObject('Microsoft.XMLHTTP'); 
    } 

    xmlhttp.onreadystatechange = function(){ 
     if(xmlhttp.readyState == 4 && xmlhttp.status == 200){ 
      document.getElementById('s-dif').innerHTML = xmlhttp.responseText; 
     } 
    } 

    var qVal = document.getElementById('query-value'); 

    xmlhttp.open('GET', 'search/suggest.php?q=' + qVal.value, true); 
    xmlhttp.send(); 
} 

非常基本的HTML:

<div class="form-container"> 
    <form method="get" id="search" name="search"> 
     <input type="text" name="q" id="query-value" onkeyup="findmatch();" placeholder="Search with Ajax..."> 
    </form> 
</div> 
<div class="suggestions"> 
    <ul id="s-dif"> 
    </ul> 
</div> 

,最後,我的PHP:

if(isset($_GET['q'])){ 
    $results = ''; 

    $query = trim($_GET['q']); 
    if(!empty($query)){ 
     $stmt = $conn->prepare("SELECT title, popularity FROM autosuggest WHERE keywords LIKE :query OR title LIKE :query ORDER BY popularity desc LIMIT 7"); 
     $query = $query . '%'; 
     $stmt->bindParam(':query', $query); 
     $stmt->execute(); 

     $count = $stmt->rowCount(); 
     $i = 0; 
     if($count > 0){ 
      while($row = $stmt->fetch(PDO::FETCH_OBJ)){ 
       $title = $row->title; 
       $popularity = $row->popularity; 

       $i++; 

       $results .= '<li id="select-suggest" value="' . $i . '" name="' . $title . '">' . $title . '</li>'; 
      } 
     } 
    } 
} 

print("$results"); 

我覺得好像問題在於我「的選擇jQuery的」內,但是,我已經確定要三重檢查一切,但我似乎無法找到任何會阻止該功能工作的東西。

+0

我要笑,你是當你已經在使用jQuery使用自己的AJAX。 – PHPglue

+0

@PHPglue這是我第一次使用Ajax ..我使用從我發現的網站的修改版本,因爲我還在學習... –

+0

爲什麼不使用自動完成的texbox? –

回答

1

我不確定谷歌是如何工作的,但我相信你會嘗試做下面的腳本。您應該可以將其應用於返回的下拉菜單。它檢查光標是否集中在輸入字段中。如果是,則激活下面的鍵代碼腳本:

的jsfiddle:https://jsfiddle.net/2wvs0tmd/

的JavaScript:

// I am going to use an object, just for reuse 
/* 
** @param jQuery [object] Pass the jQuery object 
** @param getMenu [object] jQuery DOM object (ul) that contains our menu 
** @parm getKeyTap [int] This is the e.keyCode passed from the event 
*/ 
var keyAction = function(jQuery,getMenu,getKeyTap) 
    { 
     // The variable is what is currently be acted on 
     var isSelected; 
     // This will designate first or last child 
     var getChild; 
     // This will be assigned the next, previous, or current child 
     var thisChild; 
     // We assign jQuery here 
     var $   = jQuery; 
     // These are all the keys we allow to be struck 
     var allowKeys = [38,40,13]; 
     // This is not used in this example, but can reset the keyCode 
     var keyCode  = false; 
     /* 
     ** @returns [boolean] This function returns if the key being pressed is arrow up/down 
     */ 
     var upDown  = function(getKeyTap) 
      { 
       return (getKeyTap == 38 || getKeyTap == 40); 
      } 
     /* 
     ** @returns [boolean] This method returns boolean true/false if up/down arrow pressed 
     */ 
     this.keyAllowed = function() 
      { 
       return upDown(getKeyTap); 
      } 
     /* 
     ** @description This method sees if pressed key is up/down arrow or return key 
     ** @returns [boolean] Will return true/false 
     */ 
     this.isAllowed = function() 
      { 
       return (allowKeys.indexOf(getKeyTap) != -1); 
      } 
     // This will manually set the keyCode (not required in this example) 
     this.setKey = function(keyCode) 
      { 
       getKeyTap = keyCode; 
       return this; 
      } 
     /* 
     ** @returns [object] This returns the current state of the DOM 
     */ 
     this.isSelected = function() 
      { 
       return isSelected; 
      } 
     /* 
     ** @description This will run an anonymous function passing the current DOM 
     ** @param thisChild [ANY] I pass the current DOM selection but, you 
     **      can pass whatever you want 
     ** @param func [function] This is what you want to run when the 
     **      return key is pressed 
     */ 
     this.setReturn = function(thisChild,func) 
      { 
       if(getKeyTap == 13) { 
        if(thisChild) 
         func(thisChild); 
       } 
      } 
     /* 
     ** @description This will set the current DOM and add the select class 
     ** @returns This will return the current DOM object 
     */ 
     this.firstClick = function() 
      { 
       getChild = (getKeyTap == 38)? 'last' : 'first'; 
       isSelected = getMenu.children('li:'+getChild+'-child'); 
       isSelected.addClass('selected'); 
       return isSelected; 
      } 
     /* 
     ** @description This method will move the selection up and down 
     ** @param isSelected [object] This is the current select DOM object 
     ** @returns [object] this will return the current selected DOM object 
     */ 
     this.currClick = function(isSelected) 
      { 
       var setSpot = 'last'; 

       if(getKeyTap == 38) 
        thisChild = isSelected.prev(); 
       else if(getKeyTap == 40) { 
        thisChild = isSelected.next(); 
        setSpot  = 'first'; 
       } 

       if(!thisChild.hasClass('selectable')) 
        thisChild = getMenu.children("li:"+setSpot+"-child"); 

       isSelected.removeClass('selected'); 
       thisChild.addClass('selected'); 
       return thisChild; 
      } 

     /* 
     ** @description This will just run a function 
     */ 
     this.doAction = function(func) 
      { 
       return func(); 
      } 
    } 

// When document is ready 
$(document).ready(function(){ 
    // Set container for this menu 
    var isSelected = false; 
    var qBox  = $('input[name=q]'); 
    // Use the document object to listen for a key press 
    $(this).keydown(function(e) { 
     // See where the cursor is focused 
     var isFocused = (e.target.nodeName == 'INPUT'); 
     // Start engine 
     var sMenu  = new keyAction($, $('ul'), e.keyCode); 
     // If it's focused 
     if(isFocused) { 
      // Place text into field on return   
      sMenu.setReturn(isSelected,function(obj) { 
       qBox.val(isSelected.text()); 
       // Submit form 
       $('#search').submit(); 
      }); 

      // If keys are allowed 
      if(sMenu.keyAllowed()) { 
       isSelected = (!isSelected)? sMenu.firstClick(isSelected) : sMenu.currClick(isSelected); 
       // Copy the value of the selection into the input 
       sMenu.doAction(function(){ 
        qBox.val(isSelected.text()); 
       }); 
      } 
     } 
    }); 
    // On key up in the text field 
    qBox.on('keyup',function(e){ 
     // If the key pressed is up or down arrow 
     if(e.keyCode == 38 || e.keyCode == 40) 
      // Don't do ajax call 
      return false; 
     // Run ajax 
     $.ajax({ 
      url:"search/suggest.php", 
      type:"get", 
      data: $(this).serialize(), 
      success:function(response) { 
       $('#dropdown_search').html(response); 
      } 
     }); 
    }); 
}); 

風格:

.selected { 
    background-color: #888; 
} 

HT ML:表

<div class="form-container"> 
    <form id="search" name="search"> 
     <input type="text" name="q" id="query-value" placeholder="Search with Ajax..."> 
    </form> 
</div> 
<ul id="dropdown_search"> 
</ul> 

HTML:返回從阿賈克斯(例如剛)

<li class="selectable">666554366</li> 
<li class="selectable">1174971318</li> 
<li class="selectable">1809433410</li> 
<li class="selectable">452149182</li> 
<li class="selectable">2024548770</li> 
+0

嗨,謝謝你的回答!不過,我在嘗試調試代碼時遇到了一些麻煩,無法確定一種方法來使其只能在選擇輸入時才能選擇建議。 您是否認爲您可以編輯一些代碼以更好地適合我的代碼?我對JavaScript仍然很陌生 –

+0

現在就試試吧,它應該是你需要的。看演示的小提琴。你必須專注於輸入才能工作。 – Rasclatt

+0

嗨,所以我正在檢查,看看這是否會起作用,然而,只要選擇了某種東西,它就會出現一些故障並立即取消選擇。你碰巧知道爲什麼會發生這種情況?乾杯 –

相關問題