12

I found a good solution for inline editing content in angular js that is created by running ng-repeat on a model: https://stackoverflow.com/a/16739227/2228613

To expand on that solution I added a button to the page that has a ng-click directive as so:

<button ng-click="addCategory()" class="btn btn-large btn-primary" type="button">
<i class="icon-white icon-plus"></i> Add Category
</button>

The addCategory function is defined in my controller:

$scope.addCategory = function(){
    var newCategory = {id:0, name:"Category Name"};
    $scope.categories.unshift(newCategory);
}

The goal here is to allow the user to add a new record and automatically trigger the inline-edit directive once the view is updated with the new row. How can I trigger the inline-edit directive in such a manner?

Community
  • 1
  • 1
novon
  • 973
  • 3
  • 15
  • 30
  • Possible duplicate of [Angular Directive refresh on parameter change](http://stackoverflow.com/questions/20856824/angular-directive-refresh-on-parameter-change) – Mr_Green Feb 01 '17 at 15:09

2 Answers2

19

One technique that i've used is to have a boolean change values and have a $watch on it inside the directive that needs to be triggered.

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
            scope.$watch('someValue', function (val) {
                if (val)
                    // allow edit
                else
                    // hide edit
            });
     }
});

Then in your controller you'd set $scope.someValue = true; in your ng-click for the button.

plunker: http://plnkr.co/edit/aK0HDY?p=preview


UPDATE

I've gone a bit further with the above answer. I've made something more along the lines with what you're after.

Here's the plunk for it: http://plnkr.co/edit/y7iZpb?p=preview

This is the new directive:

  .directive('editCar', function ($compile) {
      return {
        restrict: 'E',
        link: function (scope, element, attr) {
          var template = '<span class="car-edit">'+
          '<input type="text" ng-model="car.name" />' +
          '<button ng-click="someValue = false" class="btn btn-primary">Save</button></span>';
          scope.$watch('someValue', function (val) {
              if (val) {
                  $(element).html(template).show();
                  $compile($('.car-edit'))(scope);
              }
              else
                  $(element).hide();
          });
        }
      }
  })

It replaces the <edit-car></edit-car> element with the above template. The save button adds the values to an array called editedCars. I've left in some dummy code for submitting the entire thing using $http.post()

Community
  • 1
  • 1
mnsr
  • 12,337
  • 4
  • 53
  • 79
  • How does the directive know which record in the model to invoke the inline-edit functionality for? – novon Jun 17 '13 at 01:19
  • actually now that I think about it, can I just scope.$watch('todos', function(val){...}) to keep track of any changes to the array containing todo objects? – novon Jun 17 '13 at 01:28
  • yes you can do that. I've updated my post with another plunker. This one is more to the point of what you're after. – mnsr Jun 17 '13 at 03:10
  • thank you very much for your help, what does the `restrict: 'E'` mean? – novon Jun 18 '13 at 05:56
  • 1
    restrict 'E' means that the directive will only affect an ELEMENT. in my example, it's . Default is 'A' which is ATTRIBUTE, e.g.
    . There's also 'C' which is CLASS, e.g.
    – mnsr Jun 19 '13 at 06:14
0

I have one possible solution for you: http://plnkr.co/edit/uzuKki (I worked on the original plunk as you mentioned.)

My idea is

  1. Add "editMode" property to TODO model
  2. Instead of passing in just todo.title to directive's scope, passing in the whole TODO object, which is inline-edit="todo" in index.html
  3. In inline-edit.html, change every editMode to model.editMode (and every model to model.title to display title correctly)
  4. In your controller's add method, create new object with editMode = true, e.g.

    var newTodo = {id:0, name:"TODO Name", editMode: true};
    $scope.todos.unshift(newTodo);
    
Ye Liu
  • 8,946
  • 1
  • 38
  • 34