类型控制的上/下箭头键问题(angular bootstrap UI)

时间:2014-12-30 12:28:01

标签: css twitter-bootstrap angular-bootstrap

选中此PLNKR,我已实施预先控件, 默认情况下,在类型提前控制中,他们没有设置任何最大高度或高度列表,但根据要求,我必须将列表的高度固定为110px。因此,当我们一次列出更长的列表时,只会显示4个数据,并且可以通过向下滚动看到休息。 当用户点击向上/向下滚动箭头时滚动正在工作,但它不能用键盘上/下键。

问题在步骤中解释: -

  1. 键入内容,即“a”以获取typeahead中的数据(将填充列表)
  2. 按向下箭头键(焦点将在列表项目上)
  3. 按向下箭头键4-5时间进一步向下(当我们遍历时 下到列表,滚动不会被移动。)
  4. 它始终显示列表中的前4项。理想的行为是它应该转移。
  5. 用户可以通过手动点击滚动来滚动,但是使用箭头键不能滚动。

    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 datalist

    $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'];
    

4 个答案:

答案 0 :(得分:9)

Here is the working plunker

在此我按照answer的建议覆盖ui-bootstrap typeahead。

以下是我需要做出的改变:

typeaheadMatch指令中添加以下行(pluganer中ui.bootstrap.typeahead.js文件的第335行)

element[0].focus();

添加了shouldFocus指令(第314行 - 第330行)

.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)\"

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:3)

我使用另一种方法来解决这个问题,因为这里没有一个解决方案令人满意。主要是:

  • 到达最后一个项目并按下DOWN键应该将第一个项目带入视图
  • 使用光标悬停项目不应进行Typeahead弹出式滚动
  • 使用鼠标滚轮不应在Typeahead弹出窗口中触发奇怪的行为
  • 修复应避免修改AngularUI Bootstrap源

扩展AngularUI Bootstrap指令并仅侦听特定的键事件似乎提供了一个更清晰的解决方法,如下所示: 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测试&amp; AngularUI Bootstrap 0.13.4,但这应该适用于其他最新版本。

[注意我必须手动包含jQuery,因为Plunker预装的那个(jQuery v1.8.3)将无法检索当前的活动选项。]

答案 3 :(得分:0)

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

编辑ui-bootstrap-tpls-0.13.3.js并将其放在 .filter('typeaheadHighlight')上方的5205线附近,至少等到AngularUI团队决定解决此问题。以及将其他更改应用于接受的解决方案引用的模板。

class ListPlacesTableViewController: UITableViewController {


var constantCell = [ListPlacesTableViewCell?](count: 1, repeatedValue: nil)
....
//other stuff here

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

if(indexPath.section == 0) {
        let cell2:ListPlacesTableViewCell = tableView.dequeueReusableCellWithIdentifier("MapCell", forIndexPath: indexPath) as! ListPlacesTableViewCell

        constantCell[0] = cell2
//other stuff here
}
}
//Clickable Cell Function add:
 constantCell[0]!.Map.setRegion(region, animated: true)
    constantCell[0]!.Map.addAnnotation(annotation)

此外,如果你想摆脱它开始向上滚动的鼠标神器,直到它到达第一个条目或向下直到击中最后一个条目,然后从模板中删除 ng-mouseenter 属性。