Sae1962 Sae1962 - 1 year ago 117
AngularJS Question

How to make out of an HTML text a DOM object

I have an app where a page generator creates a start page that is saved in the database. The saved information is just the

outerHTML
of the DOM object. To create the edit function, I need an inverse function that recreates the DOM object out of the HTML information. Unfortunately, assigning the decrypted information to the
outerHTML
section results in nothing, as the changes in the DOM object are ignored.

My question: How can I recreate a DOM object out of saved outerHTML information? If this is impossible, what would be the right way to do such a thing?

EDIT
Thank you for your reply! Here are some snippets of code that show what I am doing. The prototype MainWidget is getting information from the HTML page & wants to assign the information. Used functions are part of another object (prototype) called Widgets.

var asserts = new Asserts();
var calls = new Calls();
var constants = new MainConst();
var strings = new Strings();
var widgets = new MainWidget();

MainWidget.method('assign2Widget', function (call, label, value, isValid) {
isValid = toBoolean(isValid), value = strings.toString(value);

if (calls.isValid(call) && strings.hasMinimalLength(label, 2)) {
var section = (!label.includes('Builder') // A marker, not an element!
&& !label.includes(constants.NewsTicker))
? widgets.getSgSectionByLabel(document, label)
: null;
value = strings.decode(decodeURIComponent(value)); //<<<< Code decoded from DB

if (asserts.isObject(section)) {
section.outerHTML = value;
} else if (label.includes(constants.Elements)) {
if (asserts.isValid(infos.Elements) && infos.Elements.length > 0) {
// HERE, THE CODE FROM DB SHOULD BE ADDED TO WIDGET.
// The "label" gives the label of the widget, and the "value" is
// what is to be assigned to.
}
} else if (label.includes(constants.NewsTicker)) {
[…]
}
[…]
});

Widget.method('getElementTypeByLabel', function (thing, elementType, label) {
if (asserts.isObject(thing)
&& strings.hasMinimalLength(elementType, 2)
&& strings.hasMinimalLength(label, 2)) {

var element, elements = document.getElementsByTagName(elementType);

if (asserts.isValid(elements)
&& asserts.isDefined(elements.length) && elements.length === 0) {

elements = thing.children;
}
for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) {
element = elements*;

if (element.getAttribute !== null) {
var labelName = element.getAttribute(constants.label);

if (label === labelName && element !== null) {
return element;
}
} else {
return null;
}
}
// If the element was not found, search recursively the elements!
for (var i = 0; asserts.isDefined(elements.length) && i < elements.length; i++) {
return this.getElementTypeByLabel(elements*, elementType, label);
}
} else {
// Error! //messages.invalidFunctionCall(functionName);
}
return null;
});

Widget.method('getSgSectionByLabel', function (element, label) {
return this.getElementTypeByLabel(element, 'sg-section', label);
});

Answer Source

The solution should be like, you get the a HTML string with the contents. Then you use the $sce.trustAsHtml(); and assign to a scope variable which will ensure the HTML is safe then you can use the HTML below which has the directive ng-bind-html to render the HTML String as actual HTML.

Here is a working example of the same.

var app = angular.module("angularApp", []);
app.controller("appController", function($scope, $sce) {
  $scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here.";
  $scope.output = $sce.trustAsHtml($scope.content);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<h2>Rendering HTML with angularJS</h2>
<div ng-app="angularApp" ng-controller="appController">
  <div ng-bind-html="output"></div>
</div>

Another option is to use ng-sanitize.

If you use ng-sanitize - Inputs are sanitized by parsing the HTML into tokens. All safe tokens (from a whitelist) are then serialized back to properly escaped html string. This means that no unsafe input can make it into the returned string.

Refer the below question for a more detailed explanation.

SO Answer


var app = angular.module("angularApp", ['ngSanitize']);
app.controller("appController", function($scope) {
  $scope.content = "This text is <em>html capable</em> meaning you can have <a href=\"#\">all</a> sorts <b>of</b> html in here.";
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular-sanitize.min.js"></script>
<h2>Rendering HTML with angularJS</h2>
<div ng-app="angularApp" ng-controller="appController">
  <div ng-bind-html="content"></div>
</div>

As seen in the above example there is no need for calling $sce.trustAsHtml(); since ngSanitize will take care of it automatically.

Let me know if this approach help you, or if you face any issues with the same!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download