How to access handlebar expression inside the options? - javascript

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

Checking equality in Blaze?

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.

How to access value in context object with key in Handlebars?

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];
}
});

loading meteor template on click events

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/

emberjs append works but raises Assertion Failed error

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.

How to show content based on url parameter via JavaScript?

[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"

Categories

Resources