mootools javascript template engine - javascript

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 :-)

Related

LocalStorage append New Element

his is : My First JSFiddle. It just appends <li></li>. It works for LocalStorage and shows the result
$(".nav").append($("<li></li>").html(inputan));
I want append like My Second JSFiddle:
var addFolder = '<li>' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
$(".nav").append($(addFolder).html(inputan));
This works for LocalStorage, but is not showing a result when the page is reloaded. I want to use use a method like that because my code looks like this :
With append method $('.nav').append(addFolder);
How can I display LocalStorage result with my second jsFiddle method?
You had addFolder inside your submitButton click handler, hence it is only available in the handler function scope.
$(".submitButton").click(function() {
var inputan = $("#input_nameFolder").val();
// move the below variable outside of this function
var addFolder = '<li>' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
...
});
Move addFolder outside of the function and it should work.
Updated your fiddle.
Edit: To get correct index
You can add a function that returns the addFolder with the current/updated index. The same function can be used for first time rendering on page load and every time on adding item from the input.
Something like:
var count = 1;
function getNewList() {
var addFolder = '<li data-index="' + (count++) + '">' +
'<div class="zf-folder">' +
'<a></a>' +
'</div>' +
'</li>';
return addFolder;
}
You can check out here:
Edited Fiddle for index
// check for the data-index on li items in the console

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.

edit (append?) a string stored in a jquery variable

I am bringing a big html string inside an ajax call that I want to modify before I use it on the page. I am wondering if it is possible to edit the string if i store it in a variable then use the newly edited string. In the success of the ajax call this is what I do :
$.each(data.arrangement, function() {
var strHere = "";
strHere = this.htmlContent;
//add new content into strHere here
var content = "<li id=" + this.id + ">" + strHere + "</li>";
htmlContent is the key for the chunk of html code I am storing in the string. It has no problem storing the string (I checked with an alert), but the issue is I need to target a div within the stored string called .widgteFooter, and then add some extra html into that (2 small divs). Is this possible with jquery?
Thanks
Convert the string into DOM elements:
domHere = $("<div>" + strHere + "</div>");
Then you can update this DOM with:
$(".widgetFooter", domHere).append("<div>...</div><div>...</div>");
Then do:
var content = "<li id=" + this.id + ">" + domHere.html() + "</li>";
An alternative way to #Barmar's would be:
var domHere = $('<div/>').html( strHere ).find('.widgetFooter')
.append('<div>....</div>');
Then finish with:
var content = '<li id="' + this.id + '">' + domHere.html() + '</li>';
You can manipulate the string, but in this case it's easier to create elements from it and then manipulate the elements:
var elements = $(this.htmlContent);
elements.find('.widgteFooter').append('<div>small</div><div>divs</div>');
Then put the elements in a list element instead of concatenating strings:
var item = $('<li>').attr('id', this.id).append(elements);
Now you can append the list element wherever you did previously append the string. (There is no point in turning into a string only to turn it into elements again.) Example:
$('#MyList').append(item);

assign html snippet in 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.

Dynamic angularjs template

I am trying to create a directive this way -
scope.nodeTemplate = '{{node.nodeText}}';
Part of template
'<ul>' +
'<li class="tree-node" data-ng-repeat="node in nodes">' +
'<span>' + scope.nodeTemplate + '</span>' +
'</li>' +
'</ul>'
Based on some condition I would like to change the nodeTemplate and it can be an html string like -
'<input type="text"/>'
But the issue is when it try to do this thing angular does not render the html. It simply puts the html string. I am kind of stuck here. Can someone suggest some solution?
You need to use ng-bind-html-unsafe like:
'<span ng-bind-html-unsafe="nodeTemplate"></span>'

Categories