Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
fix(typeahead): fix matches pop-up positioning issues
Browse files Browse the repository at this point in the history
Closes #262, #282
  • Loading branch information
pkozlowski-opensource committed Apr 23, 2013
1 parent 77d9fa7 commit 74beecd
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 20 deletions.
9 changes: 4 additions & 5 deletions src/typeahead/test/typeahead.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ describe('typeahead tests', function () {
};

var findDropDown = function(element) {
return element.find('div.dropdown');
return element.find('ul.typeahead');
};

var findMatches = function(element) {
Expand All @@ -222,7 +222,7 @@ describe('typeahead tests', function () {
this.message = function() {
return "Expected '" + angular.mock.dump(this.actual) + "' to be closed.";
};
return !typeaheadEl.hasClass('open') && findMatches(this.actual).length === 0;
return typeaheadEl.css('display')==='none' && findMatches(this.actual).length === 0;

}, toBeOpenWithActive: function(noOfMatches, activeIdx) {

Expand All @@ -232,7 +232,7 @@ describe('typeahead tests', function () {
this.message = function() {
return "Expected '" + angular.mock.dump(this.actual) + "' to be opened.";
};
return typeaheadEl.hasClass('open') && liEls.length === noOfMatches && $(liEls[activeIdx]).hasClass('active');
return typeaheadEl.css('display')==='block' && liEls.length === noOfMatches && $(liEls[activeIdx]).hasClass('active');
}
});
});
Expand Down Expand Up @@ -391,12 +391,11 @@ describe('typeahead tests', function () {
var inputEl = findInput(element);

changeInputValueTo(element, 'b');
var dropdown = findDropDown(element);

$document.find('body').click();
$scope.$digest();

expect(dropdown).not.toHaveClass('open');
expect(element).toBeClosed();
});
});

Expand Down
28 changes: 20 additions & 8 deletions src/typeahead/typeahead.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
angular.module('ui.bootstrap.typeahead', [])
angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position'])

/**
* A helper service that can parse typeahead's syntax (string provided by users)
Expand Down Expand Up @@ -29,8 +29,7 @@ angular.module('ui.bootstrap.typeahead', [])
};
}])

//options - min length
.directive('typeahead', ['$compile', '$parse', '$q', '$document', 'typeaheadParser', function ($compile, $parse, $q, $document, typeaheadParser) {
.directive('typeahead', ['$compile', '$parse', '$q', '$document', '$position', 'typeaheadParser', function ($compile, $parse, $q, $document, $position, typeaheadParser) {

var HOT_KEYS = [9, 13, 27, 38, 40];

Expand All @@ -51,6 +50,16 @@ angular.module('ui.bootstrap.typeahead', [])

var isLoadingSetter = $parse(attrs.typeaheadLoading).assign || angular.noop;

//pop-up element used to display matches
var popUpEl = angular.element(
"<typeahead-popup " +
"matches='matches' " +
"active='activeIdx' " +
"select='select(activeIdx)' "+
"query='query' "+
"position='position'>"+
"</typeahead-popup>");

//create a child scope for the typeahead directive so we are not polluting original scope
//with typeahead-specific data (matches, query etc.)
var scope = originalScope.$new();
Expand Down Expand Up @@ -87,6 +96,11 @@ angular.module('ui.bootstrap.typeahead', [])
}

scope.query = inputValue;
//position pop-up with matches - we need to re-calculate its position each time we are opening a window
//with matches as a pop-up might be absolute-positioned and position of an input might have changed on a page
//due to other elements being rendered
scope.position = $position.position(element);
scope.position.top = scope.position.top + element.prop('offsetHeight');

} else {
resetMatches();
Expand Down Expand Up @@ -167,15 +181,12 @@ angular.module('ui.bootstrap.typeahead', [])
}
});

$document.find('body').bind('click', function(){

$document.bind('click', function(){
resetMatches();
scope.$digest();
});

var tplElCompiled = $compile("<typeahead-popup matches='matches' active='activeIdx' select='select(activeIdx)' "+
"query='query'></typeahead-popup>")(scope);
element.after(tplElCompiled);
element.after($compile(popUpEl)(scope));
}
};

Expand All @@ -188,6 +199,7 @@ angular.module('ui.bootstrap.typeahead', [])
matches:'=',
query:'=',
active:'=',
position:'=',
select:'&'
},
replace:true,
Expand Down
12 changes: 5 additions & 7 deletions template/typeahead/typeahead.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<div class="dropdown clearfix" ng-class="{open: isOpen()}">
<ul class="typeahead dropdown-menu">
<li ng-repeat="match in matches" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)">
<a tabindex="-1" ng-click="selectMatch($index)" ng-bind-html-unsafe="match.label | typeaheadHighlight:query"></a>
</li>
</ul>
</div>
<ul class="typeahead dropdown-menu" ng-style="{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}">
<li ng-repeat="match in matches" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)">
<a tabindex="-1" ng-click="selectMatch($index)" ng-bind-html-unsafe="match.label | typeaheadHighlight:query"></a>
</li>
</ul>

0 comments on commit 74beecd

Please sign in to comment.