fix(typeahead): fix matches pop-up positioning issues
Closes #262, #282
This commit is contained in:
@@ -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) {
|
||||
@@ -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) {
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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];
|
||||
|
||||
@@ -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();
|
||||
@@ -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();
|
||||
@@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,6 +199,7 @@ angular.module('ui.bootstrap.typeahead', [])
|
||||
matches:'=',
|
||||
query:'=',
|
||||
active:'=',
|
||||
position:'=',
|
||||
select:'&'
|
||||
},
|
||||
replace:true,
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user