5

Trying to understand how to implement the pull-right class within the angular typeahead dropdown only.

Issues:

  • input is located on RHS of window (which is typical for a search input box)
  • my results are wider then my input (and the containing div)
  • I need right side of dropdown to align with right side of input box, and to extend on the left past (below) the input width.
  • (dropdown only needs shifting, text alignment within doesn't change and should stay aligned to left. ie. Not an RTL as in this issue: RTL for angularjs bootstrap's typeahead)

Applying pull-right class to a containing div doesn't seem to affect the drop-down independently of the input.
I'm not sure where else to put it ?

Is there a CSS method of controlling the alignment of the dropdown div?

Have modified the documentation example in the following Plunker:

  • includes the pull-right class in the containing div
  • placed in a containing div to narrow the width (perhaps unnecessary ?)

If you type 'ang' into the plunker example inputbox you'll see the results spill past the right of the window.

  <div class='column'>
    <div class='container-fluid pull-right' ng-controller="TypeaheadCtrl">
      <h4>Asynchronous results</h4>
      <pre>Model: {{asyncSelected | json}}</pre>
      <input type="text" ng-model="asyncSelected" placeholder="Locations loaded via $http" typeahead="address for address in getLocation($viewValue)" typeahead-loading="loadingLocations" class="form-control">
      <i ng-show="loadingLocations" class="glyphicon glyphicon-refresh"></i>
    </div>
  </div>

I've looked at the following issues, which don't seem to help me:

Community
  • 1
  • 1
Ben
  • 73
  • 1
  • 6

2 Answers2

5

You would need to override the inline-style that get generated for .drop-down-menu by typeahead. Something along the the lines of:

<script>
  $('#myInput').on('keypup', function() {
    $(".dropdown-menu").css({ "left": "auto", "right": "10px" });
  });
</script>

Plunker

Note: set right to whatever the distance is between your input and the RHS of the page/window


Update

For a non-jQuery version you would have to override the left css attribute of .dropdown-menu using !important

.dropdown-menu{
  left: auto !important;
  right:10px;
}

Updated Plunker

Michael Doye
  • 8,063
  • 5
  • 40
  • 56
  • thanks @M.Doye - looks like a good solution - would this work in a pure angularjs environment ? (we don't have jquery in the app currently). I presume this would require some sort of directive ? – Ben Apr 02 '15 at 17:31
  • @Ben you could do it using just CSS, but would have to use `!important`. have updated my answer as well as the plunker – Michael Doye Apr 02 '15 at 17:43
  • 1
    looks good ! modified your plunker showing your CSS solution with two different input boxes & different results alignment http://plnkr.co/edit/3arh1IOcKFQoNsqG5hwM?p=preview – Ben Apr 02 '15 at 17:59
  • Now you can have it on either side of the page :-) – Michael Doye Apr 02 '15 at 18:01
1

Another option is use the typeahead-popup-template-url hook with a little change on the default template implementation.

Using this approach you can use more than one instance of ui-typeahead defining the desired layout one by one.

Don't forget to tune the right length for your specific usage.

(function () {
 'use strict';

  angular.module('myAnswer', ['ui.bootstrap']);
  
})();
<html ng-app="myAnswer">
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
  <div class='container-fluid'>

    <h4>Static arrays</h4>
    <pre>Model: {{selected | json}}</pre>
    
<script type="text/ng-template" id="typeahead-popup-right.html">
  <ul class="dropdown-menu" ng-show="isOpen() && !moveInProgress" ng-style="{top: position().top+'px',left: 'auto', right: '15px'}" role="listbox" aria-hidden="{{!isOpen()}}">
    <li class="uib-typeahead-match" ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index, $event)" role="option" id="{{::match.id}}">
      <div uib-typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>
    </li>
  </ul>
</script>    
    
    
    <input type="text" ng-model="selected" uib-typeahead="state for state in ['Espirito Santo', 'Minhas Gerais', 'Rio de Janeiro', 'São Paulo'] | filter:$viewValue" class="form-control" typeahead-popup-template-url="typeahead-popup-right.html">
    <small class="help-block">Try typing 'Rio' or 'Janeiro'</small>
  </div>
  </body>
</html>
  • This should be the accepted answer as far as I'm concerned. One improvement would be to calculate the right position. If we get the page width in the controller, like so: `$scope.windowWidth = document.documentElement.clientWidth`. Then we can calculate the right position like this: `right: $parent.windowWidth - position().left - position().width+'px'}"` – Fonnae Jun 03 '21 at 17:09