1

I'm trying to build an editable table component in AngularJS. The way I want it to work is that when the user clicks an Edit button on a particular row that row is replaced with an "edit template" containing input fields bound to the model. You can see my progress in this Plunker.

I'm using a custom directive to allow me to define a table with editable rows like so:

<table ng-controller="peopleController as peopleCtrl">
  <tr editable-row edit-model="person" edit-tmpl="'person-editor.html'"  ng-repeat="person in peopleCtrl.people">
    <td>{{person.name}}</td>
    <td>{{person.age}}</td>
    <td>
      <button>Edit</button>
    </td>
  </tr>
</table>

In the editable-row directive's Link function I am creating the "edit template" as a string of html and using $compile to bind the expressions to the directive scope. What I would like to do instead of hard coding the html within the Link function is have the template loaded from an external file referenced from the directives "edit-tmpl" attribute. Note: Setting the templateUrl for the directive won't work as I only want the template to be loaded and injected into the DOM when the user clicks the edit button.

My question is two fold:

1) How can I load the html from the template file referred to by the "edit-tmpl" attribute within the Link function of my directive?

2) As I am new to Angular I am wondering if my approach is in keeping with the AngularJS way of things? From an angular design perspective is it a good idea to have the edit template specified in the HTML via an attribute like this and then loaded within the directive's Link function or is there a better approach that I am missing?

2
  • If u interested in angular way - u may have a look at bootstrap-ui directives. All their templates are stored in $templateCache and referenced by id, thus they can be replaced outside. I dont understand why u care so much about loading additional template - 99% that it is not a narrow place of your application. Commented Feb 16, 2015 at 17:45
  • Thanks Petr. I will take a look at the bootstrap-ui directives. My basic reason for wanting to specify the template outside of the Link function is that so the directive can be reused across different tables and a different edit template created for each table. Some of my tables may contain some more complicated UI to edit rows (not just simple input fields) so I want to be able to define the row editor separately for each table but without writing a whole new directive each time. Commented Feb 16, 2015 at 18:16

1 Answer 1

0
app.directive('editableRow', function($compile){
  return{
    restrict:'A',
    replace:true,
    scope: {editModel: '='},


    link: function(scope, element, attr){
      element.find('button').on('click', function(){

            var htmlText = '<div ng-include="{{attr.editTmpl}}"></div>';

             OR

            var htmlText='<div ng-include src="{{attr.editTmpl}}"></div>';

            // I don't know which would work for you. but this is the way to add dynamic template to your directive by just passing appropriate path of template to attr.editTmpl attribute;

        var editTmpl = angular.element($compile(htmlText)(scope));
        element.replaceWith(editTmpl);
      });
    }
  };
});

But I just wonder with your directive. As here you are using replaceWith method (which will replace your template to existing one in row) but how would you get your original template or ROW back after editing is done on a row? I'd like to see it brother.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for that. I don't seem to be able to make it work though. I get a javascript error when the first { is encountered. I have tried removing the {{}} and using string concatenation instead which produces the correct ng-include tag but still does not seem to work. The ng-include gets replaced with a comment in the HTML but not the template code: see here plnkr.co/edit/16TyvWy0lEla6iH56kue?p=preview As for bringing back the view display when the edit is completed I will likely use ng-show and move away from replaceWith() for the final design.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.