Chaining conditions using meteors' currentUser helper - meteor

I am using the currentUser helper in m template file and i was wondering whether how i can achieve this.
<h5 class="panel-title"> {{#if currentUser.profile.userrole = 'schooladmin' or 'teacher' or 'student' or 'parent' or 'superadmin'}} Academic Years {{/if}}</h5>
I want to chain using if using the or statement.
The above chaining causes this error
Can't have a non-keyword argument
after a keyword argument
How can i correct this?.

Instead of doing all this in Blaze, just make a helper and call that in your view.
Template.xxx.helpers({
customLogic: function() {
return (Meteor.user().profile.userrole === 'schooladmin' || other logics);
}
});
{{#if customLogic}}
Academic Years
{{/if}}

I have dined a global helper
Template.registerHelper("custom", function() {
return (Meteor.user().profile.userrole === 'schooladmin' || 'teacher' || 'student' || 'parent' || 'superadmin');
});
and used it like so
<h5 class="panel-title"> {{#if custom}} Academic Years{{/if}}</h5>

Related

Using an "if not x" statement in an HBS template file

How can I write an if not x statement in an HBS template file?
At present, I use an if/else clause in order to achieve that:
{{#if x}}
{{else}}
Some Text
{{/if}}
Is there a way to simplify this and use a single if statement?
I've tried stuff like {{#if !x}} and {{#if ^x}}, but it didn't work of course.
Looking on the web for HBS logical operators, I couldn't quite find the syntax for a logical-not.
Update
I should emphasize that in my case x is undefined.
I've learned it "the hard way", while trying:
{{#if not x}}
Some Text
{{/if}}
Which threw TypeError: Cannot read property 'includeZero' of undefined.
Have you tried unless?
<div class="entry">
{{#unless license}}
<h3 class="warning">WARNING: This entry does not have a license!</h3>
{{/unless}}
</div>
You can use the unless helper as the inverse of the if helper. Its
block will be rendered if the expression returns a falsy value.
https://handlebarsjs.com/builtin_helpers.html
You can also considers custom helpers:
Handlebars.registerHelper("ifNot", function(a, options){
if (!a) {
return options.fn(this);
}else{
try{
return options.inverse(this);
}catch(e){
//no else statement
}
}
});

Reuse Meteor template as inclusion with different helpers

I'd like to re-use a Meteor template as an inclusion (i.e. using {{> }}) in two different contexts. I know I can pass in different data with the inclusion by using {{> templateName data1=foo data2=bar}}, but I'm struggling to figure out how I can provide different helpers based on the context. Here's the template in question:
<template name="choiceQuestion">
<div class="choice-grid" data-picks="{{numberOfPicks}}" data-toggle="buttons">
{{! Provide for the user to make multiple selections from the multiple choice list }}
{{#if hasMultiplePicks}}
{{#unless canPickAll}}<span class="help-block text-center">Pick up to {{numberOfPicks}}</span>{{/unless}}
{{#each choices}}
<label class="btn btn-default"><input type="checkbox" class="choice" name="{{this}}" autocomplete="off" value="{{this}}" checked="{{isChecked}}"> {{this}}</label>
{{/each}}
{{/if}}{{! hasMultiplePicks}}
{{#if hasSinglePick}}
{{#each choices}}
<label class="btn btn-default"><input type="radio" class="choice" name="{{this}}" id="{{this}}" autocomplete="off" value="{{this}}" checked="{{isChecked}}"> {{this}}</label>
{{/each}}
{{/if}}{{! hasSinglePick}}
</div>
</template>
and here's how I've reused it:
{{> choiceQuestion choices=allInterests picks=4}}
The key component of the template is a checkbox. In one context, it will never be checked. In another, it may be checked based on the contents of a field in the user document. I've added checked={{isChecked}} to the template. I've read this boolean attribute will be omitted if a falsey value is returned from the helper which should work well for my purposes.
The template's JS intentionally does not have an isChecked helper. I had hoped I could provide one on the parent where the template is included in the other context in order to conditionally check the box by returning true if the checked conditions are met, but the template doesn't acknowledge this helper.
Here's the template's JS:
Template.choiceQuestion.helpers({
hasSinglePick: function() {
return this.picks === 1;
},
hasMultiplePicks: function() {
return this.picks > 1 || !this.picks;
},
numberOfPicks: function() {
return this.picks || this.choices.length;
},
canPickAll: function() {
return !this.picks;
},
});
and the parent's JS:
Template.dashboard.helpers({
postsCount: function() {
var count = (Meteor.user().profile.posts||{}).length;
if (count > 0) {
return count;
} else {
return 0;
}
},
isChecked: function() {
return (((Meteor.user() || {}).profile || {}).contentWellTags || []).indexOf(this) > -1 ? 'checked' : null;
}
});
Template.dashboard.events({
'click .js-your-profile-tab': function(){
facebookUtils.getPagesAssumeLinked();
}
});
I've tried a few other approaches as well. I tried passing the helper to the template along with the other context (i.e. {{> templateName data1=foo data2=bar isChecked=isChecked}}. This kinda works, but it calls the helper immediately. This breaks these since I need to use a value from the context to determine what to return from my helper. Since this value doesn't exist when the function returns, the function always returns undefined.
If I return a function from this helper rather than the value and then pass the helper into the template inclusion along with the data context, I get better results. In fact, my console logs show the desired output, but I still don't end up with the checked box I expect.
Here's what that looks like. Returning a function:
isChecked: function() {
var self = this;
return function() {
return (((Meteor.user() || {}).profile || {}).contentWellTags || []).indexOf(this) > -1 ? 'checked' : null;
};
}
and passing that to the template:
{{> choiceQuestion choices=allInterests picks=4 isChecked=isChecked}}
Is there an established pattern for overriding template helpers from the parent or for including helpers on the parent that are missing from the child template? How can I achieve this?

if else in handle bar template

In need to check this scenario using handle bar templates
if(data.Id==1 && Isreal==false)
{
//`enter code here
}
else if(data.id==2 && IsReal==true)
//other html
else
`//enter code here`last html
How can I do that, I tried using helper but it is not working in my case
Best practice is to not do any business logic in the template but instead do it before and pass it through the context into the template.
i.e.
var context = {
dataOneNotReal = data.Id==1 && Isreal==false,
dataTwoIsReal = data.id==2 && IsReal==true
};
then in the template
{{#if dataOneNotReal}}
// code
{{else}}
{{#if dataTwoIsReal}}
// code
{{else}}
// code
{{/if}}
{{/if}}

How to use and condition in if statement on meteor template?

I want to use the and condition in if statement like
{{#if requiredExp equals 0 and tile equals "SSE"}}
Expierince cannot be equal to 0
{{/if}}
How to write this condition using and in meteor template?
Meteor is designed in a way that you can't put logic in your templates. You can create a simple helper like equals, but you cannot use logic operators like && and || in templates because this logic does not belong to templates.
You could create a global template helper equals for this:
Template.registerHelper('equals', function(param1, param2) {
return param1 === param2;
});
So you can use it in your templates:
{{#if equals requiredExp 0}}
{{#if equals tile "SSE"}}
Expierince cannot be equal to 0
{{/if}}
{{/if}}
Or, the better option is to create a helper that handles the logic you want:
Template.yourTemplateName.helpers({
showExperienceNotification: function() {
return this.requiredExp === 0 && this.tile === 'SSE';
}
});
And use it in your template:
<template name="yourTemplateName">
{{#if showExperienceNotification}}
Experience cannot be equal to 0
{{/if}}
</template>
You can access template data via keyword this in your helper:
this.requiredExp and this.tile. Read more about Meteor templates and data context: https://www.discovermeteor.com/blog/a-guide-to-meteor-templates-data-contexts/

Meteor: getting the HTML element which is using a global helper

Is it possible to know the HTML element which is invoking a global helper?
I have this blaze template:
<template name="tools">
<div>
<a id="pencil" class="{{toolIsActive}}">Pencil</a>
<a id="shape" class="{{toolIsActive}}">Shape</a>
<a id="poly" class="{{toolIsActive}}">Polygon</a>
<a id="arrow" class="{{toolIsActive}}">Arrow</a>
</div>
</template>
and so it'd be useful a helper like this:
UI.registerHelper('toolIsActive', function() {
return (this.id === currentTool) ? 'active' : '';
});
where I want this to be the invoking HTML element instead of template's data context.
Is there a way to access the element? I know I could use this.$('#pencil') but it's useless since the id it's exactly what I want to know.
You can work around this problem by passing the tool name as an argument for the helper:
<a id="pencil" class="{{toolIsActive 'pencil'}}">Pencil</a>
UI.registerHelper('toolIsActive', function(tool) {
return (tool === currentTool) ? 'active' : '';
});
Since this sort of helper is useful in many different parts of the application, you can make an universal one instead:
<a id="pencil" class="{{classIfEqual 'pencil' currentTool 'active'}}">Pencil</a>
UI.registerHelper('classIfEqual', function(a, b, className) {
return (a === b) ? className : '';
});
Another approach, which could make it easier to add more tools in the future:
<template name="tools">
<div>
{{#each tools}}
<a id="{{id}}" class="{{toolIsActive}}">{{humanName}}</a>
{{/each}}
</div>
</template>
Template.tools.helpers({
tools: [
{id: "pencil", humanName: "Pencil"},
{id: "shape", humanName: "Shape"},
{id: "poly", humanName: "Polygon"},
{id: "arrow", humanName: "Arrow"}
],
toolIsActive: function() {
return (this.id === currentTool) ? "active" : ""
}
});
You could potentially use that tools structure in multiple places, and then if you want to add more tools, you only have to add it in one place.

Resources