0

The scenario I have is to create dynamic table using javascript by passing the data passed from script tag. My javascript code parses the provided json and generates the table header and table body. The table body is generated along with the tags required for angular binding method {{variable_name}}.

But after the DOM is created I need to re-apply the scope to ng-repeat of table.

<html>
<head>
<title>dynamic table</title>
<link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
    <script src="js/angular.min.js"></script>
    <script src="js/jquery.min.js"></script>

<script type="text/javascript">
var orderByField = "impressions";
var reverseSort = "false";
var myList = [{firstName: 'John',lastName: 'Doe',age: 30,etc : 'heelo'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Sue',lastName: 'Banter',age: 21,etc: 'cool'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'},{firstName: 'Frank',lastName: 'Burns',age: 54,etc: 'world'}];


function addAllColumnHeaders(myList, selector)
{   
    var columnSet = [];
    var headerTr$ = $('<tr/>');
    var aStart = '<a href="#" ng-click="orderByField=\'';
    var aMid = '\'; reverseSort = !reverseSort">';
    var aEnd = '</a>';

    for (var i = 0 ; i < myList.length ; i++) {
        var rowHash = myList[i];
        for (var key in rowHash) {
            keyLink = aStart+key+aMid+key+aEnd;
            if ($.inArray(key, columnSet) == -1){
                columnSet.push(key);
                headerTr$.append($('<th/>').html(keyLink));
            }
        }
    }
    $(selector).append(headerTr$);
    return columnSet;
}

function createAngularTableDataPlaceholder(myList, selector)
{
    var columnSet2 = [];
    var headerTr2$ = $('<tr/>').attr('ng-repeat','field in myList|orderBy:orderByField:reverseSort');
    var aStart2 = '<td>{{field.';

    var aEnd2 = '}}</td>';

    for (var i = 0 ; i < myList.length ; i++) {
        var rowHash2 = myList[i];
        for (var key2 in rowHash2) {
            keyLink2 = aStart2+key2+aEnd2;
            //alert(keyLink);
            if ($.inArray(key2, columnSet2) == -1){
                columnSet2.push(key2);
                headerTr2$.append($('<td/>').html(keyLink2));
            }
        }
    }
    $(selector).append(headerTr2$);
    return columnSet2;
}
</script>
</head>
<body>
<div class="container">
<section ng-app="app" ng-controller="MainCtrl" ng-init="getMember(myList)">
<table class="table" id="excelDataTable" border="1">
            <thead id="thead">

            </thead>
            <tbody id="tbody">
              <!--tr ng-repeat="field in myList|orderBy:orderByField:reverseSort">

              </tr-->
            </tbody>
  </table>
  </section>
  </div>

  <script>
    var app = angular.module('app', []);

        app.controller('MainCtrl', ['$scope', '$window', function($scope, $window) {        

                addAllColumnHeaders(myList, '#thead');
                createAngularTableDataPlaceholder(myList, '#tbody');
                console.log("header and columns done");

                $scope.orderByField = $window.orderByField;
                console.log($scope.orderByField);

                $scope.reverseSort = false;
                console.log($scope.reverseSort);

                angular.element(document).ready(function () {
                $scope.myList = $window.myList;
                console.log("got "+$scope.myList);
            });

        }]);    
    </script>

</body>
</html>

The dom elements created are as - enter image description here

The current output I am getting is as - enter image description here But the problem is that angular binds all its code at rendering time. How can I use the $scope.watch method or $scope.apply method to get this done after javascript is done. I was trying to do this using

angular.element(document).ready(function ())

but that's not the correct way I suppose.
I am new to angular. Please guide me. Thanks!

8
  • 1
    You shouldn't be creating the dom with jQuery in the first place. The data should be passed into a controller and let angular build the dom Commented Jul 15, 2016 at 19:45
  • 1
    I would put all of your js logic in the angular controller to start with Commented Jul 15, 2016 at 19:45
  • 2
    Strongly suggest reading thinking-in-angularjs-if-i-have-a-jquery-background Commented Jul 15, 2016 at 19:47
  • Thank you @charlietfl and Justin. This seems more logical. I passed all my code to controller to build the dom. But still its the same error. As I think that ng-app is getting rendered before and components are created later maybe ? Commented Jul 15, 2016 at 20:32
  • 1
    you need an ng-repeat to populate that table. Most tutorials will show this. Go through tutorial on angular docs site step by step. Will save you a lot of problems later understanding the basics Commented Jul 15, 2016 at 21:05

1 Answer 1

1

You can bootstrap angular after DOM tree is rendered. Just remove ng-app from section and put this code at the end of first script:

var elem = document.querySelector('section');
angular.bootstrap(elem, 'app');

Of course, use better way to select your element on which you want to bind ng-app to

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

4 Comments

All this will do is throw a band-aid on a poorly set up app
Thanks @bohdan, this is how I can patch the code i believe. I added an id to the section for proper selection of section tag and am trying to use the bootstrapping, but with no success. Where exactly should I put this ?
@devutkarsh , at the end of first code. But probably now your angular module code should go first. So first script tag angular.module('app')... second script - your dom rendering. But also it'll be better to use console. Often angular throws understandable mistakes and you should read it
but don't forget to remove ng-app='app' from section, let angular.bootstrap do that stuff

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.