32

I am trying to add a row "isrcrow" directive to a table as follows:

<table class="table">
        <thead><tr>
                   <th>Artist Name</th>
                   <th>Track Title</th>
                   <th>Version</th>
                   <th>Track Duration</th>
                   <th>Recording Year</th>
                   <th></th>
               </tr>
        </thead>
        <tbody>
            <isrcrow></isrcrow>
        </tbody>       

    </table>

Here is the directive:

(function() {
  var isrcorderapp;

  isrcorderapp = angular.module("isrcorderapp", []);

  isrcorderapp.controller("isrcordercontroller", function($scope, $http) {
    return $scope.recordingTypes = [
      {
        type: 'Single'
      }, {
        type: 'Album'
      }, {
        type: 'Live'
      }, {
        type: 'Concert'
      }, {
        type: 'Instrumental'
      }
    ];
  });

  isrcorderapp.directive("isrcrow", function() {
    return {
      restrict: 'E',
      template: '<tr>\
                <td><input id="artist" ng-model="name"/></td>\
                <td><input id="track"/></td>\
                <td><select id="isrctype" ng-model="isrctype" ng-change="setState(state)" ng-options="s.type for s in recordingTypes" class="ng-pristine ng-valid"></select></td>\
                <td><input id="duration"/></td>\
                <td><input id="year"/></td>\
                <td><input type="button" value="Add ISRC" onclick="AddIsrc()" class="btn btn-small btn-success" />\
                    <input type="button" value="Delete" onclick="RemoveIsrc()" class="btn btn-small btn-danger" />\
                </td>\
            </tr>',
      scope: {
        name: '='
      },
      link: function(scope, element, attr) {}
    };
  });

}).call(this);

The problem I am experincing is the isrcrow directive doesnt render inside the table body. Its rendered outside and above the table:

Does anyone knows what could be causing this behaviour?

3
  • 5
    If you are out of options, I recommend making isrcrow an attribute, and instead have <tr isrcrow></tr> in your HTML, which obviously means modifying your template code to exclude the <tr>s. Commented Feb 26, 2014 at 2:28
  • This suggestion worked. how can I make this the answer Commented Feb 28, 2014 at 6:25
  • I have the same problem. But my thing works in IE, not in Chrome. Commented Jul 14, 2014 at 18:13

3 Answers 3

30

Adding a summary of my comments as an answer since it appeared to have helped the OP. :-)

As GregL points out, omitting replace: true in a directive with restrict: 'E' and <tr> as the root template node will result in invalid markup, giving rise to the incorrect rendering of the row.

However, for those using a version of Angular prior to 1.2.13 (romantic-transclusion), this solution will not be applicable due to an issue that has been noted.

A work around would be to instead to use the directive as an attribute (i.e. restrict: 'A') and appropriately modify the template such that <tr> is no longer the root template node. This will allow replace: true to be used.

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

Comments

7

I would guess that this is because you have not specified replace: true for the isrcrow directive. As a result, the final markup would look like:

<isrcrow>
    <tr>
        <td>...</td>
        ...
        <td>...</td>
    </tr>
</isrcrow>

Which will be a direct child of a <tbody>, which is invalid markup. As a result, most modern browsers (e.g. Chrome, and also Firefox, I believe) will try to "fix" your markup to be valid by moving the <isrcrow> tag outside of the table.

Instead, if you add replace: true to your directive specification, the <isrcrow> element won't be rendered, and the browser should see only valid markup and not try to "fix" it.

1 Comment

For older versions of Angular, there is an issue concerning replace: true for directives having a template root of <tr>. (cf. github.com/angular/angular.js/issues/1459)
0

The previous answers are correct, but I found them a bit hard to understand/apply, so summarized how I solved it with their help:

The table

<tbody>
    <tr isrcrow ng-repeat="..."></tr>
</tbody>

The isrcow directive template (without tr, no single root)

<td></td>
<td></td>
...

The isrcrow directive with

restrict: 'A'
replace: false

The end results is

<tbody>
     <tr isrcrow>
         <td></td>
         <td></td>
         ...
     </tr>
     <tr isrcrow>
         <td></td>
         <td></td>
         ...
     </tr>
     ...
</tbody>

Comments

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.