HTML document preserve the new lines and spaces when using innerText - javascript

I am new to webdevelopment. So, Here, I have textAngular. In this I a, showing html document. Now, I want to show the text of the document only but that should be with the formatting as it is in the .html file. So,Right now my code is like -
here data is the html file content, you can say it's a string which has the html file content.Now,
$scope.htmlOriginalDoc = parser.parseFromString(data, 'text/html');
$rootScope.data.htmlDocument = $scope.htmlOriginalDoc.body.innerText;
So, Here when I get this that time I am getting all the data of that file, but when I see it it is like just a text document it is not having any new lines,I mean its not preserving the new line or spaces .So, How can I achieve this ?

Basically you need to compile it from string, then bind it with ngSanitize. To preserve the white space wrap with <pre> tags.
var app = angular.module('myApp', ['ngSanitize']);
app.controller('myCtrl', function($scope, $sce) {
$scope.html = "<div style=\"color:red;font-size:24px;\"> T e s t </div>"; // string
$scope.html = $sce.trustAsHtml($scope.html);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-sanitize.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div style="white-space: pre;"> <!-- instead of <pre> -->
<div ng-bind-html="html"></div>
</div>
</div>

Related

Getting compiled html from template in AngularJS

I must confess that it's not easy to find some basic and easy to understand guide about compiling templates in AngularJS.
Here is the deal:
In my main html-page I have this:
<div>
<div data-ng-include="'./views/testTemplate.html'"></div>
</div>
<div>
<input type=button ng-click="func()" />
</div>
testTemplate.html contains this:
hello {{myname}}
Im my javascript-controller I have this:
$scope.myname = 'max';
Now, when I view the page I see the text "hello max".
Im my javascript-controller I also have this:
$scope.func = function(){
var newScope = $scope.$new();
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
$compile(newElem)(newScope);
console.log('newElem');
console.log(newElem);
});
In the console I can see this:
newElem
<ng-src><div ng-include="'./views/testTemplate.html'" ></div></ng-src>
So, the template is not getting compiled? What am I missing?
***************EDIT***************
The thing is that Im trying to print to console the content of the new element because it needs to be mailed. So I need to send a mail with the compiled content from the template.
Having looked at the answers below, I now have this:
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
var compiledElem = $compile(newElem)(newScope);
console.log('compiledElem[0]');
console.log(compiledElem[0]);
If I use this:
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + compiledElem[0].innerHTML;
then the body of the mail contains this (uncompiled template):
<!-- ngInclude: './views/matching/testTemplate.html' -->
If I use this:
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + compiledElem[0];
then the body of the mail contains this:
[object HTMLElement]
So none of them is showing the html-content in the mail I want to send. I know its not exactly the original question, but it was a part of the issue.
I think the variable 'newElem' is not modified by the $compile command. It has a return value which you should use.
var compiledElement = $compile(newElem)(newScope);
console.log('compiledElement');
console.log(compiledElement);
You are missing adding your HTML to the DOM.
$scope.func = function(){
var newScope = $scope.$new();
var newElem = '<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>';
//Append to DOM
document.querySelector('#some-id').append($compile(newElem)(newScope));
console.log('newElem');
console.log(newElem);
});
In my example I'm using document.querySelector that is raw js. But we can use the $element service, or if we are in a directive's link function, it receives a param representing the current element where the directive is being applied.
EDIT:
If you want to send your compiled HTML in an email, then, you will need to wait until all the $digest finish to compile your template.
$scope.func = function(){
var newScope = $scope.$new();
var newElem = angular.element('<ng-src><div ng-include="\'./views/testTemplate.html\'" ></div></ng-src>');
$compile(newElem)(newScope);
$timeout(function(){
$window.location.href = 'mailto:mailmail.com?subject=sub&body=' + newElem.html();
//console.log('newElem');
//console.log(newElem.html());
});
});
Create your template using angular.element, use $timeout to wait until the end and then use newElem.html();.

$sce.trustAsHtml is not evaluating a javascript string (or trustAsJs For that matter);

My server has a json endpoint that returns a html/js string, looks similar to such:
"\r\n\r\n<div id=\'myEditor\" name=\"myEditor\">\r\n\r\n\t\t\r\n\t</div>\r\n\r\n\r\n\r\n\r\t<script type=\"text/javascript\" src=\"/MyEditor/WebResource.axd?...\:">\r\n\r\n\t<script>\r\n\t..."
I want to inject this with angular into a div, and have it execute the javascript as well.
First attempt:
function myCtrl ($sce) {
$http.get(endpoint).then(function (response) {
$scope.html = response.data;
$scope.editorHtml = $sce.trustAsHtml($scope.html); //also tried trustAsJs
}
}
html:
<div ng-bind-html="editorHtml"></div>
I noticed that if I return a pure html string those tags get rendered, however a pure javascript tags do NOT get evaluated. How do I get it to evaulate these tags? AngularJS version 1.5.8. Thanks!
Your HTML has some syntax problem such id=\'myEditor\". I replaced it with id=\'myEditor\' and so ...
Check this jsfiddle
Add angular.min.js and angular-sanitize.min.js to your project. I used jquery 2.2.4 for this sample.
HTML:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<h2>{{html}}</h2>
<span>{{greeting}}</span>
<div ng-bind-html="editorHtml"></div>
</div>
</div>
JS:
var myApp = angular.module('myApp', ['ngSanitize']);
var data = "\r\n\r\n<div id=\"myEditor\" name=\"myEditor\">\r\n\r\n\t\thi html\r\n\t</div>\r\n\r\n\r\n\r\n\r\t";
var script = "<script type=\"text/javascript\"> alert('hi script');\r\n\r\n\t</" + "script>\r\n\t";
myApp.controller('myCtrl', ['$sce', '$scope' , function($sce, $scope) {
$scope.html = data + script;
$scope.editorHtml = $sce.trustAsHtml($scope.html);
$scope.greeting = 'Hola!';
}]);
You have to include jQuery for this to work. Also don't forget ngSanitize.
Plunker
http://plnkr.co/edit/zEXXCB459Tp25VJiyyZb?p=preview

Decode HTML entity in Angular JS

How do i decode HTML entity in text using angular JS.
I have the string
""12.10 On-Going Submission of ""Made Up"" Samples.""
I need a way to decode this using Angular JS. I found a way to do that using javascript here but I am sure thats wont work for Angular. Need to get back the original string on the UI which would look like
""12.10 On-Going Submission of ""Made Up"" Samples.""
You can use the ng-bind-html directive to display it as an html content with all the html entities decoded. Just make sure to include the ngSanitize dependency in your application.
DEMO
JAVASCRIPT
angular.module('app', ['ngSanitize'])
.controller('Ctrl', function($scope) {
$scope.html = '"12.10 On-Going Submission of ""Made Up"" Samples."';
});
HTML
<body ng-controller="Ctrl">
<div ng-bind-html="html"></div>
</body>
If you don't want to use ngSanitize, you can do it this way:
in your controller:
$scope.html = '"12.10 On-Going Submission of ""Made Up"" Samples."'
$scope.renderHTML = function(html_code)
{
var decoded = angular.element('<textarea />').html(html_code).text();
return $sce.trustAsHtml(decoded);
};
And in the template:
<div ng-bind-html="renderHTML(html)"></div>
Just make sure you inject $sce in your controller
I have similar issue, but don't need to use result value on UI. This issue was resolved by code from angular ngSanitize module:
var hiddenPre=document.createElement("pre");
/**
* decodes all entities into regular string
* #param value
* #returns {string} A string with decoded entities.
*/
function decodeEntities(value) {
if (!value) { return ''; }
hiddenPre.innerHTML = value.replace(/</g,"<");
// innerText depends on styling as it doesn't display hidden elements.
// Therefore, it's better to use textContent not to cause unnecessary reflows.
return hiddenPre.textContent;
}
var encoded = '<p>name</p><p><span style="font-size:xx-small;">ajde</span></p><p><em>da</em></p>';
var decoded = decodeEntities(encoded);
document.getElementById("encoded").innerText=encoded;
document.getElementById("decoded").innerText=decoded;
#encoded {
color: green;
}
#decoded {
color: red;
}
Encoded: <br/>
<div id="encoded">
</div>
<br/>
<br/>
Decoded: <br/>
<div id="decoded">
</div>

Backbone: getting the html code of a view?

In order to write the HTML code of social icons (Twitter, Linkedin, etc) to a textarea so that the user can use that code elsewhere, I would like to get the HTML code of the view element, but I'm having some issues. To help illustrate this better, here is the code that creates the view:
define(function(require, exports, module) {
var _ = require('underscore');
var GridControlView = require('pb/views/grid-control');
var SocialiconsControlDialog = require('pb/views/socialicons-control-dialog');
var template = require('text!pb/templates/socialicons-grid-control.html');
var SocialiconsGridControlView = GridControlView.extend({
template: _.template(template)
,templateVars: {
partials: {
facebook: require('text!pb/templates/socialicons-grid-control-facebook.html')
,twitter: require('text!pb/templates/socialicons-grid-control-twitter.html')
,googleplus: require('text!pb/templates/socialicons-grid-control-googleplus.html')
,pinterest: require('text!pb/templates/socialicons-grid-control-pinterest.html')
,linkedin: require('text!pb/templates/socialicons-grid-control-linkedin.html')
}
}
,control_dialog: SocialiconsControlDialog
});
return SocialiconsGridControlView;
});
And, for example, the Linkedin template looks like this:
<script src="//platform.linkedin.com/in.js?<%- t.cache_buster %>" type="text/javascript">lang: en_US</script>
<script type="IN/Share" data-counter="<%- t.linkedin_option_countmode %>"></script>
What I would like to retrieve, is the parsed template code as text, something such as:
<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">
<script data-counter="top" type="IN/Share+init">
But using something such as:
control_view.render().$el.innerHTML;, control_view.render().$el.html().text() or control_view.render().$el.html().replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, ""); doesn't return text; it returns the full HTML, and produces a Linkedin icon (when I just want the text to be written to a textarea).
Any thoughts?
Update **
I noticed that the code control_view.render().$el is working correctly on other places of the application, and returning HTML code, but for some reason in this view where I'm trying it doesn't. The code seems to break at:
$control = control_view.render().el;
and in the console I get an error which is:
TypeError: t is undefined - underscore-min.js (line 3)
Use the .outerHTML property of the $el.
var html = $('<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">' +
'<script data-counter="top" type="IN/Share+init">');
var text = html[0].outerHTML;
$('textarea').val(text);
jsFiddle

Handlebars Template rendering template as text

I created a helper in Handlebars to help with logic, but my template parses the returned html as text rather than html.
I have a quiz results page that is rendered after the quiz is completed:
<script id="quiz-result" type="text/x-handlebars-template">
{{#each rounds}}
{{round_end_result}}
{{/each}}
<div class="clear"></div>
</script>
For each of the rounds, I use a helper to determine which template to render a round's result:
Handlebars.registerHelper("round_end_result", function() {
if (this.correct) {
var source = '';
if (this.guess == this.correct) {
console.log("correct guess");
var source = $("#round-end-correct").html();
} else {
var source = $("#round-end-wrong").html();
}
var template = Handlebars.compile(source);
var context = this;
var html = template(context);
console.log(html);
return html;
} else {
console.log("tie");
}
});
Here is a template that describes a correct round (let's take say it rendered the #round-end-correct template):
<script id="round-end-correct" type="text/x-handlebars-template">
<div></div>
</script>
Here is what gets rendered:
<div></div>
Not as HTML, but as text. How do I get it to actually render the HTML as HTML, rather than text?
I assume that unescaping in Handlebars works the same as in vanilla Mustache.
In that case use triple mustaches to unescape html, i,e: {{{unescapedhtml}}}, like:
<script id="quiz-result" type="text/x-handlebars-template">
{{#each rounds}}
{{{round_end_result}}}
{{/each}}
<div class="clear"></div>
for ref see:
http://mustache.github.com/mustache.5.html
Geert-Jan's answers is correct but just for reference you can also set the result to "safe" directly inside the helper (code from handlebars.js wiki)
Handlebars.registerHelper('foo', function(text, url) {
text = Handlebars.Utils.escapeExpression(text);
url = Handlebars.Utils.escapeExpression(url);
var result = '' + text + '';
return new Handlebars.SafeString(result);
});
With that you can use regular double handlebars {{ }} and handlebars won't escape your expression.

Categories

Resources