Vincent
Vincent

Reputation: 6188

Focus on input generated by ng-repeat

html code

  <div class="row" ng-repeat="form in data.forms track by $index">
            <form name="myForm">
                <input id="search_{{$index}}" type="text" name="location" ng-model="form.query" ng-keyup="keyUp($index)"  >
            </form>

   </div>

Angular code

 $scope.data = {
                            forms: []

                        };
        jQuery(document).ready(function() {
                                        setTimeout(function() {
                                            jQuery('#search_0').focus();
                                        }, 500);
                                    });

The above code works, but needs an extra setTimeout. Is there a better way to wait for the forms to be generated and then do focus()?

Upvotes: 2

Views: 2294

Answers (1)

Stewie
Stewie

Reputation: 60416

First Rule of Angular: Do not touch the DOM outside of the scope of the directive.

First input element inside the ngRepeat can be focused with custom directive which will make use of the $first scope variable provided automatically by ngRepeat:

PLUNKER

app.directive('focusedOn', [
    '$timeout'
    ,function($timeout) {
      return function($scope, $element, $attrs) {
        function focus(){
          $timeout(function(){
            $element.focus();
          }, 20);
        }

        if(_($attrs.focusedOn).isEmpty()){
          return focus();
        }

        $scope.$watch($attrs.focusedOn, function(newVal){
          if(newVal){
            focus();
          }
        });

      };

    }
  ]

);
<div class="row" ng-form="myForm" ng-repeat="form in forms track by $index">
  <input type="text" name="location" ng-model="form.query" focused-on="$first" />
</div>

Note: It might or might not work without $timeout.

Upvotes: 3

Related Questions