1

With Angular, I'm trying to implement a way to change a value with an 'Edit' button click in such a way that when this button is clicked, an input is displayed over the text, and when the 'Save' button is clicked, the input's opacity becomes 0, and the model's value is applied.

I've created a jsfiddle to make my issue a bit more visual. JSFIDDLE DEMO

The issue is the following: I want to select the text to make it obvious for the user that it can be changed now, after the 'Edit' button is clicked. I do it this way:

var input = angular.element(document.querySelector('input'))[0];
input.focus();
input.select();

The only problem is that the input.select() only works on second attempt. You can see it in the demo. I have no rational explanation to this whatsoever. I need to mention that this app that I'm writing is for Electron, it means that it will only launch in Chromium, so I don't need cross-browser support for this.

When the 'Edit' button is clicked for the first time, no selection happens:

What happens when the 'Edit' button is clicked for the first time

But when I click 'Save' and then 'Edit' again, everything works as expected:

enter image description here

Any thought would be much appreciated!

Vicky Gonsalves
  • 11,593
  • 2
  • 37
  • 58
Anton Egorov
  • 1,328
  • 1
  • 16
  • 33

2 Answers2

3

Use $timeout , it will trigger digest cycle

var app = angular.module('app', []);

app.controller('mainController', function($timeout,$scope) {
  var vm = this;
  vm.address = '127.0.0.1';
  vm.name = 'anabelbreakfasts';
  vm.editing = {
    address: false
  };
  vm.temp = {
    address: null
  };

  vm.changeClick = function(element) {
    vm.editing[element] = !vm.editing[element];
    if (vm.editing[element]) {
      vm.temp[element] = vm[element];
      var input = angular.element(document.querySelector('div.row.' + element + ' input'))[0];
      $timeout(function(){
        input.focus(); 
        input.select();
      });
    } else {
      vm[element] = vm.temp[element];
    }
  };
});

Fiddle

Vicky Gonsalves
  • 11,593
  • 2
  • 37
  • 58
1

Use setTimeout:

setTimeout(function(){
    input.select();
}, 0)

Also, input.focus() is kind of redundant

StudioTime
  • 22,603
  • 38
  • 120
  • 207
  • 1
    Great, it works, thanks. Sometimes you get so confused with the situation that you don't think of such simple solutions. – Anton Egorov Feb 11 '16 at 08:22
  • Please check this: http://stackoverflow.com/questions/19609796/what-advantage-is-there-in-using-the-timeout-in-angular-js-instead-of-window-se – Vicky Gonsalves Feb 11 '16 at 08:24
  • @VickyGonsalves thanks, I didn't know that - not a big Angular user but good to know for the future – StudioTime Feb 11 '16 at 08:58