1

I have a list of model objects that are presented in the view with an ng-repeat directive on input elements, being editable. There is an Add new button to add a new item to the list, which creates a new empty input. But as soon as the new empty input is created in the view, I want it to be focused and ready to be edited. I'm not sure how to go about this, since I have little access to the DOM in the controller and the controller is where I am adding the new empty model to the list.

I'm still new with AngularJS, writing this app to learn. So, do let me know any other things I've done wrongly in the implementation.

Plunker: http://plnkr.co/Ig4OtuUtFatIknO1Kfxi

Interesting pieces of code:

HTML:

<body ng-controller=PlanetCtrl>
  <div>
    <input ng-repeat='it in planets' type=text ng-model=it.name edit-spotlight>
  </div>
  <button ng-click=addNew() class='btn btn-primary'>+ Add new item</button>
  <div id=spotlight-shadow></div>
</body>

Javascript:

angular.module('planet-man', []).

// ... editSpotlight directive ...

function PlanetCtrl ($scope) {

  $scope.planets = [
    {name: 'Mercury'},
    {name: 'Venus'},
    {name: 'Earth'},
    {name: 'Mars'}
  ];

  $scope.addNew = function () {
    $scope.planets.push({name: ''});
  };

}

As you can see from the plunker, when the Add button is clicked, a new input is added to the view, but one has to manually focus it. I want it to receive focus (and have the spotlight effect appear) immediately on clicking the Add button.

Thank you.

sharat87
  • 7,330
  • 12
  • 55
  • 80
  • http://stackoverflow.com/questions/14833326/how-to-set-focus-in-angularjs – mb21 May 29 '13 at 16:48
  • @mb21, thanks for the link. So, should I have a pseudo-property on my planet objects called `.isEditing` which is to be watched? That feels wrong. Why should the model care about it being edited and focused? – sharat87 May 29 '13 at 17:00
  • Here is modified version of your plunker: http://plnkr.co/edit/QScU5GE1EeGskbmrZCIc?p=preview – ardentum-c May 29 '13 at 17:08
  • @ardentum-c, Nice. It shows up the spotlight, but doesn't focus. I added `$timeout(function () { element[0].focus(); }, false);` to the focus function and it works now. See http://plnkr.co/edit/BuZyqUi7qi6CJY0hA8oi?p=preview – sharat87 May 29 '13 at 17:20
  • Problem seems be solved, please post an answer @ardentum-c, so I can accept :). Thank you. – sharat87 May 29 '13 at 17:21

2 Answers2

1

tried to do this in a bit more 'angular' way: http://plnkr.co/edit/8vtgfTqBh3sxqO0KLk4y

winkerVSbecks
  • 1,173
  • 1
  • 10
  • 24
  • But this focuses the last input on page load. That is not intended behavior. And, is there any advantage in using `span`s in the markup and an `input` in the template instead of directly using `input` elements? Or is it just convention? – sharat87 May 30 '13 at 06:03
  • I had to use span in order to apply the appropriate class. Plunker was acting weird with respect to ng-class. Ideally you should be using ng-class to set or remove a class type. As for the focus on init part, you could add a variable to your Controller that activates the highlight part of your directive only after an element is added on the first run. i.e., add `$scope.startHighlighting = false;` to the controller and then the addNew function would change to: `$scope.addNew = function () { $scope.startHighlighting = true; $scope.planets.push({name: ''}); });` – winkerVSbecks Jun 01 '13 at 19:05
0

Here is modified version of your plunker: plnkr.co/edit/QScU5GE1EeGskbmrZCIc?p=preview

ardentum-c
  • 1,410
  • 13
  • 11