Isolating template regions in meteor for easier DOM navigation - meteor

It is very useful to use template.find to locate DOM elements inside a specific template instance. But what happens when the template iterates {{#each}} over some tags without using a sub-template?
<template name="top">
{{#each items}}
<img src="{{src}}">
Click me
{{/each}}
</template>
Tempalte.events(
'click a': (event, template) ->
template.find('img') # This doesn't do the trick
# Is there a better way?
)
Is there a way to easily access the img element associated with the click event?
I know I can use event.target or create another template an use it inside the {{#each}} block. I wonder if there is a better/shorter way to do it.

You could add an #index to the img to make it possible to select it (using js or CSS). How to get index in Handlebars each helper?

Related

What's a clean way to have a conditional container in handlebars?

When there is a link present, we want something like this HTML:
<img src="{{src}}"></img>
When there is no link present, we want something like this HTML:
<img src="{{src}}"></img>
Is there a clean way to do this? I consider the following solution bad, because it's dangerous to have to separately remember to open and close the <a> tag:
{{#if url}}<a href="{{url}}" title="{{title}}" target="_blank">{{/if}}
<img src="{{src}}">
{{#if url}}</a>{{/if}}
I considered using a block helper, but can't think of how to do so without adding more complexity. Maybe something like:
{{#linkWrap url}}<img src="{{src}}">{{/linkWrap}}
But then it's hard to see how we set the title and target and everything gets awkward.
I think you are on the right track, but I would recommend using a Handlebars Partial Block instead of a Block Helper. This will allow to pass one piece of template (the block) to another piece of template by which it will be wrapped (the partial).
Handlebars provides us with {{> #partial-block }} as a way to render a block of template within a partial. We can use this to create our "linkWrap" partial:
{{#if link}}
<a href="{{link.url}}" target="{{link.target}}" title="{{link.title}}">
{{> #partial-block}}
</a>
{{else}}
{{> #partial-block}}
{{/if}}
This gives us a clean and simple partial that will allow us to wrap any section of our template with a link as long as we have a link object to pass to our partial. Note that I have opted to use an object to represent the link so that I can pass a single parameter to the partial instead of passing the url, title, etc. properties individually.
For anywhere we wish to render a link around some markup in our template, we can do so in the following way:
{{#> linkWrap link=link}}
<img src="{{image.src}}">
{{/linkWrap}}
If the link object is null or undefined, the img element will be rendered without a parent anchor element.
I have created a supplementary fiddle for reference.

Meteor - sergeyt:typeahead - Not injecting when inside an {{#each}}

I have several instances of sergeyt:typeahead working in my webapp. However today I am building a table out of data from query. One of the columns needs to allow for possibly selecting from a collection or if the user wants to enter their own value.
This has worked for me in other parts. Now it appears that when using an {{#each}} statement in the html and when the typeahead is inside the {{#each}} that it does not receive the injecting.
I believe this may be due to the fact that inject is typically done on the rendered which is run before the {{#each}} has run and created the dom elements. And if that is the case how would I go about then placing the inject on these newly generated elements?
You should be able to create a sub template for each stop:
<template name='myApp'>
{{#each stops}}
{{> stop}}
{{/each}}
</template>
<template name="stop">
<input class="form-control typeahead" ...>
</template>
This way you can call typeahead.inject on each instance after it is rendered.
Template.stop.onRendered(function() {
Meteor.typeahead.inject();
});

Handlebars- block helper inside block helper

I'm new to Handlebars and I wanted to know if I can use block helper inside a block helper, something like this:
{{#each person}}
{{each family_member}}{{family_relation}}
{{/family_member}}
{{/person}}
I've tried to do it with a simple helpers in http://tryhandlebarsjs.com
and it didn't work, but I couldn't find any place saying if it can work or not....
any help?
Thanks
You can use block helpers inside block helpers. Provided they are used the correct way.
{{#each person}}
{{#each family_member}}
{{family_relation}}
{{/each}}
{{/each}}
You can actually see a plunkr here : http://plnkr.co/edit/H9XlaQG99etHb4Fwx9pp?p=preview

Meteor: Passing array parameter to template

I'm trying to pass an array to another template in Meteor.
Why? Because I would like to create a small template for each Bootstrap element, allowing me to reuse components much more easily.
{{> dropdown id="dropdown1" textDropdown="My dropdown!" listItems=["item1", "item2"] }}
This does not seem to work unfortunately.
Any clue? Does what I'm doing even make sense? I'm new to Meteor.
Thanks!
Spacebars is currently pretty limited in what it can accept - you'll need to add a helper to accomplish this:
Template.myTemplate.helpers({
listItems: ['item1', 'item2']
});
And them modify your template:
{{> dropdown id="dropdown1" textDropdown="My dropdown!" listItems="{{listItems}}"}}
Make sure to update myTemplate to the parent template's name.

Meteor: templates included in markdown do not call onRendered hook

I use markdown in a template, and include another template in markdown, as follows:
<template name="hello">
{{#markdown}}
{{> subtemplate}}
{{/markdown}}
</template>
<template name="subtemplate">
<p>Something to show</p>
</template>
Then in javascript, I have:
Template.subtemplate.onRendered(
function() {
console.log("Visited");
return;
}
)
On the page, I do see "Something to show". However, the onRendered hook is not called, as I don't see "Visited" in the console.
If I move the subtemplate outside markdown:
<template name="hello">
{{#markdown}}
{{/markdown}}
{{> subtemplate}}
</template>
I do see the "Visited" in the console.
So, anyway to trigger onRendered hook inside markdown?
Unfortunately there's currently no way to put a template inside markdown helper and have it work interactively. It also applies to event handlers not only onRendered hooks.
The reason this is happening is that what markdown effectively does is it transfer all it's contents to text, then it passes it through a markdown parser and finally renderers the resulting text. The consequence is that the structure of your views get lost in the process.
In fact, the helper was not designed to handle a lot of html content inside of it. Instead you should probably pass only single chunks of text to the markdown helper and try to avoid putting templates inside if they contain some additional logic apart from rendering stuff, e.g. event handlers.

Resources