2014-12-30 137 views
9

检查这个PLNKR,我已经实现预输入控制, 默认情况下,在提前键入控制他们不设置任何最大高度或高度列出,但根据要求,我必须修复列表的高度为110px。所以,当我们有一个更长的列表时,只有4个数据将被显示,其余可以通过向下滚动来看到。 当用户点击向上/向下滚动箭头时,滚动正在工作,但它不适用于键盘上/下键。上/下箭头键的问题与键盘缓冲控制(角度引导UI)

的问题在步骤解释: -

  1. 类型的东西,即“一”的预输入获得的数据(将被填充的列表)
  2. 按下箭头键(重点将放在列表项)
  3. 按下箭头键4-5的时间去进一步下降(当我们穿越 到列表,滚动中,无法移动。)
  4. 它总是在列表中显示前4项。理想的行为是它应该改变。

用户可以通过手动点击滚动进行滚动,但使用箭头键则不能滚动。

Type "a" and traverse down to list with down-arrow key scrolling is not working.

HTML

<!doctype html> 
<html ng-app="ui.bootstrap.demo"> 
<head> 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script> 
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script> 
<script src="example.js"></script> 
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"> 
<link href="style.css" rel="stylesheet"> 
</head> 
<body> 
<div class='container-fluid' ng-controller="TypeaheadCtrl"> 
    <h4>Static arrays</h4> 
    <pre>Model: {{selected | json}}</pre> 
    <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control"> 
</div> 
</body> 
</html> 

CSS

.dropdown-menu{ 
height:110px; 
overflow:auto; 
} 

JavaScript的数据列表

$scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; 
+0

对我来说它的工作(铬)使用 – maioman

+0

@maioman米铬(版本39.0.2171.95米),它不起作用。 – ankitd

+0

我错了它不是 - 检查[$ anchorScroll](https://docs.angularjs.org/api/ng/service/$anchorScroll) – maioman

回答

9

Here is the working plunker

在此我不得不重写UI,引导预输入作为answer建议。

以下是我需要做的修改它的工作:

typeaheadMatch指令(线 - ui.bootstrap.typeahead.js在plunker文件335)增加以下行

element[0].focus(); 

添加shouldFocus指令(线 - 314 -350)

.directive('shouldFocus', function(){ 
    return { 
    restrict: 'A', 
    link: function(scope,element,attrs){ 
    scope.$watch(attrs.shouldFocus,function(newVal,oldVal){ 
     element[0].scrollIntoView(false); 
    }); 
    } 
}; 
}) 

和最后加入指令在li(线 - 372)

should-focus=\"isActive($index)\" 
+0

当页面有滚动和输入元素的时候,这是行不通的。请在这个 – KanhuP2012

+0

@ KanhuP2012上寻求帮助 - 你能否创建一个能够证明这种行为的重载程序?这对获得错误修复将非常有帮助。谢谢 – user1690588

+0

请为这个http:// plnkr找到plunk。co/edit/qpkrmBVFNZSpxpC4eeJt?p =预览选择下拉主页面视图后滚动。 – KanhuP2012

5

@ user1690588答案很好。唯一的问题是当列表中的最后一个项目处于活动状态并且您按下了向下键时。 scrollToView到第一个项目不起作用。我添加了一个检查来确保newVal是真实的,这似乎解决了这个问题。

if (newVal) { 
    element[0].scrollIntoView(false); 
    } 

http://plnkr.co/edit/05yoHSlhvX740tgiRRXm

0

如果主窗口已经滚动接受的解决方案将失败。 @ user1690588在正确的轨道上。

编辑UI的自举-TPLS-0.13.3.js和周围线5205下降这在上面.filter(“typeaheadHighlight”)至少直到AngularUI团队决定解决这个问题。以及将其他更改应用到接受的解决方案引用的模板。

.directive('shouldFocus', function() { 
    return { 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      scope.$watch(attrs.shouldFocus, function (newVal, oldVal) { 
       if (newVal && element.prop("class").indexOf("active")) { 
        var par = element.parent("ul"); 
        var scrollingTo = element.offset().top - par.offset().top + par.scrollTop(); 
        // uncomment below section if you want the selected content to be 
        // viewed at half the box height 
        // scrollingTo = scrollingTo - (par.height()/2); 
        par.scrollTop(scrollingTo); 
       } 
      }); 
     } 
    } 
}) 

此外,如果你想摆脱鼠标神器的地方开始滚动起来,直到它碰到的第一个条目或向下,直到碰到那么最后一个条目从模板NG-的mouseenter属性中删除。

3

我用另一种方法来解决这个问题,因为这里没有任何解决方案能够满足。主要是:

  • 到达最后项目按向下键应该带来的第一项眼帘
  • 徘徊项目进行光标使用鼠标滚轮应该不会触发怪异不应使事先键入的内容弹出滚动
  • 在弹出事先键入的内容的行为
  • 修复应避免修改AngularUI引导源

扩展AngularUI引导指令,并听取只有特定的键连TS似乎提供了一个更清洁的解决方法,因为你可以在这里看到: http://plnkr.co/edit/QuZw7j?p=preview

angular.module('ui.bootstrap.demo') 
    .directive('typeahead', function() { 
     return { 
      restrict: 'A', 
      priority: 1000, // Let's ensure AngularUI Typeahead directive gets initialized first! 
      link: function (scope, element, attrs) { 
       // Bind keyboard events: arrows up(38)/down(40) 
       element.bind('keydown', function (evt) { 
        if (evt.which === 38 || evt.which === 40) { 
         // Broadcast a possible change of the currently active option: 
         // (Note that we could pass the activeIdx value as event data but AngularUI Typeahead directive 
         // has its own local scope which makes it hard to retrieve, see: 
         // https://github.com/angular-ui/bootstrap/blob/7b7039b4d94074987fa405ee1174cfe7f561320e/src/typeahead/typeahead.js#L104) 
         scope.$broadcast('TypeaheadActiveChanged'); 
        } 
       }); 
      } 
     }; 
    }).directive('typeaheadPopup', function() { 
     return { 
      restrict: 'EA', 
      link: function (scope, element, attrs) { 
       var unregisterFn = scope.$on('TypeaheadActiveChanged', function (event, data) { 
        if(scope.activeIdx !== -1) { 
         // Retrieve active Typeahead option: 
         var option = element.find('#' + attrs.id + '-option-' + scope.activeIdx); 
         if(option.length) { 
          // Make sure option is visible: 
          option[0].scrollIntoView(false); 
         } 
        } 
       }); 

       // Ensure listener is unregistered when $destroy event is fired: 
       scope.$on('$destroy', unregisterFn); 
      } 
     }; 
    }); 

测试与AngularJS 1.4.5 & AngularUI引导0.13.4,但这应该与最近的其他版本。

[注意,我不得不手动包括jQuery的,作为一个由Plunker(jQuery的v1.8.3)预装将会失败检索当前活动选项]