0

The code below tries to copy a certain part of the the page, basically the form without the buttons into a new document. Once this is done, the aim is to print() it.

The problem is that the .write() is not capturing the content/values of the form only the html tags. The fields are copied and but are empty.

I wonder is that because i'm using the angular inherit $scope and ng-model functionality which the document.write cannot handle?!

The form that i want to print has this tag <form name="ticketForm" id="printForm" class="form-horizontal" novalidate>

and the button to initiate the call is

 <button type="button"
                              class="btn btn-primary"
                              ng-click="printElem()"
                              >
                          Print
                      </button>

The js files . Mind you i had to do all that shenanigans of adding the header and other elements piece by piece since i want to remove the table, buttons among other things. I only want to print the form but still remain the CSS.

$scope.printElem  = function(){
        $log.info("i'm here");  
        //Popup($(elem).html().print());    
        var elem = document.getElementById("printForm");
        $log.info(elem);
        var pwindow= window.open('', 'printForm', 'height=800,width=600');
        pwindow.document.write('<html ng-app="HelpDeskApp0" class="ng-scope"><head><style type="text/css">@charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\:form{display:block;}</style>');
        //window.print();
        pwindow.document.write('<link href="css/bootstrap.css" rel="stylesheet" type="text/css">' +
                '<link href="css/ashraf.css" rel="stylesheet" type="text/css">' +
            '<link href="css/json-tree.css" rel="stylesheet" type="text/css">' +
            '<link href="css/loading-bar.css" rel="stylesheet" type="text/css">' +
            '<link href="css/font-awesome.min.css" rel="stylesheet" type="text/css">' +
            '<link href="css/dx.common.css" rel="stylesheet" type="text/css">' +
            '<link href="css/dx.light.css" rel="stylesheet" type="text/css">');
        pwindow.document.write('<script src="lib/jquery-2.1.4.js"></script>' +
            '<script src="lib/angular.min.js"></script>'+
            '<script src="lib/angular-sanitize.js"></script>'+
            '<script src="lib/angular-resource.js"></script>'+
            '<script src="lib/globalize.min.js"></script>'+
            '<script src="lib/ui-bootstrap-tpls.js"></script>'+
            '<script src="lib/angular-route.js"></script>'+
            '<script src="lib/bootstrap.js"></script>'+
            '<script src="lib/dx.all.js"></script>'+
            '<script src="js/app.js"></script>'+
            '<script src="js/controllers.js"></script>'+
            '<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">'+
            '<meta name="apple-mobile-web-app-capable" content="yes">'+
            '<meta name="apple-mobile-web-app-status-bar-style" content="black"> </head>');
        pwindow.document.write('<body><nav class="panel panel-primary"> <!-- navbar navbar-default-->'+
            '<div class="container-fluid">'+
            '<!-- Brand and toggle get grouped for better mobile display -->'+
            '<div class="menubar" role="navigation">'+
                '<div class="">'+
                    '<div class="menubar-content-left">'+
                        '<a><img src="images/mgpi.png" height="50" width="50">&nbsp;<b style="color: #428bca">MGPI - Beta Version</b></a>'+
                    '</div> '+
                '</div>'+
            '</div>'+

            '<!-- Collect the nav links, forms, and other content for toggling -->'+
            '<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">'+
            '  <ul class="nav navbar-nav">'+
                '<li><a href="#/home">Help Desk</a></li>'+
              '</ul>          '+

            '</div><!-- /.navbar-collapse -->'+
            '</div><!-- /.container-fluid -->'+
            '</nav>'+

            '<!-- ngView:  --><div ng-view="" class="container-fluid  ng-scope"><div ng-controller="homeController" class="ng-scope">'+
            '<div class="container bs-docs-container">  '+
            '<div class="row">                '+
                    '<div class="row margin-top">'+
                    '<br>'+
                    '</div>'+
                    '<div class="row margin-top margin-left">'+
                    '<div class="col-sm-12 top-buffer">');
        pwindow.document.write('<div class="well well-lg" style="height: 250vh; background-color:#ADD8E6">'+
         elem.innerHTML + '<br></div> </div></div></div> </div></div></div></body></html>');

        $log.info(pwindow.document);
        //pwindow.print();
        //pwindow.close();

    };

I TRIED multiple ways with elem.innerHTML, elem.value etc but none capture the value of the fields. The form is written and thus printed with empty values although the original form has values. Here is a screen shot. Any ideas why? and thanks! enter image description here

3
  • Um, so all you want to do is make a different layout for printing??? If that's the case, that's not a job for javascript, it's a css job. You can use a media-query, here is a good tutorial: smashingmagazine.com/2011/11/24/…. Or, if you want the user to see the layout of the printed form, launch a separate window with the original form and use a different stylesheet entirely designed for printing (but please don't do this -- it's so 1990s, no user wants to have another tab/window launch). Commented Jun 4, 2015 at 8:49
  • @jme11 thanks for the feedback. Different layout is the job of the Css, that i agree with you, but i want to pass data from the main doc to another one to print. The other document needs to have the form with the data. That copy of the document and the pertaining data is the job of the JavaScript. Commented Jun 4, 2015 at 9:10
  • I'm not trying to give you a hard time, this is meant as a genuine question to help me understand you. The question is tagged AngularJS, so I assume that you have the data in your model. Why would you use document.write to generate a page in Angular versus creating a new partial/template using the current scope values? Commented Jun 4, 2015 at 9:22

2 Answers 2

2

My first comment was a bit rude. I apologize. In my defense, it's early in the morning where I am and I've run out of milk to make more coffee. :-(

I think your approach would be much better if you just:

  1. Created a new route for printing.
  2. Set up a new partial or page template. You can create a service to pass the current form values to the new page via the resolve property on the route.
  3. Your print function in the controller would be as simple as something like: window.open('http://yourbasesite/print/123abc');

This type of approach would be much easier to maintain and test (and you have to admit, it's way prettier).

That said, I wouldn't be surprised if you still had issues with race conditions. Using window.open - window.print - window.close, have no context of Angular. So when you generate the page and let's say it takes a few milliseconds for the page to render fully, the window may already be in its closed state. If you're committed to this approach, you may consider changing the button on your base page to read "Print Preview" and add a separate print button on the pop up window that actually does the window.print - window.close part.

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

Comments

1

New windows with document.write usually end up being quite hacky. One option which comes to my mind is to JSON.stringify the relevant part of your $scope and put it among the things you write out. This would allow you to pass it to the new page. As the page is loaded, it would be interpreted as normal and then inserted into the page and assigned to some variable by you.

In case you're also having troubles getting angular to run at all, you'll probably need to call $compile(mywindow.document)($scope), which should get angular to run on your page again in case it didn't do that already.

Comments

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.