2016-07-04 61 views
2

我是AngularJS和Bootstrap中的一名新成员,希望得到一些帮助。在输入文字中写入时保持关注下拉列表

我想创建一个动态的下拉列表,它通过输入文本进行过滤。 这里是我的代码:

<input id="SelectedCountry" type="text" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-expanded="true" ng-model="Pass" autocomplete="off" /> 
<ul class="dropdown-menu"> 
    <li data-ng-repeat="r in countrycodes | MyFilter *my filter in the app.filter. works fine*"><a href="#" data-ng-click="selectedcountry.value=r.value">{{r.name}}</a></li> 
</ul> 

我想那每次的向下arrowkey重点用户点击将在下拉列表(?它不会自动发生,为什么),所以我写了这个代码:

$(document).on('shown.bs.dropdown', function (event) { 
    var dropdown = $(event.target); 
    $("input").keydown(function (e) { 
     if ((e.which && e.which == 40) || (e.keyCode && e.keyCode == 40)) { 
      // Set aria-expanded to true 
      dropdown.find('.dropdown-menu').attr('aria-expanded', true); 

      // Set focus on the first link in the dropdown 
      dropdown.find('.dropdown-menu li:first-child a').focus(); 

      return false; 
     } else { 
      return true; 
     } 
    }); 
}); 

我的问题是,当用户按向下的箭头键焦点不再输入文本,所以他不能继续写。

我该如何制作一个动态下拉列表,用户可以在焦点位于菜单上的同时继续书写? 我已经尝试过使用jquery过滤器,但它没有奏效,因为我必须使用AngularJs,因此我可以在用户选择他的选项时触发data-ng-click,此外,我还可以使用数据ng -repeat,所以我不能在html中使用默认的“选择”和“选项”标签。 无处不在,我搜索的解决方案说,不能对同一时间聚焦的元素。也许还有另一种选择?因为这种情况下有很多网站?

谢谢你的帮助

回答

0

是的,你说得对。它不能同时聚焦2个元素。

0

它不会自动关注下拉列表,因为它不应该是。当用户在普通的输入字段中按下或关闭(没有事件监听器和特殊的东西)时,根据被按下的内容,光标应该只移动到最左边或最右边。

此外,您无法同时关注它们。只有一个元素可以聚焦。你可以做的是保持一个变量,说明哪个下拉列表元素“聚焦”,并为用户按下回车键来设置事件监听器,该脚本将执行与该列表元素相关的所有内容。按下向上或向下时,该变量将会改变。另外,如果按下向上/向下,应该使用event.preventDefault()来停止光标向左/向右移动。希望这可以帮助。

UPDATE

还有一件事。为了模拟点击所需的下拉列表项目,您可以使用jQuery's trigger function

更新2

我做了一个示例代码,因为我不知道怎么回事,以显示我的意思。另外,我还没有使用jQuery - 一切都是香草JS。因此我也没有使用触发器功能。随意玩它或判断它(这就是我所做的):

<html> 
    <head> 
     <style> 
      #content { 
       width: 500px; 
       margin-top: 30px; 
       margin: 0 auto; 
      } 

      #search-list { 

      } 

      #search-list li { 
       display: block; 
       width: 200px; 
       height: 40px; 
       line-height: 40px; 
       padding: 5px; 
       border: 1px solid #666; 
      } 


      #search-list li.focused { 
       background: #aaa; 
      } 
     </style> 
    </head> 
    <body> 
     <div id="content"> 
      <input id="search-input" type="text" value="" placeholder="Type text here" /> 
      <ul id="search-list"> 
       <li>Meow</li> 
       <li>Roar</li> 
       <li>Mewore</li> 
       <li>Foo</li> 
       <li>Bar</li> 
       <li>Bartender</li> 
      </ul> 
      <div id="log"> 
      </div> 
     </div> 

     <script type="text/javascript"> 
      var items = document.getElementById('search-list').getElementsByTagName('li'); 

      document.getElementById('search-input').addEventListener("keydown", keyDownHandler); 

      for(var i=0; i<items.length; i++) { 
       items[i].addEventListener("mouseover", mouseOverHandler); 
       items[i].addEventListener("mouseout", mouseOutHandler); 
       items[i].addEventListener("click", clickHandler); 
      } 

      function getElementIndex(elem) { 
       var children = event.target.parentNode.childNodes; 
       var idx=-1; 
       for(var i=0; i<children.length; i++) { 
        if(children[i].nodeType == 1) { 
         idx++; 
         if(children[i] == elem) return idx; 
        } 
       } 
      } 

      function mouseOverHandler(event) { 
       var idx = getElementIndex(event.target); 

       if(currentItem != -1) items[currentItem].className = ""; 

       event.target.className = "focused"; 
       currentItem = idx; 
      } 

      function mouseOutHandler(event) { 
       var idx = getElementIndex(event.target); 
       event.target.className = ""; 
       if(currentItem == idx) { 
        currentItem = -1; 
       } 
      } 

      function clickHandler(event) { 
       document.getElementById('log').innerHTML += '<p>' + event.target.innerText + '</p>'; 
      } 

      var currentItem = -1; 

      function keyDownHandler(event) { 
       var keyPressed = event.which || event.keyCode; 
       if(keyPressed == 38) { 
        //up 
        event.preventDefault(); 
        if(currentItem >= 0) { 
         items[currentItem].className = ""; 
        } 
        currentItem = (currentItem == -1) ? (items.length-1) : (currentItem-1); 
        if(currentItem >= 0) { 
         items[currentItem].className = "focused"; 
        } 
       } else if(keyPressed == 40) { 
        //down 
        event.preventDefault(); 
        if(currentItem >= 0) { 
         items[currentItem].className = ""; 
        } 
        currentItem = (currentItem == items.length - 1) ? -1 : (currentItem+1); 
        if(currentItem >= 0) { 
         items[currentItem].className = "focused"; 
        } 
       } else if(keyPressed == 13) { 
        //enter 
        if(currentItem == -1) document.getElementById('log').innerHTML += '<p>' + event.target.value + '</p>'; 
        else document.getElementById('log').innerHTML += '<p>' + items[currentItem].innerText + '</p>'; 
       } 
      } 
     </script> 
    </body> 
</html> 
+0

首先,谢谢你的答案。第二,你说“你可以做的是保持一个变量,说哪个下拉列表元素是”重点“”。 我怎么知道当时下拉列表元素的重点? 我尝试了几件事,没有成功。 –

+0

另一件事,如果下拉列表和输入字段不能同时关注,那么如何有很多动态搜索框(最简单的例子是Google搜索框或Facebook),您可以在不断输入内容的同时关注选项输入文字? –

+0

感谢您的提问。我会更新我的答案。 –