0

I have a form in my Angular app where users can enter in multiples of the same field values using an add button.

<md-content layout-padding="">
    <div>
      <form name="userForm">
        <div layout="row" ng-repeat="person in persons">
          <md-input-container flex>
            <label>First name</label>
            <input ng-model="person.firstName">
          </md-input-container>

          <md-input-container flex>
            <label>Last Name</label>
            <input ng-model="person.lastName">
          </md-input-container>
        </div>
        <md-button class="md-raised" ng-click="addAnother()">Add Another</md-button>
      </form>
    </div>
  </md-content>

Working Codepen

So already a couple of inputs are populated, clicking the button adds a new object in order for a new set of inputs to appear.

What I would like is for the first input on the newly added row to receive focus so the user can start entering in right away.

Is there some way to set the tabIndex programatically?

mindparse
  • 6,115
  • 27
  • 90
  • 191

3 Answers3

0

Check this out. The great answer on your question you can find here: Input autofocus attribute

angular.module('ng').directive('ngFocus', function($timeout) {
    return {
        link: function ( scope, element, attrs ) {
            scope.$watch( attrs.ngFocus, function ( val ) {
                if ( angular.isDefined( val ) && val ) {
                    $timeout( function () { element[0].focus(); } );
                }
            }, true);

            element.bind('blur', function () {
                if ( angular.isDefined( attrs.ngFocusLost ) ) {
                    scope.$apply( attrs.ngFocusLost );

                }
            });
        }
    };
});
<input type="text" ng-focus="isFocused" ng-focus-lost="loseFocus()">
Community
  • 1
  • 1
admkowal
  • 31
  • 3
0

I have noticed you make use of a class named md-input-focused

Method 1(the best) This is the most simplest & elegant solution to your problem. Making use of $last in angular. Add a class condition on your <md-input-container> First name Codepen like so:

<md-input-container flex ng-class="{'md-input-focused': $last}">
  <label>First name</label>
  <input ng-model="person.firstName">
</md-input-container>

This method requires no additional javascript changes, but will only add the focus & not make the input active. See below method if you want to make the input active.

Method 2 Check the codepen. This is the same, but the javascript way of adding the same class dynamically

FYI: JQuery needed for the below statement. Hope you have that.

This is your magic statement. Codepen

$('.layout-row:last-of-type').children().first().find('input').focus();

Add this onto your $scope.addAnother function inside a timeout(very important).

Your whole function should look like

  $scope.addAnother = function() {
    $scope.persons.push({});
    setTimeout(function(){
      $('.layout-row:last-of-type').children().first().find('input').focus();
     }, 500);
  }

You could even make use of the angular $timeout instead of the window setTimeout

Nikhil Nanjappa
  • 6,454
  • 3
  • 28
  • 44
  • This isn't what I am after, instead, I want the input to receive focus. The solution you have offered still means the user has to click into the input. – mindparse Sep 14 '16 at 12:24
  • Thats even easier then, all you have to do is in "Method2" replace the `md-input-focused` lines with `$('.layout-row:last-of-type').children().first().find('input').focus();`. Answer & [Fiddle](http://codepen.io/PleaseBugMeNot/pen/EgKaGX) updated – Nikhil Nanjappa Sep 14 '16 at 13:10
0

Here you go - CodePen

Markup

<input ng-model="person.firstName" auto-focus="true">

Directive

// Inspired by Mark Rajcok's answer - http://stackoverflow.com/a/14837021/782358
.directive('autoFocus', function($timeout) {
    return {
        scope: { trigger: '@autoFocus' },
        link: function(scope, element) {
            scope.$watch('trigger', function(value) {
                if (value.toString() === "true") {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});
camden_kid
  • 12,591
  • 11
  • 52
  • 88