Does using innerHTML prevent clientside javascript from applying on new html? - javascript

I am using .innerhtml to take information from a form, and re-display a list(of dynamic data that displays in the form of a credit card. See following link for example. https://codepen.io/quinlo/pen/YONMEa) to the DOM. However, when I display that information back to the DOM, my client side Javascript does not seem to apply towards the new elements by re-reading their id's and class's.
Snippit of relevant code
var renderElement = document.querySelector(".cardbox");
const html = '<div class="card-container preload" id="target" >'+
'<div class="creditcardrender">'+
' <div class="front">'+
' <div id="ccsingle"></div>'+ ... etc
renderElement.innerHTML += html;
Is this a property of HTML/Javascript that is unavoidable or is there a work-around this issue?
thanks.

If I understood the question correctly,
Using renderElement.innerHTML += html; is equivalent to renderElement.innerHTML = renderElement.innerHTML + html;, which means its value is a new string resulted from the concatenation of the two strings. So, the existing HTML element will be refactored as if you're assigning it from scratch.
To add the HTML code you're hoping to be present, you can use insertAdjacentHTML() function to add the HTML code to the element without reforming the existing code.
renderElement.insertAdjacentHTML('beforeend', html)

Related

Unable to create Struts2 tags inside JSP script tag

I have some javascript inside the <s:param> tag on a JSP page.
I want to create a struts2 tag given a certain condition is true. Here is what I have:
<s:param name="pageScript">
<script type="text/javascript">
$(document).ready(function() {
if(translateField === "true") {
var declaredValue;
declaredValue= document.createElement("div");
declaredValue.innerHTML = '<s\:textfield label="HELLO" \/>';
} else {
var declaredValue = document.createElement("input");
declaredValue.type = "text";
declaredValue.id = "declaredValueInput";
declaredValue.value = "some value";
}
});
</script>
</s:param>
I followed the comments on this page: Create Struts2 tag inside JavaScript function and I have my JS within a JSP inside a struts tag.
Anyone see what I may be doing wrong, or if there is a better way to go about this?
I am using a textfield as an example, but in the end I want to create a <s:select> tag.
To clarify exactly what I want to do: I am trying to dynamically create a element if a flag is set to true basically. So if the flag is true, create a tag that uses a list in my struts class, otherwise use a plain ol' textfield.
I was using a text field in my example just to see if I can get a struts tag to work.
Quoting the answer you've linked:
JS is executed on the client. JSP tags are evaluated on the server.
It means that, when the Javascript engine of the browser starts to read that piece of Javascript, there's no trace of the Struts tags anymore, because they've been translated into HTML code long before the page has been rendered.
You could inject a Struts tag into JS with the proper syntax, that would be
declaredValue.innerHTML = '<s:textfield label="HELLO" />';
, then you would have the problem that the generated HTML would not be sanitized to be contained in a Javascript String (', ", etc...). But is it what you really need ? Can't you simply store the "HELLO" text, and then build an HTML <input type="text" /> on your own ?
Something like:
var text = '<s:text name="HELLO" />';
or (remember to use escapeJavascript="true" in <s:property /> tags inside JS blocks, or you'll be prone to XSS attacks):
var text = '<s:property value='getText("HELLO")' escapeJavascript="true" />';
and then
var label = '<label for="hello">' + text + '</label>';
var input = '<input type="text" id="hello" />';
declaredValue.innerHTML = label + input;
should get you closer to what you're trying to achieve, I guess.
P.S: innerHTML is fast but is not the proper way to create objects in Javascript.

Reusing HTML code blocks

In one of the page I am working on, I have to reuse a html block of code again and again.
This is a legacy application and the whole html, js code is very old.
The HTML block in question is more than 200 lines of code.
Current approach that I am using is to convert the block in javascript and store the whole block in a variable and then return it
function getItemBlock() {
var strItemBlock="";
strItemBlock += "<div class=\"itemblock newitem\" >";
strItemBlock += "<h5>Item <span class=\"itemnum\"><\/span> <button lass=\"btnDeleteItem btn\">Delete Item<\/button><\/h5>";
strItemBlock += "<div class=\"row\">";
strItemBlock += "<div class=\"col\">";
strItemBlock += "<\/div>";
return strItemBlock;
}
Another approach that I can use is to create whole structure using javascript createElement which would be more hectic and slower in performance.
What options do I have, I am looking for only client side options using javascript.
I usually just create an array like so:
function getItemBlock() {
var strItemBlock=['<div class="itemblock newitem" >',
'<h5>Item <span class="itemnum"><\/span>',
'<button class=\"btnDeleteItem btn\">Delete Item<\/button>',
'<\/h5>',
'<div class=\"row\">',
'<div class=\"col\">',
'<\/div>']
return strItemBlock.join('\n');
}
$('#wrapper').append(getItemBlock());
DEMO
I am going to use the approach the user LaughDonor suggested, here are the comments
#budding_fed The context of your HTML Block changing is independent of the other pages you have. So on the same page, if you're using the same block, then using document.createElement() and element.cloneNode() would be the fastest. Generating the code to create the element is up to you and the page it's on. There's so many JSPerf links out there, here's another. – LaughDonor 20 mins ago
If it is easier for you to make it as a string, go ahead transform it into a DOM element once, and then clone it however many times you need for the rest of that page. – LaughDonor 18 mins ago

appended html to the dom doesn't respect the charset

I have some HTML rendered by ajax, which works perfectly fine using the char-set utf-8 nevertheless some content it's appended to the dom by a JavaScript function using jquery. The problem is, the HTML rendered doesn't have the correct char-set.
Here's the example of the content added by JavaScript
var html = '<div class="right-item-container"><span style="font-size:24px;" class="item-friend-name">Mamá</span><br/><span class="clubName-container">school</span></div>';
$('.profile-container').empty().css({ 'padding-top' : '0'}).html(html);
It renders like this:
This works fine in a fiddle.
http://jsfiddle.net/HjCpp/
var html = '<div class="right-item-container"><span style="font-size:24px;" class="item-friend-name">Mamá</span><br/><span class="clubName-container">school</span></div>';
$('#test').html(html);
So it must be the way your original content is encoded.

string search in body.html() not working

Hi here is my total work to search a string in HTML and highlight it if it is found in document:
The problem is here
var SearchItems = text.split(/\r\n|\r|\n/);
var replaced = body.html();
for(var i=0;i<SearchItems.length;i++)
{
var tempRep= '<span class="highlight" style="background-color: yellow">';
tempRep = tempRep + SearchItems[i];
tempRep = tempRep + '</span>';
replaced = replaced.replace(SearchItems[i],tempRep); // It is trying to match along with html tags...
// As the <b> tags will not be there in search text, it is not matching...
}
$("body").html(replaced);
The HTML I'm using is as follows;
<div>
The clipboardData object is reserved for editing actions performed through the Edit menu, shortcut menus, and shortcut keys. It transfers information using the system clipboard, and retains it until data from the next editing operation replace s it. This form of data transfer is particularly suited to multiple pastes of the same data.
<br><br>
This object is available in script as of <b>Microsoft Internet Explorer 5.</b>
</div>
<div class='b'></div>
If I search for a page which is pure or without any html tags it will match. However, if I have any tags in HTML this will not work.. Because I am taking body html() text as the target text. It is exactly trying to match along with html tags..
In fiddle second paragraph will not match.
First of all, to ignore the HTML tags of the element to look within, use the .text() method.
Secondly, in your fiddle, it wasn't working because you weren't calling the SearchQueue function on load.
Try this amended fiddle

Use getElementById() on non-current HTML document

Essentially, I want to pull text within a div tag from a document on my server to place it in the current document. To explain the reason: I want to pull a headline from a "news article" to use it as the text for a link to that article.
For example, within the target HTML is the tag:
<div id='news-header'>Big Day in Wonderland</div>
So in my current document I want to use javascript to set the text within my anchor tags to that headline, i.e.:
<a href='index.php?link=to_page'>Big Day in Wonderland</a>
I'm having trouble figuring out how to access the non-current document in JS.
Thanks in advance for your help.
ADDED: Firefox style issue (see comment below).
I'm not sure where you're getting your HTML but, assuming you already have it in a string, you could create a document of your own, stuff your HTML into it, and then use the standard getElementById to pull out the piece you want. For example:
var doc = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
doc.documentElement.innerHTML = '<body><div>Nonsense</div><div id="news-header">Big Day in Wonderland</div><p>pancakes</p></body>';
var h = doc.getElementById('news-header');
// And now use `h` like any other DOM object.
Live version: http://jsfiddle.net/ambiguous/ZZq2z/1/
Normally, I would try to solve an issue only with the tools specified by the user; but if you are using javascript, there really is no good reason not to just use jQuery.
<a id='mylink' href='url_of_new_article' linked_div='id_of_title'></a>
$(function() {
var a = $('#mylink');
a.load(a.attr('href') + ' #' + a.attr('linked_div'));
});
That little function up there can help you update all your link's text dynamically. If you have more than one, you can just put it in a $('a').each() loop and call it a day.
update to support multiple links on condition:
$(function() {
$('a[linked_div]').each(function() {
var a = $(this);
a.load(a.attr('href') + ' #' + a.attr('linked_div'));
});
});
The selector makes sure that only the links with the existence of the attribute 'linked_div' will be processed.
You need to pull the content of the remote document into the current DOM, as QuentinUK mentioned. I'd recommend something like jQuery's .load() method

Categories