If equals validate in handlebar template inside each loop - javascript

I have a php array like this one
bookings[] = {"arrived","cancelled","departed"};
When display this array in handlebars template i want to check IF equal condition.
In the following example when value is equals to cancelled i want to display some text.
{{#each bookings}}
{{#if this.value cancelled}}
cancelled
{{/if}}
{{/each}}
This code is not working. What is alternative IF equals condition for handlebars to execute in loop.

Now my code is working,
bookings = ["arrived", "cancelled", "departed"];
Handlebar function:
Handlebars.registerHelper('check_status', function(val1, val2) {
return val1 === val2;
});
Handlebar template:
{{#if (check_status this 'cancelled')}}

If I'm not mistaken you can't do an actual conditional in handlebars, you can only do if true/false which means that the **value** in {{#if **value**}} need to either be true or false
So what you will want to do is in the area of code where this.value is defined create a function like this
valueIsCancelled = function(value) {
return value === 'cancelled';
}
In your template you will do:
{{#each bookings}}
{{#if this.valueIsCancelled this.value}}
cancelled
{{/if}}
{{/each}}
or another option is to define another variable where value is defined that would be a boolean
var isCancelled = value === 'cancelled';
and your template would look like this
{{#each bookings}}
{{#if this.isCancelled}}
cancelled
{{/if}}
{{/each}}

Related

Meteor js condition with each loop

I am very new to meteor js and trying to build a small messaging app.
What I want to do is I want to check a condition within the loop with
Probably, something like this.
<div class="messages-box">
{{#each messages}}
{{#if isCurrentUserCan}}
<p>{{msg that user can do bla bla}}</p>
{{else}}
<p>{{msg that user can't do}}</p>
{{/if}}
</div>
{{/each}}
</div>
js
Template.body.helpers({
'isCurrentUserCan': function(){
if ( random message box's user ID == Meteor.userId() ){
return 'This user can do bla bla';
}else{
return 'This user can't do';
}
}
});
How can I achieve it?
You're iterating over a collection of messages. Let's say that each message includes a userId key. You can check to see if the userId of the message is the same as the current user and return true or false accordingly.
Template.body.helpers({
'isCurrentUserCan'() {
return this.userId === Meteor.userId();
}
});
Inside the {{each}} this is set to the current message object so this.key directly accesses the corresponding key.

Meteor - display collection with conditions

I have a user based Meteor application with a collection representing groups.
A group is something like this:
{ name: groupname, members: [memberuseridlist], owner: owneruserid}
I have a template for these groups that looks like this:
{{#each groups}}
<li>{{name}}
-
<button class="join">+</button>
<button class="leave">-</button>
<button class="delete">x</button>
</li>
{{/each}}
But I'd like to ensure that only the relevant buttons are displayed e.g.:
{{#each groups}}
<li>{{name}}
-
{{#unless ismember}}<button class="join">+</button>{{/unless}}
{{#if ismember}}<button class="leave">-</button>{{/if}}
{{#if isowner}}<button class="delete">x</button>{{/if}}
</li>
{{/each}}
I have a set of template helper methods but I don't understand how to pass the actual group into the function, so that I can evaluate ismember and isowner for each group.
The context within {{#each groups}} is a group document. So within your helpers you can use this to mean a group. Try something like this:
Template.myTemplate.helpers({
ismember: function() {
return _.contains(this.memberuseridlist, Meteor.userId());
},
isowner: function() {
return this.owner === Meteor.userId();
}
});
If you wish to make these helpers more portable between your templates, see my article on models.

Changing template on Link Click Meteor

There is a button :
<a id = "login" class="waves-effect white blue-text text-darken-2 btn"><i class="fa fa-pencil"></i> Write</a>
and there are two templates, firstpage, and secondpage.
Now, I want Meteor to change templates when I click that link, and render the second page.
How can I do this?
I used aldeed:template-extension but it doesnt work.
You can use some helpers here, and template variables.
Lets say you have this template.
<template name="example">
{{#if clicked}}
{{> firstPage}} <!-- the firstPage template will be rendered if the var is == false -->
{{else}}
{{> secondPage}} <!-- this will be render when the session is equals to true -->
{{/if}}
</template>
Now the Javascript.
First on the onCreate function declare the default values (similar so Session.setDefault)
Template.example.onCreated( function(){
var self = this;
self.vars = new ReactiveDict();
self.vars.setDefault( 'clicked' , true ); //default is true
});
Now the event to change the state of the clicked to false (Similar to Session get/set).
Template.example.events({
'click .waves-effect':function(event,template){
var instance = Template.instance();
instance.vars.set('clicked', false) //set to true.
}
})
Now we something to listen our variables changes, lets use a helper
Template.example.helpers({
clicked:function(){
var instance = Template.instance(); //http://docs.meteor.com/#/full/template_instance
return instance.vars.get('clicked') //this will return false(default) | true
}
})
NOTE Here we are using reactive-dict wich share the same syntaxis of a Session.
meteor add reactive-dict
Here is the MeteorPad Example

How to convert a Array Object to EmberJS Array

I've the following class:
App.Entity = Ember.Object.extend({
id: null,
name : null,
});
And I've the following controller :
App.HomeController = Ember.ObjectController.extend({
entities: null,
init:function(){
var myArray = [];
var a = App.Entity.create();
a.set('id',1);
a.set('name','A');
var b = App.Entity.create();
b.set('id'2);
b.set('name','B');
//and I add another entities dynamycally
myArray.push(a);
myArray.push(b);
console.log( 'isArray: '+ Ember.isArray(myArray) ); //I get true
this.set('entities', myArray );
}
});
The problem is when I try to iterate and render the content over view:
<script type="text/x-handlebars" data-template-name="home" >
{{#if entities}}
{{#each entities }}
{{this.value}}
{{/each}}
{{/if}}
{{outlet}}
</script>
I get the following mistake:
Assertion Failed: The value that #each loops over must be an Array. You passed <App.Entity:ember425>,<App.Entity:ember426>,...
How to fix it?
After reading a bit in their documentation, I have understood that you should use Ember.ArrayController to render arrays.
An example from their documentation would be like this:
Controller:
MyApp.listController = Ember.ArrayController.create();
$.get('people.json', function(data) {
MyApp.listController.set('content', data);
});
Template:
{{#each MyApp.listController}}
{{firstName}} {{lastName}}
{{/each}}
As can be seen here, they first set the key content with the data array directly on the controller. In your case this would be the step this.set('entities', myArray ); that you already did.
In the second step, they use the #each helper on the controller, not the key. In your case this would look like:
<script type="text/x-handlebars" data-template-name="home" >
{{#if entities}}
{{#each App.HomeController }}
{{id}} {{value}}
{{/each}}
{{/if}}
{{outlet}}
</script>
To access the properties you do it as in any handlebars template.
Update
From your comments I assume that you are not deserializing the json string to a javascript object.
The json you receive from the server is a plain string. You must deserialize it using JSON.parse.
Example :
var json = '[{"id":"17","nombre":"Musical dezzer"},
{"id":"172","nombre":"Musical dezzer"}]',
trueResult = JSON.parse(json);
console.log(trueResult);

Is it possible to pass conditionals or other javascript as arguments in ember handlebars?

I would like to pass a true/false statement to my handlebars
{{Gd-text-input label="Specify" name="Specify" key="entry.810220554" hideIf="entry.18110 === "Client""}}
I would like hideIf to be true if the variable entry.18110 is set to "Client
First, add this somewhere -
Handlebars.registerHelper('ifEqual', function (var1, var2, options) {
if (var1=== var2) {
return new Handlebars.SafeString(options.fn(this));
}
return new Handlebars.SafeString(options.inverse(this));
});
Then..
{{#ifEqual entry.18110 "Client"}}
{{Gd-text-input label="Specify" name="Specify" key="entry.810220554" hideIf="true"}}
{{else}}
{{Gd-text-input label="Specify" name="Specify" key="entry.810220554" hideIf="false"}}
{{/if}}
This is pretty much the only way to do it, as the handlebars team has specifically left most logic out of the templates since it generally doesn't belong there. Which is debatable, as sometimes it makes things more complicated not to allow simple logic. But, this is very workaroundable.
The other answer does not work for Ember Handlebars, for your case you could do something like this.
http://emberjs.jsbin.com/agewuxAT/3/edit
Component
App.HideableCompComponent = Em.Component.extend({
isHidden: function(){
var prop = this.get('hideIfProperty');
if(!prop) return false;
// allow lazy comparison? up to you
return this.get('content').get(prop) == this.get('hideIfValue');
}.property('hideIfProperty', 'hideIfValue')
});
Template
<script type="text/x-handlebars" data-template-name="components/hideable-comp">
{{#unless isHidden}}
I am a component I am not hidden!
{{else}}
I am hidden
{{/unless}}
</script>
Usage
{{hideable-comp content=model hideIfProperty='length' hideIfValue=3}}

Categories