1

According to this link : up/down arrow key issue with typeahead control (angular bootstrap UI)

i have added these line in my js:

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

while scrolling, we get some more disturb, scroll was not smoothy. Before adding this code, scroll was normal and smoothy. Please anyone help me?

Community
  • 1
  • 1
Priya M
  • 51
  • 1
  • 4

3 Answers3

2

Hi here is another code only for keyup event to adjust the scroll height while up/down keypress you need to add a function only to keyup in the typeahead directive in angular ui

search directive('typeahead' in the angular ui js file find fireRecalculating function before it paste the following function

function makeSureVisible(){
            $timeout(function(){
                $el = popUpEl.find('.active');
                if($el.length>0)
                {
                    var elTop, elBottom, nodeScrollTop, nodeHeight;
                    elTop = $el.position().top;
                    console.log(elTop);
                    elBottom = elTop + $el.outerHeight(true);

                    nodeScrollTop = popUpEl.scrollTop();
                    nodeHeight = popUpEl.height() + parseInt(popUpEl.css("paddingTop"), 10) + parseInt(popUpEl.css("paddingBottom"), 10);
                    if (elTop < 0) {
                        popUpEl.scrollTop(nodeScrollTop + elTop);
                    } else if (nodeHeight < elBottom) {
                        popUpEl.scrollTop(nodeScrollTop + (elBottom - nodeHeight));
                    }  
                }
            });  
        }

now find keyup function attached. call the above function

element.bind('keydown', function(evt) {
          //typeahead is open and an "interesting" key was pressed
          if (scope.matches.length === 0 || HOT_KEYS.indexOf(evt.which) === -1) {
            return;
          }

          // if there's nothing selected (i.e. focusFirst) and enter or tab is hit, clear the results
          if (scope.activeIdx === -1 && (evt.which === 9 || evt.which === 13)) {
            resetMatches();
            scope.$digest();
            return;
          }

          evt.preventDefault();

          if (evt.which === 40) {
            scope.activeIdx = (scope.activeIdx + 1) % scope.matches.length;
            scope.$digest();
            makeSureVisible();

          } else if (evt.which === 38) {
            scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;
            scope.$digest();
            makeSureVisible();

          } else if (evt.which === 13 || evt.which === 9) {
            scope.$apply(function () {
              scope.select(scope.activeIdx);
            });

          } else if (evt.which === 27) {
            evt.stopPropagation();

            resetMatches();
            scope.$digest();
          }
        }); 
abhishek
  • 21
  • 2
1
function makeSureVisible() {
    $timeout(function () {
        $el = popUpEl[0].querySelector('.active');
        if ($el) {
            var elTop, elBottom, nodeScrollTop, nodeHeight;
            elTop = $el.offsetTop;
            elBottom = elTop + $el.offsetHeight;

            nodeScrollTop = popUpEl[0].scrollTop;
            nodeHeight = popUpEl[0].offsetHeight - (parseInt(window.getComputedStyle(popUpEl[0], null).getPropertyValue('padding-top')) + parseInt(window.getComputedStyle(popUpEl[0], null).getPropertyValue('padding-bottom')));

            if (elTop < nodeScrollTop) {
                popUpEl[0].scrollTop = elTop;
            } else if (nodeHeight < elBottom) {
                popUpEl[0].scrollTop = nodeScrollTop + elBottom - nodeHeight;
            }
        }
    });
 }

I bumped into the same issue with latest version of angular bootstrap 0.14.3 as of 27/11/2015.

Comments:

I placed the function in the element.bind("keydown") since it didn't work where you suggested. (function wasn't in proper scope and was undefined)

  1. The first "if" wasn't triggered for me so i changed the logic a bit. When user reaches the end the dropdown scrolls to top properly in my case.

  2. Modified it to work for plain javascript.

Thank you for your solution!

Andrew
  • 113
  • 1
  • 9
0

I had previously resolved this issue using the "shouldFocus" directive but I had to make more tweaks to get this to work. Perhaps this version will work for you.

.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 cellHeight = element.children().innerHeight();
                    var maxHeight = par.height();
                    var startIndex = Math.floor(maxHeight / cellHeight);

                    if (scope.$index > startIndex) {
                        var scroll = (scope.$index - startIndex) * cellHeight;
                        par.scrollTop(scroll);
                    }
                    if (scope.$index === 0) {
                        par.scrollTop(0);
                    }
                }
            });
        }
    }
})

Here is the modified template for those who don't know where to add the directive:

angular.module("template/typeahead/typeahead-popup.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/typeahead/typeahead-popup.html",
    "<ul class=\"dropdown-menu\" ng-show=\"isOpen() && !moveInProgress\" ng-style=\"{top: position().top+'px', left: position().left+'px'}\" style=\"display: block;\" role=\"listbox\" aria-hidden=\"{{!isOpen()}}\">\n" +
    "    <li ng-repeat=\"match in matches track by $index\" should-focus=\"isActive($index)\" ng-class=\"{active: isActive($index) }\" ng-click=\"selectMatch($index)\" role=\"option\" id=\"{{::match.id}}\">\n" +
    "        <div typeahead-match index=\"$index\" match=\"match\" query=\"query\" template-url=\"templateUrl\"></div>\n" +
    "    </li>\n" +
    "</ul>\n" +
    "");
}]);
ewahner
  • 1,149
  • 2
  • 11
  • 23