2014-12-30 133 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)預裝將會失敗檢索當前活動選項]