Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular table row directive not rendering inside table

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?

like image 573
Milligran Avatar asked Feb 26 '14 01:02

Milligran


2 Answers

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.

like image 106
miqh Avatar answered Oct 08 '22 08:10

miqh


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.

like image 23
GregL Avatar answered Oct 08 '22 08:10

GregL