Javascript – Print Div Content Using AngularJs

angularjscsshtmljavascriptjquery

Inside AngularJs app, I want to inject generated content inside printDiv on certain on event. This printDiv is styled using and should be displayed on print only.

Below is the code snippet:

@media print {    
    body > #printDiv{
        display:block;
    }
    body > #screenContent{
        display:none;
    }        
}
@media screen {
    body > #printDiv {
        display: none;
    }
    body > #printContent{
        display:block;
    }
}

On certain event like (ng-click) like below example it calls function GenerateContent() on controller.

$scope.GenerateContent = function () {
   $("#divOne").text(data.FirstName);
   $("#divTwo").text(data.LastName);
   ...
     $scope.Print();
}

Here, I tried to fetch previously injected content using plain JS and then printed using window.print() like below:

$scope.Print = function () {
    var content = document.getElementById("printContent").innerHTML;            
    document.getElementById('printDiv').innerHTML = content;
    window.print();
}

And, finally on html page div structure is like below:

<html>
   <body>
       <div id="screenContent">
           // html content for screen only
       </div>
       <div id="printDiv"></div>
       <div id="printContent">
          <div id="divOne"></div>
          <div id="divTwo"></div>
       </div>
   </body>
</html>

On first attempt content is generated correctly and printed well. On every other attempt content is not injected, it always prints content generated on first attempt.

Is this correct way of injecting and printing div using AngularJs SPA? How can my example be fixed to work in expected manner?

Update:

I tried with ng-bind instead of using jquery like this

<div id="printContent" ng-controller="myController">
    <div id="divOne" ng-bind="firstName"></div>
    <div id="divTwo" ng-bind="lastName"></div>
</div>

and inside controller

$scope.firstName = data.FirstName;
$scope.lastName = data.LastName;

but this doesnt inject anything into dom.

I tried also with ng-model instead of ng-bind that also doesnt work.

Update 2

myController
(function () {
    "use strict";
    app.controller('myController',
       ....
        $http({
             method: 'POST',
             url: '/SomeService',
             data: ....,
           }).success(function (data) {
              $scope.firstName = data.FirstName;
              $scope.lastName = data.LastName;
          }
       });
    ...
}());

Update 3

<div id="printDiv">
   <div id="printContent" ng-app="myApp" ng-controller="myController">
      <div id="divOne" ng-bind="data.firstName"></div>
      <div id="divTwo" ng-bind="lastName"></div>
   </div>
</div>

myController code

angular.module('myApp', [])
.controller('myController', function ($scope) {
   $scope.firstName: "Bob";
   $scope.lastName: "Smith";
   window.print();
});

I'm calling window.print to print content inside printDiv where elements are binded to controller properties, yet this not working. When I look inside firebug content is not binded at all (html structure looks ok with ng-bing, but there is no actual content binded to that element).

What I'm doing wrong here?

Best Answer

Can't tell from your disconnected bits and pieces where you're going off track (where is GenerateContent located relative to everything else for example?) but here is a very simple example of a controller doing what you're asking for without jQuery:

DOM:

<div ng-app="foo">
     <div id="printContent" ng-controller="demoController">
        <div id="divOne" ng-bind="data.firstName"></div>
        <div id="divTwo" ng-bind="data.lastName"></div>
    </div>
</div>

Controller:

angular.module('foo', [])
    .controller('demoController', function ($scope) {
    $scope.data = {
        firstName: "Bob",
        lastName: "Smith"
    };

})

https://jsfiddle.net/m10ojexn/