Incorporating HTML with ng-binds through transclusion

I have been developing an angular directive to enhance the functionality of ng-table by adding filtering and exporting features. The main goal is to make this directive reusable for multiple tables, which requires the <td> elements to be dynamic. To achieve this, I am utilizing ng-transclude

The issue I am facing is that my <td> elements need certain directives like ng-bind, data-title, and sortable. However, when they are transcluded by the directive, they appear as empty values. I need a solution to delay rendering the <td> rows until they are inserted into the directive.

Below is a snippet of my view markup:

<div>
   <my-data-table search-filter="ss" table-values="mvData">
     <td data-title="'UUID' | translate" sortable="'id'" ng-bind="row.uuid | shortUuid"></td>
     <td data-title="'DEVICE.UNAME' | translate" sortable="'uname'" ng-bind="row.uname"></td>
     <td data-title="'DEVICE.LOGIN' | translate" sortable="'last_login'">{{{true: (row.last_login | selectedTimezone | moment:'MMM D, YYYY h:mma'), false: 'N/A'}[!!row.last_login]}}</td>
   </my-data-table>
</div>

This is how the directive template looks like:

<div class="row">
  <div class="col-sm-12">
    <table ng-table="mvData.tableParams" class="table table-striped table-hover table-bordered" template-pagination="src/tables/responsive-pager.html">
      <tr ng-repeat="row in $data">
        <div ng-transclude></div>
      </tr>
    </table>
  </div>
</div>

And here is the directive declaration:

angular.module('myApp')
.directive('myDataTable',function() {

    return {
        restrict:'E'
      , templateUrl:'src/tables/myDataTable.tpl.html'
      , transclude:true
      , scope: {
            searchFilter:'='
          , tableValues:'='
        }
      , link:function(scope,el,attr,ctrls) {
          console.log('hello world');
        }
      }
});

Answer №1

One issue arises when you divide a table and its columns into a directive with transcluded content in Angular. The problem stems from the fact that Angular becomes confused since it attempts to manipulate the DOM with invalid HTML (<td> elements should not exist outside of a <table> or <tr> elements).

To resolve this, there are a few steps you need to take:

  1. Instead of using <td> tags in the transcluded content, replace them with <div> tags (which will later be converted back to <td> during processing)

  2. Your template declaration needs to be more complex so that you can construct the entire template as a string. Within this template, include the logic to generate the desired HTML structure. Once you pass this string template to Angular, the remaining functionality should work smoothly. Essentially, you are manually handling the content transclusion.

Below is sample code featuring ng-table declarations without including the directives for simplicity:

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="MainCtrl">
   <my-data-table search-filter="ss" table-values="mvData">
     <div data-title="'UUID' | translate" sortable="'id'" ng-bind="row.uuid"></div>
     <div data-title="'DEVICE.UNAME' | translate" sortable="'uname'" ng-bind="row.uname"></div>
     <div data-title="'DEVICE.LOGIN' | translate" sortable="'last_login'"></div>
   </my-data-table>
</div>
</body>
<script>
    var app = angular.module('myApp',[]);

    app.controller("MainCtrl", function($scope){
        $scope.mvData= {
            $data : [
                {uuid : 'abc', uname : 'test'},
                {uuid : 'abc1', uname : 'test1'},
                {uuid : 'abc2', uname : 'test2'},
                {uuid : 'abc3', uname : 'test3'}
            ]
        };
    })

    app.directive('myDataTable',function() {
        return {
            restrict:'E',
            template : function(elem, attr){
                var startStr = 
                    '<div class="row">' + 
                        '<div class="col-sm-12">' + 
                            '<table ng-table="mvData.tableParams" class="table table-striped table-hover table-bordered" template-pagination="src/tables/responsive-pager.html">' + 
                                '<tbody><tr ng-repeat="row in tableValues.$data">';
                var endStr =    '</tr></tbody>' +
                            '</table>' + 
                        '</div>' + 
                    '</div>';

                var template = startStr;
                var colStr;
                angular.forEach(elem.find("div"), function(item){
                    colStr = item.outerHTML.replace('<div ','<td ').replace('</div>','</td>');
                    template = template + colStr;
                });

                template = template + endStr;
                return template;
            },
            scope: {
                searchFilter:'='
              , tableValues:'='
            }, 
          }
    });



</script>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When using the `Node fs.readstream()` function, the output includes `<Buffer 3c 3f 78 6d 6c ...>`, which is not in a readable

Handling a large XML file (~1.5gb) in Node Js by streaming it to process data in chunks has proven challenging due to the complexity of the documentation. A simple code snippet I am currently using is: var fs = require('fs'); var stream = fs.c ...

JavaScript function that shows the name of an individual extracted from a specific file

Hey there, currently I'm diving into a javascript tutorial and exploring ways to display a person's name along with their birthday on this historical day. <script type="text/javascript"> document.write("Today is <br/&g ...

All menus effortlessly sliding out simultaneously

I'm having an issue with my navigation bar. I want each link to slide its corresponding DIV up or down when clicked. However, all the DIVs are sliding and when clicking on the same link everything slides up. How can I fix this problem? This is my HT ...

Automatically populate input field values into a textarea using a separator with jQuery

There are multiple input fields to fill out: <input type="text" placeholder="name"> <input type="text" placeholder="age"> <input type="text" placeholder="gender"> <input type="text" placeholder="interest"> As I enter information i ...

Insert a numerical value into a list to make a series of numbers whole

I currently have an array of objects that looks like this: var arr = [ { "code": "10", }, { "code": "14", } ] My goal is to expand this array to contain 5 elements. The numbers should ran ...

Tips for modifying the hue of the hint attribute within vue.js?

`<v-text-field id="loginPasswordId" ref="password" v-model="password" class="login-input" dense :disabled="loading" :hint="hello world" :loading="loading" maxlength= ...

Is there an issue with the functionality of the number input type in HTML 5?

<form name="form" method="get" action="" > Number : <input type="number" name="num" id="num" min="1" max="5" required="required"/> <br/> Email : <input type="email" name="email" id="email" required="required"/> <br /> <in ...

Placing a FontAwesome icon alongside the navigation bar on the same line

Upon login, the navigation bar experiences display issues. Prior to logging in: https://i.stack.imgur.com/ZKyGe.jpg Following successful login: https://i.stack.imgur.com/zyP3m.jpg An obstacle I'm facing involves the Log Out fontawesome icon wrappi ...

Is there a way to grab code from a different HTML page using JavaScript and jQuery when the user clicks on something?

After testing various codes for the intended purpose mentioned in the title, I have observed a peculiar behavior. The code from settings.html appears briefly and then disappears rapidly. Javascript: function load() { $("#paste").load("settings.html") ...

Transform text that represents a numerical value in any base into an actual number

Looking to convert a base36 string back to a double value. The original double is 0.3128540377812142. When converting it to base 36: (0.3128540377812142).toString(36); The results are : Chrome: 0.b9ginb6s73gd1bfel7npv0wwmi Firefox: 0.b9ginb6s73e Now, h ...

Using regular expressions in Python with PyQt4 to eliminate anchor tags from HTML links in text

When using my QTextBrowser, I am able to identify links such as "www.test.com" with the following regular expression: re.compile( r"(\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Za-z0-9+&@#/%?=~_()|!:,.;]*[-A-Za-z0-9+&@#/%=~_()|])" ...

Achieving success seems to be out of reach

Can you help me achieve a successful data transmission conclusion? I have tried different methods, but none seem to work. When clicking the "Send" button, the data gets sent, but instead of the message saying "Data sent successfully," I need the form to di ...

What is the process of establishing a connection to a web service using Meteor or Node.js?

Currently working on developing a package that interfaces with a web service (either through nodejs or meteor). The web service will be delivering real-time data, so I am in need of a mechanism like a listener or trigger event that can alert me when new da ...

Incorporating HTML5 audio elements in JavaScript

I am working on a project where I need to create a grid of 16 audio files with separate links for each in HTML, CSS and JavaScript. Each box in the grid should link to a different audio file. My initial thought was to use a table to achieve this, so I cre ...

Ways to incorporate design elements for transitioning focus between different elements

When focusing on an element, I am using spatialNavigation with the following code: in index.html <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfb5acf2acafbeabb6beb3f2b1bea9b6 ...

Accessing variables from child controllers with populated select inputs in Angular

I'm currently facing an issue involving 3 controllers: Parent Controller: DocumentController Child Controller1: XdataController Child Controller2: CompanyController The child controllers are used to populate data in three Selector inputs on the fron ...

Looking to design a popup using CSS styles

How can I design a pop-up window using CSS for a specific div? I also want to display additional information within another div inside the popup. ...

Rotate each row of the table in sequence with a pause between each flip

I have a table with 3 columns and 10 rows. I would like to flip each row one by one, where each row contains data on both the front and back sides. The flipping animation should be similar to the example provided in this link, but the flipping should sta ...

What is the best way to make my if statement pause until a GET request finishes (GUARD) with the help of Angular?

I am currently working on implementing admin routes for my Angular app, and I have used a role guard to handle this. The code snippet below showcases my implementation: However, I would like the get request to finish executing before the if statement begi ...

Integrating Gesture Handling in Leaflet JS for two-finger scrolling enforcement

Have you ever noticed that when you're using a mobile device and scrolling down a webpage with a Google map, the map goes dark and prompts you to "Use two fingers to move the map"? https://i.stack.imgur.com/4HD1M.jpg I am interested in incorporating ...