Javascript read HTML tags - javascript

I have a problem and I don't know how to fix it after sometime now, I really need help
So I have asp:GridView, in my DB i am saving text (In English column) with HTML tags, on DataBound event I am using Context.Server.HtmlDecode(encoded); so it is displayed perfectly
But problem is, that also on that event, I am creating OnClick event for that cell ... calling javascript function, and sending parameters to it, it looks like this
ChangeTranslationText('English',
'<div style="text-align: center;"><span style="font-style:italic;">Stavi dole
</span><span style="font-weight: bold;">neki text<br><br><br>Hvala na paznji!
<br><br>Mozes Z da stavis<br><br>Ali Z<br><br>Hvala<br></span></div> '
,'56');return false;
Now in function I am trying that my javascript read that HTML and format my text as it looks like in GridView ...
function ChangeTranslationText(Language, Text, Control) {
document.getElementById("MainContent_txtChangeLanguage").value = Language;
var el = $('<div></div>');
el.html(Text);
document.getElementById("MainContent_txtTranslationText").innerHTML = el.text();
document.getElementById("MainContent_hfControl").value = Control;
$('#ModalChangeTranslate_Fade').modal('show');
}
And I can't format it as I don't know how ... this is best I got so far
Can you help me and advice me how can Javascript read that HTML and keep format like it is in GridView cell?

I made a test here and saw two things:
var el = $('<div></div>'); was throwing $ is not defined. You probably have jquery library in your project, but you actually dont need to declare this el variable. You can use it like you did before:
document.getElementById("MainContent_txtTranslationText").innerHTML = Text;
Another thing was your Text parameter. Not sure if the line breaks is only in the question, but, when we have a string in javascript, it must be on the same line. You can't break lines with "enter". You will need to concatenate the strings to do that, like this:
var html = '<div style="text-align: center;"><span style="font-style:italic;">Stavi dole' +
'</span><span style="font-weight: bold;">neki text<br><br><br>Hvala na paznji!' +
'<br><br>Mozes Z da stavis<br><br>Ali Z<br><br>Hvala<br></span></div>';

Related

concatenate a variable to a html string in javaScript

Please be gentle with me, it is my first time uploading a question to stack overflow, and since I am rather new in programming I might be a bit vague in the terms.
My problem is that I have a function that places some markers on a map, this happens automatically when I load the site, these markers are different and contain different "trophies", that I have placed in a pop-up locked to the marker. However I want the program to be able to collect the trophies, therefore I would like to call a function with the specific trophy as my parameter in my javaScript file when I click a button in my pop up. HTML.
So far it looks like this:
function createMarker(coords, trophy) {
var id
// check if array is empty and set id to 0 if it is
if (markers.length < 1) id = 0
// else make id based on array length
else id = markers[markers.length - 1]._id + 1
// custom popup content with HTML that can be styled
var popupContent =
'<div id= "divTrophy">'+
'<img src=' + trophy +'></img>' +
'<button onClick="trophyCollection('+trophy+')">Collect trophy</button>'+
'<button onclick="closePopUp()">Close pop up</button>'+
'</div>'
'<button onClick="trophyCollection('+trophy+')">Collect trophy</button>'+
The problem is in this line where I am for some reason not allowed to concat this way, which confuses me because it works fine in the line above in the <img>.
I really hope someone can help me, create my little treasure hunt around DK.
Try using string interpolation. Something like this.
`your_html_string ${your_dynamic_value} your_html_string`
You can find more info on interpolation here.
How to interpolate variables in strings in JavaScript, without concatenation?
Try escaping them it should work, example
'<button onClick="trophyCollection(\''+trophy+'\')">Collect trophy</button>'+
You can insert your entire HTML inside of a backtick string and interpolate values like this:
let popupContent =
`<div id= "divTrophy">
<img src=${trophy}></img>
<button onClick="trophyCollection(${trophy})">Collect trophy</button>
<button onclick="closePopUp()">Close pop up</button>
</div>`
As suggested you can try template literals:
var popupContent = `<div id="divTrophy">
<img src="${trophy}"/>
<button onClick="trophyCollection('${trophy}')">Collect trophy</button>
<button onclick="closePopUp()">Close pop up</button>
</div>`
Do note that as trophy is a string you still need to wrap it in quotes.

I have two separate functions one collects form text the other toggles display of an image. I'm unable to pull values from the other variable

Note: I'm not a javascript expert so please be kind. I continue to get a Null value from a variable that I believe is triggered from a DOM event. I have two functions. One looks at form text whether it is present, if not it pulls from another existing variable so it should never be empty/null. However when I try to pull these variable results into another function it returns Null. I'm trying to have a form where the user enters a filename (picture name) and the script inserts the rest of the string around this filename. Allowing the user to not have to enter a full url path and especially not html code. This works if I put the variables in manually as text strings, I'm just not able to get anything other than null from that variable inside this function.
I thought this was due possibly to the DOM event but I tried everything I could find on here with no success. I even tried making the variable global which didn't help. I'm trying to concatenate text before and after this other variable data. If I put these other variables in as string text it works fine, but whenever I try to pull the other variable outside of the function I get Null. I've mascaraed my java at this point. I've been coming back to this the past few days trying different thing with no success. Thank you.
// This checks for radio toggle and writes html(var string) if on
function output_headshot() {
var text1 = "<td border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><br><img src=\"https://url/Headshots/";
var text2 = headshot_path;
var text3 = "\" width=\"154\" height=\"154\"></td>";
var headshot_html = text1 + text2 + text3;
$(".headshot_element").show();
$(".headshot_element").html(headshot_html);
// Monitor logo option to hide/show
$(".input_headshot input[type=radio]").on("change", function(){
if(document.getElementById('headshot_show').checked) {
$(".headshot_element").show();
$(".headshot_element").html(wpe_headshot_html);
} else if(document.getElementById('headshot_hide').checked) {
$(".headshot_element").hide();
$(".headshot_element").html('');
}
updateHtmlSigRaw()
});
}
output_headshot();
// This looks at form contents, if empty pulls from another static variable employee.headshot_location
// This will display the text string on HTML using this: <span class="output_headshot_location"></span>
$(".input_headshot_location input").on("change keyup paste", function(){
var headshot_location = $(this).val();
if(headshot_location) {
$("span.output_headshot_location").html(headshot_location)
} else {
$("span.output_headshot_location").html(employee.headshot_location);
}
updateHtmlSigRaw()
});
EDIT: Added for context
// Place raw HTML of each version into appropriate containers
function updateHtmlSigRaw() {
get_html_signature_full_visual = document.getElementById("signature-full-visual").innerHTML;
get_html_signature_horizontal_visual = document.getElementById("signature-horizontal-visual").innerHTML;
$("#signature-full-html textarea").text(get_html_signature_full_visual);
$("#signature-horizontal-html textarea").text(get_html_signature_horizontal_visual);
}
This is starting normal variables.
// Start Normal variables
var employee = {
headshot_location: "TimC-Rounded-SQ-SM.png"
}
The following is how I'm placing in HTML for the image to toggle off an on.
<td height="237" valign="middle" style="padding:0px 10px 0px 0;">
<div class="headshot_element" onClick="document.location = 'https://url'" border="0" cellpadding="0" cellspacing="0" >
Next is the form for input.
<div class="input_headshot_location form-group">
<label>Headshot Location</label>
<input class="form-control" type="text" name="headshot_location" placeholder="Enter Full Filename">
</div>
Expecting to pull string from variable to add/concatenate to other static string variables to insert html into page using Span class or Div class.

the reason why Conflict between plugin and javascript function occured

Few days ago I had to write code quickly and added the bad code below.
<td class="note_box_con" onclick="getElementsByTagName('a')[0].click();">
After then, when I tried to use Text editor plugin written by Javascript, I found
Text editor plugin and the function of DOM collide into each other
Now I know what was the problem and solve it. But I cannot understand what kind of risk getElementsByTagName('a')[0].click(); has.
In my incomplete view, that code is just addEventlistener function().....
what kind of risk onclick="getElementsByTagName('a')[0].click();" has?
In my understanding, its a bad practice to do it this way. I would rather suggest you to use to fetch using classname or id.
If you are using some resource that adds anchor tags to your page, this will break your logic.
Following is a simulation:
var count = 0;
function addAnchor(){
var div = document.getElementById("content");
var str = "<a href='#'>" + count++ + "</a>";
div.innerHTML = str + div.innerHTML;
}
document.getElementsByTagName("a")[0].addEventListener("click", function(){
console.log(this.innerHTML);
return false;
})
<div id="content">
Test
</div>
<button onclick="addAnchor()">Add Link</button>
<a onclick="document.getElementsByTagName('a')[0].click()"> test </a>
Also, if there is a change in DOM structure, your code will not work properly. Best use a proper selector that uniquely identifies the element.

How to create a list with formatted items using DOM instead on HTML concatenation?

Please forgive me and let me know if my post is not right since I am brand new to this forum.
I have found most of the answer here (Create a <ul> and fill it based on a passed array), but my problem comes with .createTextNode. My users are using multiple editor boxes to build an outline. Within these boxes they can format the text (underline, color, bold, etc.). So the array items that I am passing to .createTextNode actually have HTML tags in them to format the line items. However .createTextNode makes it just plain text which in turn just spits out the tag instead of applying it when displayed via document.getElementById('foo').appendChild...
I know that I should stay away from HTML concatenation but it is looking very tempting.
Is there any way to retain the formatting of the list items when appended and displayed?
Thank you in advance for your assistance.
Try innerHTML, which will try to parse the content string as HTML structure. For example you have a P tag
<p id="asdf"></p>
<script>
document.getElementById('asdf').innerHTML = 'qwerty';
</script>
Will give you a clickable anchor
<p id="asdf">
qwerty
</p>
But be careful!!! (Notice I use three bang sign here) You must be sure there's no harmful code before you insert it. Check this example:
document.getElementById('asdf').innerHTML = '<img src="image.png" onload="alert(1)">'
You will see an alert dialog. This example is simple though, in practice it can be much more dangerous, e.g. dynamically append a cross site script into you page, aka XSS.
EDIT: here is a demo.
var options = ['Option 1','Option 2'];
function makeUL(){
var LIs = '';
for (i = 0; i < options.length; i += 1){
LIs += '<li>' + options[i] + '</li>';
}
return '<ul>' + LIs + '</ul>';
}
document.getElementById('foo').innerHTML = makeUL();
<div id="foo"></div>

How do I dynamically append a large block of HTML to a div?

I'm trying to learn web development, so I don't have much experience with the various languages and markups yet. I'm making a website with a blog that reads JSON data from the Tumblr v2 API. After getting the JSON data from Tumblr I want to add some of the data from each post to my own website's blog, here's the code that I've been trying to use..
<script>
function loadBlogPosts(){
$.getJSON("http://api.tumblr.com/v2/blog/[MY_BLOG]/info?api_key=[MY_KEY]",
function(blogData){
$.each(blogData.posts, function(){
$(#main_content).append( [BUNCH OF NESTED HTML] );
});
}
);
}
</script>
Before writing this, I thought it would be a good idea to make a 'layout' of each blog post in divs. So i came up with this:
<div class="post">
<div class="post_header">
<div class="post_title"></div>
<div class="post_author"></div>
<div class="post_date"></div>
</div>
<div class="post_content"></div>
<div class="post_footer"></div>
</div>
But that's where I'm stuck. I know what I want to do, but I don't have enough experience with JavaScript/JQuery/JSON/HTML to know how to do it. I want parse the JSON blog data and, for each post, take the post content and apply it to that div structure while writing/appending it to the "main_content" div.. I tried copy-pasting that group of divs into the append function surrounded by quotes, but it became a real mess of quotes and slashes, and it didn't look like it was working correctly..
So, whats the best way for me to do that? Is there a good way of applying a big chunk of nested HTML elements while populating them with content from my JSON data? If not, what should I do? I'm still very new to HTML, JavaScript, and web coding in general, so I may be going about this completely wrong!
If you want HIGH PERFORMANCE:
In pure javascript the highest performing method is probably using createDocumentFragment()
function postEl(json){ // create a function for the POST element
var post=document.createElement('div');
post.className='post';
var postHeader=document.createElement('div');
postHeader.className='post_header';
var postTitle=document.createElement('div');
postTitle.className='post_title';
postTitle.tectContent=json.title;
//more code
postHeader.appendChild(postTitle);
//more code
post.appendChild(postHeader);
return post;
}
function appendPosts(){ // append each post to a fragment. and then to the main
var frag=document.createDocumentFragment();
for(/*each post*/){
frag.appendChild(postEl(/*jsonPost*/));
}
document.getElementById('main_content').appendChild(frag);
}
Precreating the structure should also increase the performance.
cloneNode
https://developer.mozilla.org/en-US/docs/Web/API/Node.cloneNode
https://developer.mozilla.org/en-US/docs/Web/API/document.createDocumentFragment
cloning the node also increases the performance by setting the valuse directly without recreating each individual node.
function appendPosts(js){
var node=document.createElemtnt('div'),
frag=document.createDocumentFragment();
node.innerHTML='<div class="post_header"><div class="post_title"></div><div class="post_author"></div><div class="post_date"></div></div><div class="post_content"></div><div class="post_footer"></div>';
for(var a=0,b;b=js.posts[a];++a){
var newNode=node.cloneNode(true),
childs=newNode.childNodes,
header=childs[0].childNodes;
header[0].textContent=b.title/*title from Postdata*/;
header[1].textContent=b.author/*author from Postdata*/;
header[2].textContent=b.date/*date from Postdata*/;
childs[1].textContent=b.content/*content from Postdata*/;
childs[2].textContent=b.footer/*footer from Postdata*/;
frag.appendChild(newNode);
}
document.getElementById('main_content').appendChild(frag);
}
function loadBlogPosts(){
$.getJSON("http://api.tumblr.com/v2/blog/[MY_BLOG]/info?api_key=[MY_KEY]",
appendPosts
)
This function should work now .. but as i don't exactly know the json response you may need to change the various post keys.
note: i put the fragment thing in a function so you have an idea how it works.
you should put the postEl content inside the appendPosts function... (thats also faster)
if you have any questions just ask.
EDIT
no they are not globals
var a,b,c,d; // not globals == var a;var b;var c;var d;
var a,b;c;d; // c d = gobal
// , comma affter a var allows you to not write 1000 times var.
EDIT2
//.......
frag.appendChild(newNode);
}
var topNode=document.createElement('div');
topNode.className='post';
topNode.appendChild(frag);
document.getElementById('main_content').appendChild(topNode);
//.....
when you want to do everything with jquery yoiu could use something like this:
var post = $('<div class="post"></div>');
var postheader = $('<div class="post_header"></div>');
postheader.append('<div class="post_title"></div>');
postheader.append('<div class="post_author"></div>');
post.append(postheader);
post.append('<div class="post_content"></div>');
post.find('.post_title').text('my title');
post.find('.post_content').text('my content');
$('#main_content').append(post);
instead of .text('my title') you can use .text(variable) of course
Write your code in a separate page, then append a whole html page into a div by using:
$('#containerDiv').load('page.htm');
Also, this is a good way to fragment the content.
you could do something like this:
$.each(blogData.posts, function(i,v){
var cnt= '<div class="post">' +
'<div class="post_header">' +
'<div class="post_title">'+ blogData.posts[i].title +'</div>' +
'<div class="post_author">'+ blogData.posts[i].author +'</div>' +
'<div class="post_date">'+ blogData.posts[i].date +'</div>' +
'</div>' +
'<div class="post_content">' +
blogData.posts[i].body +
'</div>' +
'<div class="post_footer">' +
'</div>' +
'</div>';
$('#main_content').append(cnt);
});
Note that you don't need to split up all the lines, i've just done that to make it more readable. (I'm also not sure if all the variables are correct, (i don't think author exists) but it's just as a demo)

Categories

Resources