Handlebars - partial template not getting the context - handlebars.js

I have pre compiled all my templates into one js file and loaded the js in the page.
I have 3 templates
Template 1 - a.handlebars
<ul>
{{#each this}}
<li class="a">
{{#key}}
{{> b}}
</li>
{{/each}}
</ul>
Template 2 - b.handlebars
<ul>
{{#each this}}
<li class="b">
{{#key}}
{{> c}}
</li>
{{/each}}
</ul>
Template 3 -c.handlebars
<ul>
{{#each this}}
<li class="c">
{{ this }}
</li>
{{/each}}
</ul>
I have the following JS which load data to the template
var menu= {
a1:{
b1:[c1, c2, c3],
b2: [c4, c5, c6]
},
a2:{
b3:[c7, c8],
b4: [c9]
}
};
Handlebars.templates.a(menu);
The first template (a.handlebars) loads a1 and a2. But when the first template loads the partials b.handlebars it fails. I tried to put a log statement to see what is that I am getting for "this". I got 4 spaces and it was of type string.
I do not understand why b.handlebar is getting a string when I thought I will be getting (example for a1)
{
b1:[c1, c2, c3],
b2: [c4, c5, c6]
}
Previously,I did not pre compile the handlebars. I had all the handlebars in my html and compiled it using Handlebars.compile it worked fine. I do not know why the code is failing after per compiling.
Any help is highly appreciated.
I am trying to get his as my final result:
<ul>
<li class="a">a1
<ul>
<li class="b">b1
<ul>
<li class="c">c1</li>
<li class="c">c2</li>
<li class="c">c3</li>
</ul>
</li>
<li class="b">b2
<ul>
<li class="c">c4</li>
<li class="c">c5</li>
<li class="c">c6</li>
</ul>
</li>
<li class="b">b3</li>
</ul>
</li>
<li class="a">a2
<ul>
<li class="b">b3
<ul>
<li class="c">c7</li>
<li class="c">c8</li>
</ul>
</li>
<li class="b">b4
<ul>
<li class="c">c9</li>
</ul>
</li>
</ul>
</li>
</ul>
But I am getting this. Since the b.handlebars is not getting the object data.
<ul>
<li class="a">a1
<ul>
</ul>
</li>
<li class="a">a2
<ul>
</ul>
</li>
</ul>
My apologies for the very lengthy post. I have been trying to find a solution for this for a while now. Again, any help to resolve this issue would be great.
Thanks.

The issue was caused due to compiling the handlebar/template files using grunt.
Command: "grunt handlebars"
Once I compiled the files using handlers itself, the code started working.
Command: handlebars template_files -f output_file
If anyone knows how to make the compiled code work using grunt command I would definitely would like to know. Thanks.

Related

access parent sub array key handlbars

I have the following array / sub array structure
"filters": {
"types": {
"34": "Ford",
"22": "Jeep",
"18": "Porsche",
},
"locations": [
"Earth",
"Mars",
"Moon",
]
}
and the following handlebars template
{{#if filters}}
{{#each filters}}
<div class="cars">
<ul class="cars__list">
<li class="cars-{{#key}}__title">Filter by {{#key}}:</li>
<li class="cars-{{#key}}__filters">
<ul>
<li class="cars-{{#key}}">View All</li>
{{#each this}}
<li class="cars-{{*want to access filters[key]*}} color={{#key}}">{{this}}</li>
{{/each}}
</li>
</li>
</ul>
</div>
{{/each}}
{{/if}}
I'm having trouble accessing the filters[types] and filters[locations] within the each this loop.
In my CSS I'm using a classes called .cars-type and .cars-location. I want to be able to style each list separately and unfortunately target each li with a class. I want to apply these styles within the each this loop.
I can do it within the filters loop by using {{#key}} but not in the each this loop
I've tried
<li class="cars-{{../filters}}">{{this}}</li>
but this just returns the car type like ford - I want the key ie. '34' in this case
<li class="cars-{{lookup ../filters #index}}">{{this}}</li>
using handlebars helper lookup but again no luck
<li class="cars-{{../this}}">{{this}}</li>
and the above which gives me [object Object]
I've checked out handlebars - is it possible to access parent context in a partial?, handlebars.js: relative paths in partials not working and Lookup helper in handlebars but no luck with any of the solutions
EDIT Here's the HTML output that I want to produce
<div class="cars">
<ul class="cars__list">
<li class="cars-types__title">Filter by types:</li>
<li class="cars-types__filters">
<ul>
<li class="cars-types">View All</li>
<li class="cars-types color-34">Ford</li>
<li class="cars-types color-22">Jeep</li>
<li class="cars-types color-18">Porsche</li>
</ul>
</li>
</ul>
<ul class="cars__list">
<li class="cars-locations__title">Filter by locations:</li>
<li class="cars-locations__filters">
<ul>
<li class="cars-locations">View All</li>
<li class="cars-locations color-0">Earth</li>
<li class="cars-locations color-1">Mars</li>
<li class="cars-locations color-2">Moon</li>
</ul>
</li>
</ul>
</div>
You should reconsider your HTML because a ul cannot be a direct child of another ul. See https://developer.mozilla.org/en/docs/Web/HTML/Element/ul#Usage_context
With that said, we can solve your problem. The Handlebars docs have our answer:
Nested each blocks may access the interation variables via depth based
paths. To access the parent index, for example, {{#../index}} can be
used.
Therefore, your problematic line should look like the following:
<li class="cars-{{#../key}} color-{{#key}}">{{this}}</li>

Meteor's Blaze keeps re-using first list element's attributes

Using Meteor 1.2.02
I create a list with a helper:
<ul>
{{#each movie}}
<li id="{{_id}}">{{name}}</li>
{{/each}}
</ul>
The result:
<li id="1">Interstellar</i>
<li id="2">The Martian</i>
Then I hide Interstellar:
$("#1").hide();
Result:
<li id="1" style="display:none">Interstellar</li>
<li id="2">The Martian</li>
Then I remove Interstellar from the collection Movies.remove({name: "Interstellar"}) and this is what I end up with after Blaze reactively updates the DOM:
<li id="2" style="display:none">The Martian</li>
Does anyone know why now "The Martian" is inside the list element with display:none that belonged to Interstellar? I thought Blaze would have removed that first <li> elements and all its attributes. Thank you.

Meteor takes time to know if there's a {{currentUser}} or not

I've a few code that I want to run only when there's noUser and a few when there's a currentUser.
All these are inside the navigation template. Like so...
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{/if}}
{{#if noUser}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
So the problem is that when there's a currentUser(i.e, I'm logged in) and I refresh the page, the code inside the {{#if noUser}} block shows up first then the {{#if currentUser}} block, while the {{#if noUser}} block was only meant to show up when there is no user.
Here's the helper code for the template..
Template.navigation.helpers({
thisUser: function () {
return Meteor.user().username;
},
noUser: function () {
var user = Meteor.user();
if (!user) {
return true;
};
}
});
Don't know what am I doing wrong here. :(
Please help.
You should use if else conditions instead of noUser helper. And to prevent showing "noUser" block while logging in you have to use {{ loggingIn }} helper. Something like this:
{{#if loggingIn}}
<p>Loggin in...</p>
{{else}}
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{else}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
{{/if}}
Because Meteor does not know immediately whether user is logged in or not. Therefore you have to use loggingIn helper.
Why don't you refactor your code like this ?
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{else}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
You might want to have a look to http://docs.meteor.com/#meteor_loggingin to show a loading indicator if needed.

How to dynamically set a menu item class name with MVC4?

For a new application we are using Bootstrap v3.0, which has the navigation menu defined as follows:
<div id="sidebar">
<ul>
<li class="active"><i class="icon-home"></i> <span>Dashboard</span></li>
<li class="submenu">
<i class="icon-beaker"></i> <span>UI Lab</span> <i class="arrow icon-chevron-right"></i>
<ul>
<li>Interface Elements</li>
<li>jQuery UI</li>
<li>Buttons & icons</li>
</ul>
</li>
<li class="submenu">
<i class="icon-th-list"></i> <span>Form elements</span> <i class="arrow icon-chevron-right"></i>
<ul>
<li>Common elements</li>
<li>Validation</li>
<li>Wizard</li>
</ul>
</li>...
This is currently sitting in a shared _Layout.cshtml, and don't currently see a need to move this into its own shared view.
The layout template consists of several static files with <li class="active"> hard coded for the corresponding menu item within that file.
Since I'm building this with MVC4, I would like to know how to dynamically set this, based on the view being displayed.
Not sure best practice on this. You could try something like this:
<li class="#( RouteVariable.CurrentController.Equals("Home") ? "active" : "")">
Or RouteVariables.CurrentAction may be of use.

asp.net literal.text using multiple lines of html code

I am trying to initialize a literal with a big sequence of html code.
for example this is working just fine:
Literal1.Text.= "<ul><li>home<li/><ul/>";//just fine
But:
When i have more than one lines it doesn't work:
Literal1.Text.= "<ul><li>home
</li></ul>";//error
I know a simple solution which is this:
Literal1.Text.= "<ul><li>home"+
"</li></ul>";//nice but time wasting for many lines
But:
When i have 100 lines for example i don't want to spend my time concatenating the strings.Is there any more practical solution?
Specifically my html code is the folowing:
Literal1.Text.= "<ul id="nav">
<li class="current">Home</li>
<li>People
<ul>
<li>Customers
<ul>
<li>View</li>
<li>Edit</li>
<li>Print</li>
<li>Delete</li>
</ul>
</li>
<li>Employees
<ul>
<li>View</li>
<li>Edit</li>
<li>Print</li>
<li>Delete</li>
</ul>
</li>
</ul>
</li>
<li>Quotations
<ul>
<li>Create</li>
<li>Edit</li>
<li>View</li>
</ul>
</li>
<li>Invoices
<ul>
<li>Create</li>
<li>Edit</li>
<li>View</li>
</ul>
</li>
<li>Receipts
<ul>
<li>Create</li>
<li>Edit</li>
<li>View</li>
</ul>
</li>
<li>Statements
<ul>
<li>Create</li>
</ul>
</li>
<li>About Us</li>
<li class="style1">Contact Us</li>
</ul>";
For a small number of lines of code, I generally use StringBuilder. That way there are no performance issues with concatenating large immutable strings.
StringBuilder sb = new StringBuilder();
sb.Add("<ul><li>home");
sb.Add("</li></ul>");
For a large number of lines, don't put them in your code at all. Read them in using System.IO.File, so that you can edit your HTML without worrying about doubling your quotes. If you're using the code a lot, read it in once using a static class so that you're not causing a lot of extra IO usage. Something like this (untested):
public static class HTMLStringClass
{
private static string html;
public static string GetHtmlString()
{
if (string.IsNullOrEmpty(html))
html = File.ReadAllText("path/to/file");
return html;
}
}
And then call it by doing this:
Literal1.Text = HtmlStringClass.GetHtmlString();
Use a verbatim string literal (one that starts with #):
Literal1.Text = #"<ul><li>home
</li></ul>";

Resources