I am new to Handlebar.js and trying to learn it. I have a scenario where I want to insert handlebar expression inside the extra options.
In below sample code I want to set the title of each link based on its text for example "Click to go Google"
This is what I have tried but no one is working:
title="Click to go (this.text)"
title="Click to go this.text"
title="Click to go "+this.text
Data:
var links=[
{text:"Google",url:"http://www.google.com"},
{text:"Yahoo",url:"http://www.yahoo.com"}
];
Sample code:
<script type="x-handlebars-template" id="links">
{{#each this}}
{{link url text title="Click to go (this.text)"}}<br>
{{/each}}
</script>
Complete code:
Links:
<div class="links"></div>
<script type="text/javascript">
Handlebars.registerHelper("link",function(url,text,options){
var attrs=[];
for(var attr in options.hash){
attrs.push(attr+"=\""+options.hash[attr]+"\"");
}
var escapedURL=Handlebars.escapeExpression(url);
return new Handlebars.SafeString('<a href=\"'+escapedURL+'\"'+attrs+'>'+text+'</a>')
});
</script>
<script type="x-handlebars-template" id="links">
{{#each this}}
{{link url text title="Click to go (text)"}}<br>
{{/each}}
</script>
<script type="text/javascript">
var links=[
{text:"Google",url:"http://www.google.com"},
{text:"Yahoo",url:"http://www.yahoo.com"}
];
var template=Handlebars.compile($("#links").html());
$(".links").append(template(links));
</script>
take a look on this answers: Pass JavaScript object/hash to Handlebars helper?
use only options in your helper, add text=title in template and pass text to SafeString.
Related
The user can only delete a post if he was the one who posted it.However a user can see all the posts.The javascript code is:
var postedBy = Meteor.user();
var currentPost = this._id;
Posts.insert({
name:postName,
createdAt:new Date(),
postId:currentPost,
postedBy:postedBy
});
The HTML code is:
<template name="posts">
{{#if currentUser}}
{{> addPost}}
<ul>
{{#each post}}
<li>{{> postItem}}</li>
{{/each}}
</ul>
{{/if}}
</template>
<template name="postItem">
<li>
<h4>{{name}}</h4>
<i>Posted by {{postedBy.username}} on {{createdAt}}</i>
[Delete]
</li>
</template>
<template name='addPost'>
<input type='text' placeholder='Add post here' name='postName' id ='myinput'>
<button class="btn btn" type="button" id='btn'>Post</button>
</template>
Both currentUser.username and postedBy.username are displaying the names of the logged in user and the user who posted a particular post respectively.
I am trying to work with the Delete anchor tag.
{{#if currentUser.username==postedBy.username}}
[Delete]
{{/if}}
But it shows error in command prompt.I know it is wrong but I can't think of any other way.How do i write this 'if' statement to check if the current user was the one who posted this post?
Please help as I am new to Meteor.Sorry for bad English.
You can't use arbitrary JavaScript expressions in spacebars. Add a helper like this:
Template.postItem.helpers({
canDelete: function (){
return Meteor.user().username === this.postedBy.username;
}
});
Which you can then use in your template like this:
{{#if canDelete}}
Delete
{{/if}}
Also note, instead of copying the user object into each post, the recommended way is to store the user's id in postedBy.
I have a handlebars template that looks like:
<script id="user-template" type="text/x-handlebars-template">
<a class="result" href="/{{github_id}}">
<img src="{{image_url}}" />
<span class='additional-name'>{{> highlight object=this key="github_id"}}</span>
</a>
</script>
And my highlight partial looks like:
<script id="highlight-search-partial" type="text/x-handlebars-template">
{{#if object._highlightResult}}
{{#if object._highlightResult.key}}
{{object._highlightResult.key.value}}
{{/if}}
{{else}}
{{object.key}}
{{/if}}
</script>
Here's what my javascript object looks like:
After rendering the handlebars template, visually it's empty. Nothing is being rendered.
Any ideas on what I'm doing wrong? I'm using handlebars 3.0.3 (latest).
I ended up writing a helper handlebars function:
<span>{{highlight this "github_id"}}</span>
Handlebars.registerHelper('highlight', function(obj, field) {
if (obj['_highlightResult']) {
return obj['_highlightResult'][field].value;
} else {
return obj[field];
}
});
So, Basically i'm new to meteor(0.8.2) and trying to create a basic app having two templates(addnewPlace and Map) and a single button. What i need to get is that, when i click on "Add new Place" button, template "addNewPlace" should be loaded in body or else template "Map" should be loaded. Help will be appreciated :)
My html code:
<body>
{{> menu}}
{{> body}}
</body>
<template name="body">
{{#if isTrue}}
{{> addnewPlace}}// tested this template individually, it works.
{{else}}
{{> maps}} // tested this template individually, it works too.
{{/if}}
</template>
<template name="menu">
<h1>Bank Innovation Map</h1>
<input type="button" value="Add new Place">
</template>
My js code:
Template.body.isTrue = true;
Template.menu.events({
'click input': function(){
//load a new template
console.log("You pressed the addNewplace button");//this fn is called properly
Template.body.isTrue = true;
}
});
Well first of all you obviously aren't changing anything in the click event (true before, true after). But also if you did, I think you might be better off using a session variable for this, to maintain reactivity.
Session.setDefault('showAddNewPlace', false)
Template.body.isTrue = function() { Session.get('showAddNewPlace'); }
Template.menu.events({
'click input': function(){
//load a new template
console.log("You pressed the addNewplace button");//this fn is called properly
Session.set('showAddNewPlace', true)
}
});
Meteor 0.8.2 comes in with the dynamic template include feature. Just set a session variable value on click event and you would like to use the template name on the event.
Session.setDefault('myTemplate', 'DefaultTemplateName');
"click input": function (event) {
Session.set("myTemplate", 'template_name');
}
You can now write this:
<body>
{{> menu}}
{{> body}}
</body>
<template name="body">
{{> UI.dynamic template=myTemplate}}
</template>
<template name="menu">
<h1>Bank Innovation Map</h1>
<input type="button" value="Add new Place">
</template>
You may like to take a look at this article for the reference:
https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
I'm new to ember I am trying to append a template to another and it seems to work but it raises an error, can you please explain why?
The error:
Assertion failed: You cannot append to an existing Ember.View. Consider using Ember.ContainerView instead
This is the code in app.js
App.NewStickie = Ember.View.extend({
click: function(evt){
var stickie = Ember.View.create({
templateName: 'stickie',
content: 'write your notes here'
});
stickie.appendTo('#stickies');
}
});
These are the contents of index.html
<script type="text/x-handlebars">
{{#view App.NewStickie}}
<button type="button" class="btn btn-success">
New
</button>
{{/view}}
{{outlet}}
</script>
<script type="text/x-handlebars" id="index">
<div id="stickies">
{{#each item in model}}
<div class="stickie" contenteditable="true">
{{#view App.DeleteStickie}}
<span class="glyphicon glyphicon-trash"></span>
{{/view}}
<div contenteditable="true">
{{item.content}}
</div>
</div>
{{/each}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="stickie">
<div class="stickie">
{{#view App.DeleteStickie}}
<span class="glyphicon glyphicon-trash"></span>
{{/view}}
<div contenteditable="true">
{{view.content}}
</div>
</div>
</script>
Each view in ember have a template, for example:
foo_view.js
App.FooView = Ember.View.extend({
templateName: 'foo'
})
foo template
<script type="text/x-handlebars" data-template-name="index">
<div id=myFooView>Foo</div>
</script>
You are trying to insert a view inside of other in that way:
App.BarView.create().appendTo('#myFooView')
This isn't allowed. You can use the {{view}} handlebars helper to render a view inside other like that:
foo template
<script type="text/x-handlebars" data-template-name="index">
<div id=myFooView>
Foo
{{view App.BarView}}
</div>
</script>
But I think that you want this working dynamically. So you can use the ContainerView, like described by the error message:
App.StickiesView = Ember.ContainerView.extend({
click: function() {
var stickie = Ember.View.create({
templateName: 'stickie',
content: 'write your notes here'
});
this.pushObject(stickie);
}
})
I see in your code a lot of views with the click event, ember encourage you to use actions, this give more flexibility, error/loading handling etc. I think is a good idea to use it.
I hope it helps
You should probably read this guide that explains that ContainerView is. Also, I don't think it's necessary to create another View to append a template to another template.
[Update] code I have edited
First, the plain HTML :
<ul>
<li>coke</li>
<li>buble-tea</li>
<li>milk</li>
</ul>
Second, link page (javascript_accord.php) contain javascript:
<html>
<head>
<script type="text/javascript" src="development-bundle/jquery-1.3.2.js"></script>
<script language="javascript">
$(document).ready(function() {
var option = 'coke';
var url = window.location.pathname.split('/');
option = url[3];
showDiv(option);
});
function showDiv(option) {
$('.boxes').hide();
$('#' + option).show();
}
</script>
</head>
<body>
<div class="boxes" id="coke">Coke is awesome!</div>
<div class="boxes" id="bubble-tea">Bubble tea is da bomb!</div>
<div class="boxes" id="milk">Milk is healthy!</div>
<p>
I change my mind:
<ul>
<li>Coke</li>
<li>Bubble Tea</li>
<li>Milk</li>
</ul>
</p>
Back to main page
</body>
</html>
I found some tutorial about 'show/hide' content based on URL parameter via JavaScript.
But I stuck when I change a part of the JavaScript code.
Here are the code that I learned from the tutorial.
First page contain some links to other page:
If you had to choose a drink, what would you choose:
<a href="/demo/demo-show-hide-based-on-url.html?option=coke"
<a href="/demo/demo-show-hide-based-on-url.html?option=bubble-tea"
<a href="/demo/demo-show-hide-based-on-url.html?option=milk
And here is the code contain in linking page (/demo/demo-show-hide-based-on-url.html) :
<div class="boxes" id="coke">Coke is awesome!</div>
<div class="boxes" id="bubble-tea">Bubble tea is da bomb!</div>
<div class="boxes" id="milk">Milk is healthy!</div>
<p>
I change my mind:
<ul>
<li>Coke</li>
<li>Bubble Tea</li>
<li>Milk</li>
</ul>
</p>
Back to main page
And the javascript :
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var option = 'coke';
var url = window.location.href;
option = url.match(/option=(.*)/)[1];
showDiv(option);
});
function showDiv(option) {
$('.boxes').hide();
$('#' + option).show();
}
</script>
It works greatly, but when I try to change the link page from
href="/demo/demo-show-hide-based-on-url.html?option=coke"
into something like this :
href="/demo/demo-show-hide-based-on-url.html/option/coke"
And change the url variable in javascript from
var url = window.location.href;
option = url.match(/option=(.*)/)[1];
to
var url = window.location.pathname.split('/');
option = url[3];
And all content in
<div class="boxes" id="...">
appear.
It supposed to be only selected one will appear. I have tried
var url = window.location.pathname.split('/');
option = url[3];
in simple JavaScript to check whether it will catch the right or value or not. And it does return the right value (coke, milk, bubble-tea).
So, what went wrong?
I hope somebody understand this problem and help.
path to jquery is wrong. Can you please check if jquery library is loading?
jquery will be loaded from javascript_accord.php/option/coke/development-bundle/jquery-1.3.2.js
Please make the path to library absolute. That should do :)
I believe that window.location will return the full URL of the page, so you're not just working with the /demo/demo-show-hide-based-on-url.html/option/coke part.
I'd simply change the regular expression instead to replace the = with a /, like so:
option = url.match(/option\/(.*)/)[1];
"/demo/demo-show-hide-based-on-url.html/option/coke".split('/')[3] will return option and not coke
there are 5 entries in the array, because there is an empty string before the first '/':
"",
"demo",
"demo-show-hide-based-on-url.html",
"option" and
"coke"