Reusing HTML code blocks - javascript

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

Related

Add complexe Javascript array elements to HTML [duplicate]

I have a template:
function useIt() {
var content = document.querySelector('template').content;
// Update something in the template DOM.
var span = content.querySelector('span');
span.textContent = parseInt(span.textContent) + 1;
document.querySelector('#container').appendChild(
document.importNode(content, true));
}
<button onclick="useIt()">Use me</button>
<div id="container"></div>
<template>
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</template>
You can try the code here.
This code basically copies the template(html5 templates does not render on your screen) into another div. This allows you to reuse the DOM.
Problem: The line "span.textContent = parseInt(span.textContent) + 1;" changes the template code directly. I need to manipulate the content DOM and clone it into the container, without changing the template. This is very important since if I want to reuse the code, I need it to stay the same.
I have tried multiple ways to use jQuery to mimic the above javascript code, but I can't manage to figure it out. It would be better if there is a jQuery way.
If you NEED to use the new <template> tag, then you are mildly stuck . . . your cleanest alternative is to use importNode to bring in the content and then modify it after it's been appended.
Assuming that the templated code is realtively small, this should happen fast enough that you would never notice the difference in approach, though, in this specific example, the alert(), would delay the change of the content, so you would see "0", until you clicked "Okay", and then it would update to "1".
The code change for that would be:
function useIt() {
var content = document.querySelector('template').content;
var targetContainer = document.querySelector('#container');
targetContainer.appendChild(document.importNode(content, true));
var $span = $(targetContainer).find("div:last-of-type").find("span");
$span.text(parseInt($span.text() + 1));
}
If you are not married to the idea of <templates>, you could use jQuery's clone() method to do what you want to do, very easily . . . but, clone does not "see" the content of a <template>, due to the special nature of that particular element, so you would have to store the templated code some other way (JS variable, hidden div, etc.).
HOWEVER, this method will not work if you need to clone a script, the way that a <template> will. It will not trigger any script code in the "template container" element when the cloned version is created or appended. Additionally, if you store it in a hidden <div>, any script code in the "template container" element will trigger immediately on page load.
A simple version of the code for the clone() approach would look something like this:
function useIt() {
var $content = $("#template").clone();
var $span = $content.find("span");
$span.text(parseInt($span.text()) + 1);
$content.children().each(function() {
$("#container").append($(this));
});
}
Assuming that your template was:
<div id="template" style="display: none;">
<div>Template used: <span>0</span></div>
<script>alert('Thanks!')</script>
</div>
You could also move the <script>alert('Thanks!')</script> out of the template and into the script section (after you completed the "append loop"), to achive the desired alert functionality, if you wanted to.
It's an old question, but, did you try cloneNode(true)? It works on templates, as this:
var span = content.querySelector('span').cloneNode(true)
regards.

How to style HTML elements for Google custom search API json results?

I'm using Google Custom Search API to fetch and publish JSON callback results. I've been tinkering around with the json results callback variables as per Google recommend documentation here:
https://github.com/googleapis/google-api-java-client-services/blob/master/clients/google-api-services-customsearch/v1/1.30.1/resources/customsearch.v1.json
Wondering how I can use either Javascript variable or other to add CSS/styling to HTML elements that I'm using to produce styled titles, desctiptions & links for Google custom search results on the page?
Here's the code I'm using now:
<div>
<script>
function hndlr(response) {
for (var i = 0; i < response.items.length; i++) {
var item = response.items[i];
// in production code, item.htmlTitle should have the HTML entities escaped.
document.getElementById("content").innerHTML += "<span>" + item.title;
document.getElementById("content").innerHTML += "<p>" + item.snippet +"<u><a href='"+item.link+"'>(continue reading)</a>";
}
}
</script>
<script src="https://www.googleapis.com/customsearch/v1?key=API_KEY&cx=GOOGLE_CUSTOM_SEARCH_ID&q=MY+QUERY+WORDSS&callback=hndlr">
</script>
</div>
How should I add styling to the HTML elements in my code for span, p, etc?
Also, is there a more simple method to just fetch the top ten search results with HTML styling same as it appears Google.com search results page? This would be nice!
Thanks for your help!
For a simpler method, consider using the Search Element -- you can do custom rending of results using the Callbacks API. Plus, it's free

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

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)

Javascript within HTML form tag in the javascript function

Is it possible to put a JavaScript code within the HTML Form tags. I am trying to achieve something like this:
function abc(abcd) {
document.getElementById("context").innerHTML += "<br> 1:";
document.getElementById("context").innerHTML += "***<form METHOD=POST ACTION=\"/InformationRetrieval/home\">***<input type=\"checkbox\" name=\" GoogleRelevance\" value=\"1\"> Relevant <br><br>";
document.getElementById("context").innerHTML += "<br> 2:";
document.getElementById("context").innerHTML += "<input type=\"checkbox\" name=\" GoogleRelevance1\" value=\"1\"> Relevant <br><br>";
document.getElementById("context").innerHTML += "<br> 3:";
document.getElementById("context").innerHTML += "<input type=\"checkbox\" name=\" GoogleRelevance3\" value=\"1\"> Relevant <br>***<input type=\"submit\" value=\"Submit\"></form>***<br><br>";
}
Here what I am trying to ask in this example is:
I have started the tag initially in my starting 2-3 lines, but I am not closing it there and rather inserting some more javascript lines and in the end I am closing the tag with another <input type="submit">, but when I click this button it does not work.
I tried using the OnClick property too but that didn't work either.
I am badly stuck with it. Any help will be greatly appreciated.
I think you really should use some good ajax library (jQuery, YUI, dojo, goog, ...) for something like this, stuffing all the code into form attributes doesn't feel right. As nickf pointed out modifying a dom property in this way is really not a good idea. As I'm used to jQuery here is a snippet to what I understand from your post is the problem:
// Caching the stuff that you used to += on the innerHTML
var newStuff = ' /* your form code here */ ';
jQuery
.ajax({
url: /* your request to google */,
context: jQuery('#context') // Caching the context dom node
})
.done(function() {
// The request was successful
jQuery(this) // The cached context node is the context of this callback
.append(newStuff); // You only have to append new stuff here, if you want something
// more dynamic insert the logic in this function
})
.fail(function() { /* alert("error"); */ })
.always(function() { /* alert("complete"); */ });
I didn't test this one though, it's only a recommendation. To me it is cleaner and it has the advantage if you get it to work in one browser this way you can count on jQuery to make sure it's working in most other browsers too.
And by the way: you can use single ' around the whole html string so that you don't need to escape the " thingys.
Hope this helps, good luck!

dynamic html buttons in javascript code

So I am using javascript, jQuery, and HTML here. Basically I have a dynamic number of buttons that are being created, and will each call a function using unique variables. The variables are held in a json variable. Here is the code as it is:
var box = "<font size=\"2\">The following assassins are in your current location:<br/><table width = \"100%\">";
for (var i=0; i<info.length; i++) {
if(userid != info[i].playerid){
box += "<tr><td>"+info[i].name+" | rank: "+info[i].rank+"</td><td align=\"right\"><input id='attack' type='button' onclick='loadAttack(userid, info[i].playerid, info[i].name, info[i].rank, location)' value='Attack'/></td></tr>";
}
}
box += "</table></font>";
$("#assassinBox").html(box);
The box looks fine, with the proper names, ranks, and buttons. The problem is when a button is pushed, info is undefined. I think this is because the button doesn't get its own copy of it, and is out of the bounds of the array at the end of the loop. I am struggling to think of a solution, some way of passing the onclick function a unique variable?
Thanks!
box += "<tr><td>"+info[i].name+" | rank: "+info[i].rank+"</td><td align=\"right\"><input id='attack' type='button' onclick='loadAttack(userid, info["+i+"].playerid, info["+i+"].name, info["+i+"].rank, location)' value='Attack'/></td></tr>";
That should work. Although if I were you I would consider rewriting it to not use inline event handlers and maybe building the HTML with jQuery or the native DOMElement creation methods rather than concatenating strings of HTML. It makes it a lot more maintainable in the long run.

Categories