user1851003 user1851003 - 4 months ago 74
AngularJS Question

Apply autofocus on input inside ng-repeat

I want to autofocus the first input inside

ngRepeat
when my page loads and when I add a new item to array the focus should go for the last item of the
ngRepeat
and so on, doesn't matter how many items I add.

Here's my code actually:

<div class="add-top" ng-show="showstep=='step2'" style="position:relative;width:100%;">
<form name="EmailForm" novalidate accessible-form autocomplete="off" ng-submit="checkDup() && EmailForm.$valid ? Add() :''">
<div class="white text-center ">
<!-- && (emailDel | filter:'':true).length == emailDel.length -->
<div class=" bg-color-upload03 ticket-top">
<div class="col-md-12 " ng-init="emailDel=[1]">
<div class="newevent-nav01">
Enter email ids</div>
<div class="col-md-6 col-md-offset-3" ng-repeat="e in emailDel track by $index">

<input type="email" class="text-left" placeholder="Email ID" validate-email ng-model="emailDel[$index]" ng-init="emailDel[$index]=''" ng-required="emailDel.length==1" name="email_{{$index}}" id="email_{{$index}}">

<div class="col-md-2 col-md-offset-10 text-left" style="margin-top: -10px;" ng-show="(emailDel.length-1)==$index">

<img src="../../../path to + symbol-active icon" width="40%" ng-hide="(EmailForm.$valid && emailDel[ds.emailDel.length-1] !='')" />

<img src="../../..path to +symbol gray icon" width="40%" class="cursor-poi" ng-click="(EmailForm.$valid && emailDel[emailDel.length-1] !='') ? emailDel.push(emailDel.length+1) :''" ng-show="(EmailForm.$valid && emailDel[emailDel.length-1] !='')" />

</div>
<div class="col-md-12">
<span class="error" ng-show="EmailForm['email_'+$index].$touched && !EmailForm['email_'+$index].hasFocus">
<span ng-show="EmailForm['email_'+$index].$error.required">
Required
</span>
<span ng-show="EmailForm['email_'+$index].$error.email">
Invalid Email
</span>
<span ng-show="emailDel[$index]!='' && (emailDel | filter:emailDel[$index]:true).length>1">
Duplicate Email
</span>
</span>
</div>
</div>
</div>

<div class="col-md-4 col-md-offset-4">
<div class="col-md-10 col-md-offset-1">
<button type="submit" class="btn" ng-disabled="EmailForm.$invalid || (emailDel.length>1 && (emailDel | filter:'':true).length==emailDel.length)">Continue</button>
</div>
</div>
</div>
</div>
</form>
</div>

Answer

You can create your own directive for this.

When it loads you set focus to the $first element of your ngRepeat, when you starts to add elements, the focus should go to the $last.

Here's a snippet working:

angular.module('app', [])
 .controller('mainCtrl', function($scope) {
   $scope.email = ['test1@gmail.com', 'test2@hotmail.com', 'test3@stackoverflow.com'];
   $scope.init = true;
   $scope.add = function() {
     $scope.email.push('');
     $scope.init = false;
   }
 })

 .directive('setFocus', function() {
   return {
     scope: {
       setFocus: '='
     },
     link: function(scope, element) {
       if (scope.setFocus) element[0].focus();
     }
   };
 });
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>

<body ng-controller="mainCtrl">
  <form name="delEmailForm" novalidate accessible-form autocomplete="off" ng-submit="testing() && delEmailForm.$valid ? Add() :''">
    <div class="col-md-6 col-md-offset-3 text-center" ng-repeat="e in email track by $index">
      <input type="email" set-focus="init ? $first : $last" class="inputbox-text-left" placeholder="Email ID" validate-email ng-model="email[$index]" ng-required="email.length==1 " name="email_{{$index}}" id="email_{{$index}}">
    </div>
    <button type="button" value="add" ng-click="add()">+</button>
  </form>
</body>

</html>