Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Updating an input with a dynamic ng-model blurs on each key press

jsFiddle to demonstrate the problem: http://jsfiddle.net/yoxigen/xxTJc/

I'm building a small form to edit all of an object's properties. For that, I have a repeater for the properties. Each property has its input:

<ul ng-controller="myController">
   <li ng-repeat="(property, value) in obj">
       <input ng-model="obj[property]"/><span>{{value}}</span>
   </li>
</ul>

Each time a key is pressed in an input, the value next to it updates properly, but the input loses focus. Any idea how this can be fixed?

like image 256
yoxigen Avatar asked Jan 15 '13 15:01

yoxigen


2 Answers

I wish there was a way to postpone the regeneration until I'm done editing.

You might be able to do that. Just make a custom directive that blasts away the AngularJS events and listen to "change" instead. Here is a sample of what that custom directive might look like:

YourModule.directive('updateModelOnBlur', function() {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elm, attr, ngModelCtrl)
    {
      if(attr.type === 'radio' || attr.type === 'checkbox')
      {
        return;
      }

      // Update model on blur only
      elm.unbind('input').unbind('keydown').unbind('change');
      var updateModel = function()
      {
        scope.$apply(function()
        {
          ngModelCtrl.$setViewValue(elm.val());
        });
      };
      elm.bind('blur', updateModel);

      // Not a textarea
      if(elm[0].nodeName.toLowerCase() !== 'textarea')
      {
        // Update model on ENTER
        elm.bind('keydown', function(e)
        {
          e.which == 13 && updateModel();
        });
      }
    }
  };
});

Then on your input:

<input type="text" ng-model="foo" update-model-on-blur />
like image 82
Ezekiel Victor Avatar answered Oct 24 '22 09:10

Ezekiel Victor


From the google forums:

The problem is that with every change to the model object the ng-repeat regenerates the whole array and so blurs your input box. What you need to do is wrap your strings in objects

like image 40
Ulises Avatar answered Oct 24 '22 09:10

Ulises