我是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>
我希望每次用户点击向下箭头键时,焦点都会放在下拉列表中(这不会自动发生,为什么?),所以我写了这段代码:
$(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,所以我可以在用户选择他的选项时触发数据-ng-click,另外我得到了数据的选项 - ng-repeat所以我不能使用默认&#34;选择&#34;和&#34;选项&#34; html中的标签。 在我寻找解决方案的任何地方都说不能同时关注的元素。也许有另一种选择?因为这个案子有很多网站?
谢谢你的帮助
答案 0 :(得分:0)
是的,你是对的。它不能同时聚焦2个元素。
答案 1 :(得分:0)
它不会自动关注下拉列表,因为它不应该。当用户在普通输入字段中向上或向下按下时(没有事件监听器和类似的特殊东西),光标应该只移动到最左边或最右边,这取决于按下的内容。
此外,您无法同时关注它们。只有一个元素可以成为焦点。你可以做的是保留一个变量来说明哪个下拉列表元素是“聚焦”的,并且有一个事件监听器供用户按下回车,这将执行它应该关于该列表元素的任何内容。按下向上或向下时,该变量将发生变化。此外,如果按下向上/向下,您应该使用event.preventDefault()来停止光标向左/向右移动。希望这会有所帮助。
<强>更新强>
还有一件事。为了模拟所需下拉列表项的单击,您可以使用jQuery's trigger function。
更新2
我制作了一个示例代码,因为我不知道如何表达我的意思。另外,我还没有使用过jQuery - 一切都是vanilla 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>