assign html snippet in javascript - javascript

There are times that I need to assign a html snippet to a javascript var, such as,
var homePage =
'<div>' +
'<div class="header"><h1>Page Slider</h1></div>' +
'<div class="scroller">' +
'<ul class="list">' +
'<li><strong>Build Bot</strong></li>' +
'<li><strong>Medi Bot</strong></li>' +
'<li><strong>Ripple Bot</strong></li>' +
'</ul>' +
'</div>' +
'</div>';
This can work good, but it makes editing a bit hard. May I know any framework can do this elegantly?

Use handlebars.js this is how is works:
Server side:
Send a JSON object back to javascript. I usually use something like this:
echo json_encode(array('object_name'=>$obj));
HTML
Create a container on your page.
<div id="#my_template_container"></div>
Javascript:
usually in your AJAX success function:
Parse your data into a JSON object:
var my_obj= JSON.parse(data);
Create a reference to the template:
var tmpl = $("#my_layout").html();
Use the Handlebars engine to compile the template:
var theTemplate = Handlebars.compile(tmpl);
Append the template to the HTML
$('#my_template_container').html(theTemplate(my_obj));
Template
Access your object in the template by it's name, in this example it would be : object_name the variable I assigned in my echo json_encode(array('object_name'=>$obj)) statement from PHP.
Access properties of the object using {{Property_Name}}.
To access properties of object children use the nested path operator: {{Propert_Name.ID}}
<script id="my_layout" type="text/x-handlebars-template">
{{#object_name}}
'<div>' +
'<div class="header"><h1>Page Slider</h1></div>' +
'<div class="scroller">' +
'<ul class="list">' +
'<li><strong>{{property1}}</strong></li>' +
'<li><strong>{{property2}}</strong></li>' +
'<li><strong>{{property3}}</strong></li>' +
'</ul>' +
'</div>' +
'</div>';
{{/object_name}}
</script>

I created a very light plugin, just for the times, when you just want to use some html inside js, and do not require a lot of options provided my templating frameworks and thus want to avoid heavy js.
Coffee script
(($) ->
utCache = {}
$.fn.ut = (tmplID, obj) ->
_tmpl = (str) ->
fn = "var p=[]; p.push('" + str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g, "',$1,'").split("<%").join("');").split("%>").join("p.push('") + "'); return p.join('');"
new Function("o", fn)
_getData = (ele) ->
$(ele).html utCache[tmplID](obj)
#each ->
ele = this
utCache[tmplID] = _tmpl($(tmplID).html()) unless utCache[tmplID]
_getData ele
) jQuery
Javascript
(function($) {
var utCache;
utCache = {};
return $.fn.ut = function(tmplID, obj) {
var _getData, _tmpl;
_tmpl = function(str) {
var fn;
fn = "var p=[]; p.push('" + str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g, "',$1,'").split("<%").join("');").split("%>").join("p.push('") + "'); return p.join('');";
return new Function("o", fn);
};
_getData = function(ele) {
return $(ele).html(utCache[tmplID](obj));
};
return this.each(function() {
var ele;
ele = this;
if (!utCache[tmplID]) {
utCache[tmplID] = _tmpl($(tmplID).html());
}
return _getData(ele);
});
};
})(jQuery);
You can use it simply like,
$('#my-div').ut("#my-template", { name: 'jashwant'});
when we have following HTML:
<div id='my-div'></div>
<script type='javascript' id='my-template'>
<p><%=o.name %> welcomes you !</p>
</script>

Do it with Javascript's document methods.
var topdiv = document.createElement('div');
var headerDiv = document.createElement('header');
var header = document.createElement('h1');
header.innerHTML = 'Page Slider';
headerDiv.appendChild(header);
// etc....
Or use templating.

Just use backslashes to escape line breaks.
Eg:
var homePage =
'<div> \
<div class="header"><h1>Page Slider</h1></div> \
<div class="scroller"> \
<ul class="list"> \
<li><strong>Build Bot</strong></li> \
<li><strong>Medi Bot</strong></li> \
<li><strong>Ripple Bot</strong></li> \
</ul> \
</div> \
</div>';
Use \n\ instead of \ if you want to include the line breaks in the string.

Related

send data from java to javascript page into a href function

I want to send variable into onclick function, but I did not succeed to get the suitable code.
this is the java code :
for (int i = 0; i < projetList.size(); i++) {
contenuTableHTML.append("<tr>");
contenuTableHTML.append("<td class='width1'><div class='coupe'>" + projetList.get(i).getProjectAbr() + "</div></td>");
contenuTableHTML.append("<td class='width3'><div class='coupe'>" + projetList.get(i).getProjectTkt() + "</div></td>");
List<String> objList = projetList.get(i).getObjectList();
contenuTableHTML.append("<div id='objList' name='objList' value='objList'>");
contenuTableHTML.append("<td class='width3'><div class='coupe'> <a href='#' **onclick='popupFunction(objList)**'>" + projetList.get(i).getObjectList().size() + "</div></td>");
contenuTableHTML.append("</div>");
contenuTableHTML.append("<td class='tableTicketsSummaryTd width3'><div class='coupe'>" + projetList.get(i).getProjectDomain() + "</div></td>");
contenuTableHTML.append("</tr>");
}
As below the javascript code:
function popupFunction(obj) {
objList = document.getElementById(obj);
console.log("objList ",objList);
console.log("obj: ", obj);
var w = window.open("", "", "width=600,height=300");
w.document.write(obj);
w.document.close();
w.focus();
}
I always get objList and obj as null.
The onclick template in html, should be dynamic to send an actual argument (objList) to the javascript function.
You can make use of template literals or dynamic strings while creating your HTML in the following way by adding (template literal) and accessing dynamic elements using ${element} inside the template literal``:
contenuTableHTML.append(`<div id=${objList} name=${objList} value=$[objList}>`);
contenuTableHTML.append(`<td class='width3'><div class='coupe'> <a href='#' onclick='popupFunction(${objList})'>` + projetList.get(i).getObjectList().size() + "</div></td>");
This will allow you to access objList and obj in your javascript function.

How to properly generate HTML in a JavaScript widget?

I've been following this tutorial on how to make JS widget. However I noticed that manually building html with plain JavaScript is not DRY. I am planning to build a form, tables etc. in a JS widget. Whats the best way to do this?
$.getJSON(jsonp_url, function(data) {
var fruits = ["Apples", "Mangoes", "Banana"];
var myHtml = "<ul>";
$(fruits).each(function(i){
myHtml += "<li>" + fruits[i] + "</li>";
});
myHtml += "</ul>";
$('#example-widget-container').html(myHtml);
});
if you want one of your divs or containers to continuously grow while you build dynamic content, without losing older content, use jQuery.append
$('#example-widget-container').append(myHtml);
this is probably the cleanest way. Or you can do other things like
var html = $('#example-widget-container').html();
newHtml = yourContent;
$('#example-widget-container').html(html + newHtml);
In JavaScript you can generate html content in different ways :
Create HTML with a string directly :
$("#sampleArea").append('<div class="' + newClass + '">' + newText + '</div>');
Create HTML with jQuery Api wrapping :
$("#sampleArea").append($('<div/>',{class : newClass}).text(newText));
Use a template engine in Javascript (like mustache.js) :
<script id="exampleTpl" type="x-tmpl-mustache">
<div class="{{class}}">{{text}}</div>
</script>
<script>
var data = {
class: newClass,
text: newText
}
var template = $('#exampleTpl').html();
var html = Mustache.render(template, data);
$('#sampleArea').append(html);
</script>
The best solution will depends of your use.

mootools javascript template engine

I'm using this great javascript mootools template engine: https://github.com/tbela99/template
My template looks like this:
var tmpl = '<ul>' +
'{repeat:products}' +
'<li class="small">' +
'{photos.0.name}' +
'{name}' +
'</li>' +
'{/repeat:products}' +
'</ul>';
My data below:
var data = {"products":[{"id":"449","name":"Apple","photos":[{"name":"image.jpg"}]}]};
new Element('div',{'html':template.substitute(tmpl,data)}).inject(document.body);
And my question:
How to add custom modifier (.addModifier function) inside current context {repeat:products} and pass a value: {photos.0.name} ?
For example: {repeat:products}{customtag photos.0.name}{/repeat:products}.
Thanks!
The modifier first argument is the current object in the loop :-)

Adding html while iterating over jquery object

Is there a better way of inserting somewhat complex html into a page other than the way I'm doing now? :
function display(friends) {
$(".row").empty();
$.each(friends, function(index, friend) {
var html = '<div class="profileImage" style="float:left;padding:20px; width:200px">';
html += '<a href="/app/click/' + friend.id + '">';
html += '<img id="' + friend.id + ' " src="https://graph.facebook.com/' + friend.id + '/picture?width=200&height=200 " />';
html += '</a>';
html += '</div>';
$(".row").append(html);
});
Currently I have a list of facebook friends which are styled nicely. When a user searches through the friends, the entire content block is emptied and the result is appended (i'm using autocomplete). However the design could change and get more complex so i'm looking for a scalable way of doing what I have above.
Instead of creating the html inside the javascript, is there a smarter way of doing this? Perhaps with $.load() and passing each friend as an argument? But that seems very slow and server intensive if you have to list 100 friends.
One good way to go would be to use a templating engine, handlebars (as mentioned in the prev answer) is one of them. You could create your own as well if your scenario is simple as this. And another key thing is not to use append inside the loop, instead construct them to a temp array and add it to the DOM in the end. If your list is big and appending to the dom in the array can be expensive.
Add the template html with a placeholder for friendId
<script type="text/html" id="template">
<div class = "profileImage" style = "float:left;padding:20px; width:200px">
<a href = "/app/click/{{friendId}}">
<img id = "{{friendId}}" src = "https://graph.facebook.com/{{friendId}}/picture?width=200&height=200 " />
</a>
</div>
</script>
And
var $template = $('#template'),
$row = $('.row');
function display(friends) {
var rows = [];
$.each(friends, function (index, friend) {
var templateHtml = $template.text().replace(/{{friendId}}/g, friend.id);
rows.push(templateHtml);
});
$row.html(rows); //Append them in the end
}
Demo
You could use $.map as well.
var $template = $('#template'),
$row = $('.row');
function display(friends) {
var rows = $.map(friends, function (friend) {
var templateHtml = $template.text().replace(/{{friendId}}/g, friend.id);
return templateHtml;
});
$row.html(rows);
}
A scalable solution would be to use a template engine and make the server returns JSON response.
Take a look at Handlebars.js http://handlebarsjs.com/

Pass string from one function to the next javascript

I've got a simple JavaScript client that pulls from a REST API to present some book data, however I seem unable to call the function createBookRow(bookid) and return the appropriate html string to the document ready function where it is called,
The output is currently being produced correctly as verified by the append to .row-fluid on the html page, ideas or suggestions welcome
function createBookRow(bookid)
{
$.get('http://mysite.co.uk/atiwd/books/course/'+bookid+'/xml', function(xml){
$(xml).find('book').each(function(){
var $book = $(this);
var id = $book.attr("id");
var title = $book.attr("title");
var isbn = $book.attr("isbn");
var borrowedcount = $book.attr("borrowedcount");
var html = '<div class="span3"><img name="test" src="http://covers.openlibrary.org/b/isbn/'+isbn+'-L.jpg" width="32" height="32" alt=""></p>' ;
html += '<p> ' + title + '</p>' ;
html += '<p> ' + isbn + '</p>' ;
html += '<p> ' + borrowedcount + '</p>' ;
html += '</div>';
$('.row-fluid').append($(html));
});
});
}
$(document).ready(function()
{
$.get('xml/courses.xml', function(xml){
$(xml).find('course').each(function(){
var $course = $(this);
var id = $course.attr("id");
var title = $course.text();
var html = '<div class="span12"><p>' + title + '</p><row id="'+id+'" >'+createBookRow(id)+'</row></div>' ;
$('.row-fluid').append($(html));
$('.loadingPic').fadeOut(1400);
});
});
});
The line
var html = '<div class="span12"><p>' + title + '</p><row id="'+id+'" >'+createBookRow(id)+'</row></div>' ;
should be just
var html = '<div class="span12"><p>' + title + '</p><row id="'+id+'" ></row></div>' ;
createBookRow(id);
createBookRow(id) function is making a get request to get some details, which happens asynchronously. Unless you explicitly mention it is a synchronous call(which is not advised).
I guess the functionality you need is to render some rows for course and in between you need books details displayed. In that case you need to explicitly say where your book row needs to be appended.
$('.row-fluid').append($(html));
The above code will always append book row at the end.
You aren't returning anything in the code you provided. You just append some HTML to a jQuery object. Try adding a return statement
return html;

Categories