2016-07-21 68 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

嗨,所以我正在检查,看看这是否会起作用,然而,只要选择了某种东西,它就会出现一些故障并立即取消选择。你碰巧知道为什么会发生这种情况?干杯 –

相关问题