Dynamic html with angular bindings not working - javascript

I have a simple javascript code that dynamically adds HTML content to a div tag.
function addData(id,title,title_data){
var htmlcode='';
htmlcode+=`<h1> Title: `+title+` </h1> <div ng-app="">
<input ng-model="model`+title+id`" ng-init="model`+title+id+'='+\'`+title_data+`\'`" >`+
`<p ng-bind="model`+title+id`"> </p>`;
return htmlcode;
}
Then i simply use it like this:
$('#someDiv').html(addData(1,'Some Title','Some title data'));
The html works well and displays the desired dynamic content. But the angular bindings didn't work. The copy pasted version of the rendered html from web browser works well including the bindings but the dynamic one does not. What seems to be the problem?

You are not using the ng-app name in the declared dynamic html code.

Related

json & JavaScript replacing html h1 heading?

When I reload my browser to show some json data the JavaScript code keeps replacing my HTML code? How can I correct the problem?
JavaScript code:
$.getJSON('https://jsonplaceholder.typicode.com/posts/1', function, data) {
document.write(data.title);
};
HTML Code:
<div class="container">
<div id="json_example">
<h1>json Example</h1>
</div>
</div>
Don't use document.write() as it replaces fully built HTML documents with the new content. document.write() should only ever be used to construct dynamic pages while the page is being built.
Instead, just populate some pre-existing element with data.title,
As in:
$.getJSON('https://jsonplaceholder.typicode.com/posts/1', function, data) {
$("#output").text(data.title);
};
<div class="container">
<div id="json_example">
<h1>json Example</h1>
<span id="output"></span>
</div>
</div>
You are using document.write() which takes your document, and replaces it's content with the content you supply to the function. If you want to replace just the content of the <div id="json_example"></div> element, then you can use the following snippet in place of the document.write():
$("#json_example").text(data.title);
For non jQuery-version:
document.querySelector("#json_example").innerText = data.title;
If you want to replace the content of the <h1> the correct selector would be #json_example h1 instead.
In all the snippets what you do is find the element you want to change the content of using a CSS-selector. Both jQuery and pure Javascript supports this since IE8.
After finding the correct element, you set the elements content text to the content you want.
NOTE! Do NOT use innerHtml or .html() to set the content, as that opens you to script injections. Only use those methods when you generate the HTML yourself on the fly, in the browser. Even your database needs to be considered dirty.
try this
$.getJSON('https://jsonplaceholder.typicode.com/posts/1', function, data) {
document.getElementById("json_example").textContent = data.title;
};
Since you're already using jQuery here's a possible solution which uses it.
$.getJSON('https://jsonplaceholder.typicode.com/posts/1', function, data) {
$("#json_example").html("<h1>" + data.title + "</h1>");
};
This replaces your div html with your content.

Displaying text with '<b>' tags as html

How do I display my string that is: <b>test</b> as: test in my html page?
I'm getting the string from my database, which was created with a wysiwyg editor.
I've tried using razor syntax:
#Html.Encode(Model.teststring);
But this doesn't work.
I've also tried using javascript, which didn't work either:
<div id="#Model.ID">
<script type="text/javascript">
$('##Model.ID').html(Model.teststring);
</script>
</div>
Both show the text as follows: <b>test</b>
Is there a way to fix my problem?
You need to place it within the Html.Raw() like below
#Html.Raw(Model.teststring)
This method wraps HTML markup using the IHtmlString class, which renders unencoded HTML. You can find out more about it here
There are two problems in your ID-naming:
Don't use the #-character and
Don't use the dot-character (.)
This seems to work well:
var Model = {
teststring: '<b>test</b>'
};
$('#ModelID').html(Model.teststring);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="ModelID">
</div>

Html tags not rendering inside div (ckeditor)

I'm using ckeditor to get what user has inputed in the textarea , but when I want to show/render that field in my page it just shows the html tags not the rendered one !
It's odd cause even tags aren't escaped and everything looks like a pure html syntax which is just not rendered !
what is stored in mongodb is this :
"longDesc" : "<p style=\"text-align: left;\">We need creation of <strong>7 animated banners</strong>.</p>\n\n<p style=\"text-align: left;\">We need to remake to dynamic form. We provide you open source data and technical specifications.</p>\n"
and am using angularjs double brace in view to show this expression .
{{job.longDesc}}
and the output exactly is :
<p style=\"text-align: left;\">We need creation of <strong>7 animated banners</strong>.</p>\n\n<p style=\"text-align: left;\">We need to remake to dynamic form. We provide you open source data and technical specifications.</p>\n
Take a look at ngBindHtml. You just need to:
$scope.myHTML = '<p>test</p>';
....
<div ng-controller="ExampleController">
<p ng-bind-html="myHTML"></p>
</div>
You will need to include the ngSanitize in your app dependency to make the ng-bind-html work. Here is an Plunker example:
http://plnkr.co/edit/RRNyiwQAaHQfNqtHslCD?p=preview

updating div with jQuery and Knockout.js with .html() not working

This should be a simple matter of updating some simple modal controls with .html() but for some reason, I'm having issues. This is the modal code...
<div id="answerTaskQuestionModal" class=" modal-dialog" data-bind="with: currentQuestion">
<div id="answerTaskQuestionValidation" class="validation"></div>
<span data-bind="text: html"></span>
<div id="taskQuestionAnswer"></div>
</div>
And here is the JavaScript inside my working view model...
self.answerTaskQuestion = function (question) {
$('#answerTaskQuestionValidation').html('');
var $taskQuestionAnswer = $('#taskQuestionAnswer');
$taskQuestionAnswer.html(' \* {my html with bindings} *\ ');
$answerTaskQuestionModal.dialog('open');
self.currentQuestion(question);
};
Basically, I'm trying to dynamically change the ways one can answer a question as a proof of concept. If I just paste the html inside the target div, they work. However, when I check the value of .html(), this is what happens...
first run: $taskQuestionAnswer.html() returns undefined
second run: $taskQuestionAnswer.html() returns the proper HTML but the div won't update.
Replacing the bindings with just simple HTML doesn't help either. What am I missing here?
I think after $taskQuestionAnswer.html(' \* {my html with bindings} *\ ');
you should call ko.applyBindings(myViewModel) again to apply view model to new html.

best way to inject html using javascript

I'm hoping that this isn't too subjective. I feel there is a definitive answer so here goes.
I want to create this html on the fly using JS (no libraries):
Play
Mute
<div id="progressBarOuter">
<div id="bytesLoaded"></div>
<div id="progressBar"></div>
</div>
<div id="currentTime">0:00</div>
<div id="totalTime">0:00</div>
using javascript. I know I can do this using createElement etc but it seems extremely long winded to do this for each element. Can anyone suggest a way to do this with more brevity.
I do not have access to a library in this project....so no jquery etc.
Keep your markup separate from your code:
You can embed the HTML snippets that you'll be using as hidden templates inside your HTML page and clone them on demand:
<style type="text/css">
#templates { display: none }
</style>
...
<script type="text/javascript">
var node = document.getElementById("tmp_audio").cloneNode(true);
node.id = ""; // Don't forget :)
// modify node contents with DOM manipulation
container.appendChild(node);
</script>
...
<div id="templates">
<div id="tmp_audio">
Play
Mute
<div class="progressBarOuter">
<div class="bytesLoaded"></div>
<div class="progressBar"></div>
</div>
<div class="currentTime">0:00</div>
<div class="totalTime">0:00</div>
</div>
</div>
Update: Note that I've converted the id attributes in the template to class attributes. This is to avoid having multiple elements on your page with the same ids. You probably don't even need the classes. You can access elements with:
node.getElementsByTagName("div")[4].innerHTML =
format(data.currentTime);
Alternatively, you can act on the HTML of the template:
<script type="text/javascript">
var tmp = document.getElementById("tmp_audio").innerHTML;
// modify template HTML with token replacement
container.innerHTML += tmp;
</script>
Shove the entire thing into a JS variable:
var html = 'Play';
html += 'Mute';
html += '<div id="progressBarOuter"><div id="bytesLoaded"></div><div id="progressBar"></div></div>';
html += '<div id="currentTime">0:00</div>';
html += '<div id="totalTime">0:00</div>';
Then:
document.getElementById("parentElement").innerHTML = html;
if you want theN:
document.getElementById("totalTime").innerHTML = "5:00";
You can use
<script type="text/javascript">
function appendHTML() {
var wrapper = document.createElement("div");
wrapper.innerHTML = '\
Play\
Mute\
<div id="progressBarOuter"> \
<div id="bytesLoaded"></div>\
<div id="progressBar"></div>\
</div>\
<div id="currentTime">0:00</div>\
<div id="totalTime">0:00</div>\
';
document.body.appendChild(wrapper);
}
</script>
If you live in 2019 and beyond read here.
With JavaScript es6 you can use string literals to create templates.
create a function that returns a string/template literal
function videoPlayerTemplate(data) {
return `
<h1>${data.header}</h1>
<p>${data.subheader}</p>
Play
Mute
<div id="progressBarOuter">
<div id="bytesLoaded"></div>
<div id="progressBar"></div>
</div>
<time id="currentTime">0:00</time>
<time id="totalTime">0:00</time>
`
}
Create a JSON object containing the data you want to display
var data = {
header: 'My video player',
subheader: 'Version 2 coming soon'
}
add that to whatever element you like
const videoplayer = videoPlayerTemplate(data);
document.getElementById('myRandomElement').insertAdjacentHTML("afterbegin", videoplayer);
You can read more about string literals here
edit: HTML import is now deprecated.
Now with Web Components you can inject HTML using an HTML import.
The syntax looks like this:
<link rel="import" href="component.html" >
This will just load the content of the html file in the href attribute inline in the order it appears. You can any valid html in the loaded file, so you can even load other scripts if you want.
To inject that from JavaScript you could do something of the likes of:
var importTag = document.createElement('link');
importTag.setAttribute('rel', 'import');
importTag.setAttribute('href', 'component.html');
document.body.appendChild(importTag);
At the time I am writing this, Chrome and Opera support HTML imports. You can see an up to date compatibility table here http://caniuse.com/#feat=imports
But don't worry about browsers not supporting it, you can use it in them anyway with the webcomponentsjs polyfill.
For more info about HTML imports check http://webcomponents.org/articles/introduction-to-html-imports/
If you don't need any validation for your syntax (which is what makes createElement() so nice) then you could always default to simply setting the innerHTML property of the element you want to insert your markup inside of.
Personally, I would stick with using createElement(). It is more verbose but there are far less things to worry about that way.
If performance is a concern, stay away from innerHTML. You should create the whole object tree using document.createElement() as many times as needed, including for nested elements.
Finally, append it to the document with one statement, not many statements.
In my informal testing over the years, this will give you the best performance (some browsers may differ).
If HTML is ever declared in a variable, it should be simple and for a very specific purpose. Usually, this is not the right approach.
here's 2 possible cases :
Your HTML is static
Your HTML is dynamic
solution 1
In this case, wrap your HTML in double quotes, make it a string and save it in a variable. then push it inside HTML, here's a demo 👇
HTML
<div id="test"></div>
JavaScript
let selector = document.querySelector("#test");
let demo_1 = "<div id='child'> hello and welcome</div>"
selector.innerHTML = demo_1;
solution 2
In this case, wrap your HTML in back ticks, make it a template literal and save it in a variable. then push it inside HTML,
here, you can use variables to change your content. here's a demo 👇
HTML
<div id="test"></div>
JavaScript
let selector = document.querySelector("#test");
let changes = 'hello and welcome'
let demo_1 = `<div id='child'>${changes}</div>`
selector.innerHTML = demo_1;
You can concatenate raw HTML strings (being careful to escape text and prevent XSS holes), or you can rewrite jQuery (or something similar)
I have a situation where I pass text into a third party library, but if my model isPrivate, I'd like to add an element to the text.
return { id: item.id, text: (item.isPrivate == true) ? "<i class=\"icon-lock\" title=\"Private group.\"></i> " + item.label : item.label };
This creates issues with the way the third party library builds up its markup.
This is never a good idea, but third party libraries are there so that we don't have to write everything ourselves. In a situation like this, you have to rely on passing markup though javascript.
When i find a proper solution to this, I will give you an update

Categories

Resources