5

I work with the angular bootstrap ui (typeahead) trying to show the list of my customers when the inputs is focused, with this:

lima3app.directive('typeaheadOpenOnFocus', function() {
    return {
        require: ['ngModel'],
        link: function(scope, element, attr, ctrls) {
            element.bind('focus', function() {
                ctrls.$setViewValue('');
                console.log('customer.customer');
            });
        }
    };

});

So in the view i setted my input:

<input type="text" class="form-content req" id="form-customer"
       name="formcustomer"
       typeahead="customer as customer.customer for customer in customerList | filter:{customer:$viewValue}"
       typeahead-on-select="onCustomerSelect($item)"
       typeahead-append-to-body="true"
       typeahead-open-on-focus

       ng-model="customer.customer"
       focus="true"
       required="required">

But the code, doesn't work. Is there any way to do this?

Holland Risley
  • 6,969
  • 9
  • 25
  • 34
Jhonatan Sandoval
  • 1,283
  • 6
  • 24
  • 40

4 Answers4

4

Thanks to @HenryNeo in locating the correct attribute that UI Bootstrap accepts. The following code is working for me , for angular-ui Bootstrap 1.3.3.

Use uib-typeahead to enable the dropdown and typeahead-min-length (without uib-) to enable the minLength attribute.

<input type="text" typeahead-min-length="0" uib-typeahead="t for t in timeZoneList">
Jeson Martajaya
  • 6,996
  • 7
  • 54
  • 56
1

I now have a working solution. There are 2 new directives which focus the field and automatically open the typeahead dropdown.

There is a working Plunker here.

app.js

(function () {
  var secretEmptyKey = '[$empty$]'

  angular.module('plunker', ['ui.bootstrap'])
    .directive('focusMe', function($timeout, $parse) {
      return {
          //scope: true,   // optionally create a child scope
          link: function(scope, element, attrs) {
              var model = $parse(attrs.focusMe);
              scope.$watch(model, function(value) {
                  if(value === true) { 
                      $timeout(function() {
                          element[0].focus();
                      });
                  }
              });
          }
      };
    })
    .directive('emptyTypeahead', function () {
      return {
        require: 'ngModel',
        link: function (scope, element, attrs, modelCtrl) {
          // this parser run before typeahead's parser
          modelCtrl.$parsers.unshift(function (inputValue) {
            var value = (inputValue ? inputValue : secretEmptyKey); // replace empty string with secretEmptyKey to bypass typeahead-min-length check
            modelCtrl.$viewValue = value; // this $viewValue must match the inputValue pass to typehead directive
            return value;
          });

          // this parser run after typeahead's parser
          modelCtrl.$parsers.push(function (inputValue) {
            return inputValue === secretEmptyKey ? '' : inputValue; // set the secretEmptyKey back to empty string
          });
        }
      }
    })
    .controller('TypeaheadCtrl', function($scope, $http, $timeout) {
      $scope.selected = undefined;
      $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'];
      $scope.opened = false;

      $scope.stateComparator = function (state, viewValue) {
        return viewValue === secretEmptyKey || (''+state).toLowerCase().indexOf((''+viewValue).toLowerCase()) > -1;
      };

      $scope.onFocus = function (e) {
        $timeout(function () {
          $(e.target).trigger('input');
        });
      };

      $scope.open = function() {
        $scope.opened = true;
      }
      $scope.close = function() {
        $scope.opened = false;
      }
    });
}());

HTML View

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
    <link href="style.css" rel="stylesheet" />
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.js"></script>
    <script src="ui-bootstrap-tpls-0.10.0.js"></script>
    <script src="app.js"></script>
  </head>

  <body>
    <div class="container-fluid" ng-controller="TypeaheadCtrl">
      <h4>Typeahead dropdown opens automatically</h4>
      <p>2 directives automatically focus on the field and show the dropdown.

            <br />
        <br />
        <button class="btn btn-default" ng-show="!opened" ng-click="open()">Open Input and show typeahead!</button>
        <button class="btn btn-default" ng-show="opened" ng-click="close()">Close Input</button>
        <br />
        <br />
        <input type="text" focus-me="opened" ng-focus="onFocus($event)" ng-show="opened" ng-trim="false" ng-model="selected" empty-typeahead typeahead="state for state in states | filter:$viewValue:stateComparator" class="form-control" />
        <br />
      </p>
      <pre ng-show="opened">Model: {{selected | json}}</pre>
    </div>
  </body>

</html>

This solution was posted in response to my question here:

Angular JS - Automatically focus input and show typeahead dropdown - ui.bootstrap.typeahead

Community
  • 1
  • 1
Holland Risley
  • 6,969
  • 9
  • 25
  • 34
1

I got a working solution by changing some code in ui-bootstrap-tpls-0.10.0.js. So there are no differences in the typeahead html markup.

You can have a look here at http://plnkr.co/edit/LXHDpL?p=preview.

To use this fix, use the ui-bootstrap-tpls-0.10.0.js from the Plunk. To see my changes, open ui-bootstrap-tpls-0.10.0.js from the Plunk and search for 'ahneo'.

 1. //minimal no of characters that needs to be entered before typeahead
    kicks-in
    // ahneo :: before
    //var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
    // ahneo :: after (changed minimal no of characters to 0 by default)
    var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 0;
 2. // ahneo :: new (set input value to empty string if it contains " " string value)
    if (inputValue === ' ') {
        inputValue = '';
        modelCtrl.$setViewValue('');
    }  
 3. // ahneo :: before
    //if (inputValue && inputValue.length >= minSearch) {
    // ahneo :: after (add new condition to get matches for min search = 0)
    if (minSearch === 0 || inputValue && inputValue.length >= minSearch) {
 4. // ahneo :: new (bind element to focus event to trigger modelCtrl.$parsers.unshift method)
    element.bind('focus', function (evt) {
        if (modelCtrl.$viewValue === '') {
            modelCtrl.$setViewValue(' ');
        }
    });

Hope this helps

Henry Neo
  • 2,357
  • 1
  • 24
  • 27
-1

You can set view value $setViewValue and bind click and blur events

directive('emptyTypeahead', function() {
return {
    require: 'ngModel',
    link: function(scope, element, attributes, control) {
      element.bind('click', function() {
        control.$setViewValue(' ');
      });
      element.bind('blur', function() {
        control.$setViewValue('');
      });
    }
  };
})
Sarthak
  • 183
  • 8