Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular floating input label to use typeahead

I have used one of the style from here: http://tympanus.net/Development/TextInputEffects/index.html

To create an input directive, please see plunker: https://plnkr.co/edit/wELJGgUUoiykcp402u1G?p=preview

This working great for standard input fields, however, i am struggling to work wirth Twitter typeahead: https://github.com/twitter/typeahead.js/

Question - How can i use my floating input label with a typeahead?

app.directive('floatInput', function($compile) {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: {
      elemTitle: '=elemTitle',
      elemtId: '=elemeId'
    },
    templateUrl: 'input-template.html',
    link: function(scope, elem, attrs) {
      var ngModelName = elem.attr('input-model');
      var inputElem = angular.element(elem[0].querySelector('input'));
      inputElem.attr('ng-model', ngModelName);

      $compile(inputElem)(scope);
      $compile(inputElem)(scope.$parent);

      var inputLabel = angular.element(elem[0].querySelector('label span'));
      inputLabel.attr('ng-class', '{\'annimate-input\' : '+ngModelName+'.length > 0}');
      $compile(inputLabel)(scope);
    },
    controller: function($scope) {
      $scope.title = $scope.elemTitle;
      $scope.inputId = $scope.elemId
    }
  }
})

HTML:

<div>
<span class="input input--juro">
    <input class="input__field input__field--juro" type="text" id="{{inputId}}" ng-model="tmp" />
    <label class="input__label input__label--juro" for="{{inputId}}">
    <span class="input__label-content input__label-content--juro">{{title}}</span>
  </label>
  </span>
</div>
like image 713
Oam Psy Avatar asked Jul 02 '16 05:07

Oam Psy


1 Answers

The easiest way I know of to achieve this is to initialize the typeahead input in the link function of the directive. For initializing the typeahead with available options I would create an optional parameter to the directive and selectively initialize the input as a typeahead input if the list is provided.

Here is an example of how the directive could look instead:

app.directive('floatInput', function($compile) {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: {
      elemTitle: '=elemTitle',
      elemtId: '=elemeId',
      typeaheadSrc: '=?typeaheadSrc'
    },
    templateUrl: 'input-template.html',
    link: function(scope, elem, attrs) {
      var inputElem = angular.element(elem[0].querySelector('input'));

      if(scope.typeaheadSrc && scope.typeaheadSrc.length > 0){
        var typeahead = jQuery(inputElem).typeahead({
          hint: true,
          highlight: true,
          minLength: 1
        }, {
          name: 'typeahead',
          source: substringMatcher(scope.typeaheadSrc)
        });
      }
    },
    controller: function($scope) {
      $scope.title = $scope.elemTitle;
      $scope.inputId = $scope.elemId
    }
  }
});
// from http://twitter.github.io/typeahead.js/examples/
var substringMatcher = function(strs) {
  return function findMatches(q, cb) {
    var matches= [],
        substrRegex = new RegExp(q, 'i');

    $.each(strs, function(i, str) {
      if (substrRegex.test(str)) {
        matches.push({value: str});
      }
    });

    cb(matches);
  };
};

I have updated your plunker to achieve the desired result: Plunker

like image 154
Teddy Sterne Avatar answered Oct 16 '22 02:10

Teddy Sterne