I have been playing with jquery and templates, and I cobbled together a simple template binding system:
<script type="text/template" id="Template">
<div>{0}</div>
</script>
and...
var buffer = '';
var template = $("#Template").html();
response.Data.forEach(function(arrayElement)
{
buffer += template.format(arrayElement.p1,);
});
$("#ListOutput").html(buffer);
My question is: Is there a more natural way that I can take a JSON object, such as:
{"user": { "id": "1","name": "bob" }}
And use a more natural binding sintax, such a this:
<script type="text/template" id="Template">
<div>{user.name}</div>
</script>
straight JS or jquery would be idea. I know that some of the more complex data binding tools like Angular provide these features, but the complexity of some of the data binding plugins makes my head swim. Anything based on node is right out.
Is there some native feature I don't know about that makes this easy?
If you can use ES2015 "template strings".
<script type="text/template" id="Template">
<div>${user.name}</div>
</script>
You have not added response array, so I am assuming it as
[
{"user": { "id": "1","name": "bob" }},
{"user": { "id": "2","name": "Some Name" }}
]
var buffer = '';
var template = $("#Template").html();
response.Data.forEach(function(arrayElement) {
var user = arrayElement.user;
buffer += eval('`' + template + '`');
});
$("#ListOutput").html(buffer);
I want to use the same data object across multiple templates in different contexts, how can I reuse it. By any chance, handlebars partials would be helpful in this situation.
$("document").ready(function(){
var source = $("#homePage-template").html();
var template = Handlebars.compile(source);
var dataPanel = {activites:[
{activity: "Events" , activityRedirect:"#", icon:"fa fa-camera-retro" , imageUrl:"xyz"},
{activity: "Ciriculars" , activityRedirect:"#", icon:"fa fa-paper-plane", imageUrl:"xyz"}
]};
$("#homePage-placeholder").html(template(dataPanel));
$("#another-placeholder").html(template(dataPanel));
});
And here is my template:
<script id="homePage-template" type="text/x-handlebars-template">
<ul>
{{#activites}}
<li><i class="{{icon}}" aria-hidden="true"></i>{{activity}}</li>
{{/activites}}
</ul>
</script>
Another Template
<script id="another-template" type="text/x-handlebars-template">
{{#activites}}
<div>
<img src="{{imageUrl}}"/>
<span>{{activity}}</span>
</div>
{{/activites}}
</script>
Now how can I reuse this data into "another-template", because I want an image and text in that but it renders like "homePage-template" only in form of a list, if anyone has an idea over this!
In order to have a second template you must fetch its HTML source from the DOM and compile it into a template method just as you are doing for the Home Page Template.
var homepage_template_source = $('#homePage-template').html();
var another_template_source = $('#another-template').html();
var homepage_template = Handlebars.compile(homepage_template_source);
var another_template = Handlebars.compile(another_template_source);
You must call the template method for the specific template you wish to render:
$("#homePage-placeholder").html(homepage_template(dataPanel));
$("#another-placeholder").html(another_template(dataPanel));
See this fiddle for an example.
For simplification and control, I have my own js templating engine, which works like this:
html:
<ul id="persons">
<li class="person-template hide">
<span>{name}</span>, <span class="placemark" data-lat="{latitude}" data-lng="{longitude}">{location}</span>
<li>
</ul>
js:
var persons = [
{"name":"hulk", "location": "usa", latitude: -33.4, longitude: -70.5},
{"name":"wolverine", "location": "mexico", latitude: -33.4, longitude: -70.5},
];
$.each(persons, function(i, person) {
var html = $(".person-template").clone().removeClass("person-template").addClass("person").show().outerHtml();
html = html.replaceAll("{name}", person.name);
html = html.replaceAll("{latitude}", person.latitude);
html = html.replaceAll("{longitude}", person.longitude);
html = html.replaceAll("{location}", person.location);
});
(replaceAll and outerHtml are two helper functions I've made, they are self-explained by their names)
My problem with this is that sometimes I want to select things with jQuery but my template notation interferes, for example:
$(".placemark").each(function(i, v) {
alert($(v).data("latitude")));
});
Will alert: "{latitude}", "-33.4", "-33.4"
Obviously I want to avoid the template value.
What is the most clean solution for this?
Start using a formal template engine?
Skip first in the $.each? (kind of ugly)
...?
You are cloning the template, so it still exists. You need to remove it after you loop through.
$(".person-template").remove();
or, you can just make sure not to grab the person-template when you alert. $(".location_but_not_location_template").each ...
I am new to Backbone js. Can some one help me to send data in template from my view.
My View has this code:
$('#top-bar').html(_.template($("#loginned-top-bar-template").html()));
and my template contains
<li class="menu-item"><%user_name%></li>
and I want to send "awsome_user"to it.
It would be great if any one would help me.
var compiled = _.template($("#loginned-top-bar-template").html());
var templateVars = {user_name : 'awesome_user' };
$('#top-bar').html( compiled(templateVars) );
<%user_name%> should be <%=user_name%> if you want to print the variable.
If you want to use other user_name, set user_name property before compiled function called.
var compiled = _.template($("#loginned-top-bar-template").html());
var templateVars = {user_name : 'awesome_user' };
templateVars.user_name = Parse.User.current().get("name");
$('#top-bar').html( compiled(templateVars) );
I am fetching the contents of a webpage (using scipio module of nodejs). From the webpage, I need to extract all lines of the form {title: "..." ......}. The relevant portion of the webpage is shown below:
//<!--
if(!ALEXA)
var ALEXA={viewsHelpers:{}};
if(!ALEXA.viewsHelpers.map)
ALEXA.viewsHelpers.map={};
ALEXA.viewsHelpers.map.div= "visitsMap";
ALEXA.viewsHelpers.map.areas=[
{title:"United States: 29.8%",id:"US",value:"5.39"},
{title:"India: 8.9%",id:"IN",value:"4.19"},
{title:"Russia: 3.3%",id:"RU",value:"3.19"},
{title:"Japan: 3.3%",id:"JP",value:"3.19"},
{title:"Brazil: 3%",id:"BR",value:"3.1"},
{title:"United Kingdom: 2.9%",id:"GB",value:"3.06"},
{title:"Iran: 2.5%",id:"IR",value:"2.92"},
{title:"France: 2.3%",id:"FR",value:"2.83"},
{title:"Spain: 2.3%",id:"ES",value:"2.83"},
{title:"Germany: 2.3%",id:"DE",value:"2.83"},
{title:"Mexico: 2.1%",id:"MX",value:"2.74"},
{title:"Italy: 2%",id:"IT",value:"2.69"},
{title:"Canada: 1.9%",id:"CA",value:"2.64"},
{title:"Indonesia: 1.7%",id:"ID",value:"2.53"},
{title:"Turkey: 1.2%",id:"TR",value:"2.18"},
{title:"Australia: 1.2%",id:"AU",value:"2.18"},
{title:"Pakistan: 1%",id:"PK",value:"2"},
{title:"Taiwan: 0.9%",id:"TW",value:"1.89"},
{title:"Argentina: 0.9%",id:"AR",value:"1.89"},
{title:"Netherlands: 0.9%",id:"NL",value:"1.89"},
{title:"South Korea: 0.9%",id:"KR",value:"1.89"},
{title:"Poland: 0.9%",id:"PL",value:"1.89"},
{title:"China: 0.8%",id:"CN",value:"1.78"},
{title:"Saudi Arabia: 0.8%",id:"SA",value:"1.78"},
{title:"Malaysia: 0.8%",id:"MY",value:"1.78"},
{title:"South Africa: 0.8%",id:"ZA",value:"1.78"},
{title:"Thailand: 0.7%",id:"TH",value:"1.64"},
{title:"Nigeria: 0.7%",id:"NG",value:"1.64"},
{title:"Colombia: 0.7%",id:"CO",value:"1.64"},
{title:"Egypt: 0.6%",id:"EG",value:"1.49"},
{title:"Ukraine: 0.6%",id:"UA",value:"1.49"},
{title:"Venezuela: 0.6%",id:"VE",value:"1.49"},
{title:"Philippines: 0.6%",id:"PH",value:"1.49"},
{title:"Singapore: 0.5%",id:"SG",value:"1.31"},
{title:"Greece: 0.5%",id:"GR",value:"1.31"}];
//-->
Any suggestions on how to achieve this will be helpful
If I understand well your question, you can do
html = html.split('\n').filter(function(l){
return !/^\s*{title:.*},?\s*/.test(l)
}).join('\n');