convert angular view to static html - angularjs

I hvae an angular view of a pdf preview that utilizes a controller to fill the view in. I am using pdflayer then to convert the html page into a pdf. The problem however is that no matter how I try and do this the scope variable values never make it into the pdf. I am basically trying to figure out a way to capture the angular view as an html string (data already injected) so that I can pass it to pdflayer. I have tried creating a directive and used replace within the directive then collecting the DOM as a string using .HTML().
For example:
I could like this
<div id="name">{{test.name}}</div>
to become this
<div id="name">Bob Smith</div>
It inevitably however turns into this when i use $('#name').html() and then console log it
<div id="name"></div>
or
<div id="name">{{test.name}}</div>
Any help would be appreciated even if the solution is to use a different method to create the pdf. Ultimately, I need to get a angular view into a formated pdf.

Please check if below library would work for you : https://www.npmjs.com/package/angular-save-html-to-pdf

Related

Angular render markup that is nested

I get JSON like this
{
"lots of":"keys"
"description" : {
"key":"Some sample key",
"value":"This is the markup™"
}
}
from server and I ultimately iterate the description objects and populate table rows with two columns: one for the key and one for the value.
I have tried putting on my <td> tag ng-bind-html as well as injecting $sce into my controller and using trustAsHtml but so far the string always displays as it is in the JSON. Not every value will be HTML but I can easily detect based on the key if HTML is a possibility. It seemed when I put in the directive on the td it did not display anything if no HTML was present. I am interested in using something that can allow HTML in the value but not require it so I can display either
HTML fragment
<tr ng-repeat="(key, val) in record.description">
<td>{{key}}:</td>
<td>{{val}}</td>
</tr>
I created a quick fiddle here:
https://jsfiddle.net/frishi/mvw97s3q/6/
I used angular-sanitize, which I am not sure you mentioned injecting in your module dependency list. Either way, the example works simply by using ng-bind-html
Relevant docs page: https://docs.angularjs.org/api/ng/directive/ngBindHtml
It works by using the directive ng-bind-html on the element you want to display the HTML string in. You use it like so:
<p ng-bind-html="data.firstName"></p>
assuming that data.firstName = "<strong>FeeFee</strong>" or something like that.
I would also like to add that Angular does not allow this natively because of legitimate security concerns. That and the fact that allowing arbitrary HTML to be rendered might not always produce desirable results. Your page layout could quite possibly break because of some HTML you allowed to be passed through.
Angular was designed with security in mind, and will prevent you from displaying HTML from raw strings whenever possible - to prevent various injection attacks.
Here is workarround for your problem: AngularJS: Insert HTML from a string. Generally you should use ng-bind-html insted of ng-bind (this is used by curly braces).

How can I hide a component in AngularJS yet still get an external library to bind to it?

In my code I have something similar to
<div ng-if="variableThatEvaluatesToFalse">
<input id="location">
</div>
What I'm trying to do is hide a component and then show it in response to user input. However, upon my page loading I want Google Maps to attach to my input. Google Maps relies on document.getElementById('location') which is null presumably because AngularJS is 'hiding' it. I can I get document.getElementById('location') to return my input field even if it is initially hidden by the ngIf directive?
The ngIf directive prevents elements from being included in the DOM at all. What you would need in this case is ngHide, which would keep the element in the DOM.
See: https://docs.angularjs.org/api/ng/directive/ngHide

Image not showing in angularjs, mobile

Image not showing in ng-repeat, getting all data from indexeddb and binding to page everything show up expect img in blackberry 10 webworks
<img data-ng-src='{{item.Picture}}' width="100px;" height="100px;"/>
{
id:48758,
Botanical_name:"Cladothamnus pyroliflorus",
Common_name:"Himalayan Cotoneaster ",
Picture: "images/Fplants/Cladothamnus pyroliflorus.png",
},...
This wouldn't seem like an issue with IndexedDB.
For non-Angular directive attributes, such as src you want to interpolate as in the code below:
<img src='{{item.Picture}}' width="100px;" height="100px;"/>
For Angular directive attributes, there's no need for such interpolation:
<img data-ng-src='item.Picture' width="100px;" height="100px;"/>
As your data is going to be undefined on bootstrap, you want to use the latter approach. It prevents the browser from trying to load undefined as an image source.
Also, please note vaibhav's comment above. Without a leading slash, you'll load the images directory as relative to the current. While that may be what you're going for, it's probably going to make your code more reusable to include the leading slash regardless.
Update: If you're in an ng-repeat, note that your scope is not the scope in which the ng-repeat directive appears but it's own, brand new scope. Perhaps try out $parent.item.Picture
I'm having the same problem, it occurs with the image filename having spaces in between , maybe we could write a directive the removes the space from the filename as I'm calling the image via other variable such as title..
app.config(['$routeProvider','$compileProvider',function($routeProvider, $compileProvider){ $compileProvider.imgSrcSanitizationWhitelist('img/');

AngularJS insert invalid HTML

I have an app that requires HTML to be pieced together from different APIs. Rather than getting into specifics there, let me just say that we have tried getting away from that many times but in the end the best answer always end up being what we currently have. Hopefully that changes someday but for now it's working great.
Currently, the HTML is parsed together as a string server-side using NodeJS and sent across the wire as complete HTML to be rendered. I'm in the process of adopting AngularJS, and while I'm loving it I am stuck on this issue-- how can I use Angular templating to insert invalid HTML at times?
The server will return three JSON fields: leadingHTML, trailingHTML, and copy. The copy field is always valid HTML, but leadingHTML and trailingHTML can sometimes return invalid HTML. When all three are added together, valid HTML results.
Let me illustrate:
leadingHTML='<figure>';
copy = '<img src="img1.jpg"/><img src="im2.jpg"/><figcaption>I love AngularJS</figcaption>';
trailingHTML='</figure>';
As you can see, if you add those together you will get the valid HTML that is required to be displayed. It's pretty easy to make the fields trustworthy HTML in Angular:
for (i in data.results){
data.results[i].copy=$sce.trustAsHtml(data.results[i].copy);
data.results[i].leadingHTML =$sce.trustAsHtml(data.results[i].leadingHTML );
data.results[i].trailingHTML =$sce.trustAsHtml(data.results[i].trailingHTML );
}
And then render the copy in my view:
<div ng-repeat='i in data.result'>
<p ng-bind-html='i.copy'></p>
</div>
But I need a way that does what this looks like it would do, but the leadingHTML and trailingHTML scope variables get render as strings:
<div ng-repeat='i in data.result'>
{{ i.leadingHTML }}
<p ng-bind-html='i.copy'></p>
{{ i.trailingHTML }}
</div>
Is the best answer here to build the template via javascript? Would that even work?
Are you able to pre-process your data so that you do have valid HTML?
var item;
for (i in data.results){
item = data.results[i];
item.content = $sce.trustAsHtml(item.leadingHTML + item.copy + item.trailingHTML);
}
Then you can just bind to the combined content in the view:
<div ng-repeat='i in data.results'>
<div ng-bind-html='i.content'></div>
</div>
Edit:
Yes, this will allow you to embed expressions in your HTML content.
In fact, you will need to be careful that you aren't opening yourself up to security exploits in the trusted HTML content (see the example at the bottom of the page for the $sce service).
Using $sce.trustAsHtml in this way is roughly equivalent to loading a directive's templateUrl from your site, so the security considerations around that are probably the same. See the "How does it work?" and
"Impact on loading templates".

AngularJS: Updating a view with a template from a controller?

I have been working with routing and I have seen how I can update the ng-view using routing and a view template.. But the problem I have is that I am doing a REST call and depending what I get back from the response I wish to update part of the DOM with a view template but I don't want to involve routing.
Does anyone know how I can do this? Or any examples would be great
Thanks in advance
Another answer. Based on your description in the comment, it sounds like you wish to display part of the DOM conditionally.
When you want to display part of the DOM conditionally, you have the following choices:
Use an ng-show and ng-hide directive.
Based on what returns from the RESTful call, you can set up a model that will identify the DOM that needs to be displayed. An example:
<div ng-show="status">
This text will be shown only when the status is truthy
</div>
<div ng-hide="status">
This text will be shown only when the status is false.
</div>
Inside your controller, you could then set the status to true or false based on your RESTful calls and based on which part of the DOM you wish to display post RESTful call.
You can use ng-switch directive
While the ng-show and ng-hide directives will display the content of your DOM conditionally, that is anybody could simply open the source file and see the contents for both, ng-switch directive will load the contents only based on which case fulfills the swtich. An example:
<div ng-switch on="status">
<div ng-switch-when="true">
This text will be shown only when the status is truthy.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
<div ng-switch-when="false">
This text will be shown only when the status is false.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
</div>
The first child div is shown when the status is true else it is not shown at all. The advantage over ng-show or ng-hide is that the DOM will not contain the child elements if the case is not fulfilled.
$location.path() can be used here.
So, in your Parent Controller, you can make the REST call. Once you have the data with you, you can then decide which route to take. The route value goes into the path() function.
As an example, let us say that if your REST call returns with cherries, you need to take the /foo path (which, based on your $routeProvider will load the template associated with that route). You can then write the following:
$location.path('/foo');
and it will loads the /foo path - $routeProvider will then take care of loading the template associated with that path.
Reference: $location

Resources