Angular table row directive not rendering inside table

11,300

Solution 1

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.

Solution 2

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.

Share:
11,300
Milligran
Author by

Milligran

Updated on June 14, 2022

Comments

  • Milligran
    Milligran about 2 years

    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?