Action helper won't work inside handlebar's {{#if}} - javascript

I have a machine_list_item.html template which contains this piece of code:
{{#if view.machine.isGhost}}
<div class="remove-machine-key-association">
<button {{action "aloha" target="view"}}></button>
</div>
{{/if}}
And I have this function inside machine_list_item.js view:
aloha: function() {
alert('Tadah!');
}
The button won't call the function and will give this error:
Error: assertion failed: The action 'aloha' did not exist on Mist.MachineListItemView
However, if I comment out the handlebar's {{#if}} structure, the code will work just fine.
Any help will be appreciated!

Using {{#linkTo}} ... {{/linkTo}} implicitly creates a view. Many handlebars blocks do this. So anything inside the ... that refers to view is actually referring to the LinkToView.
To fix this, rename your view using {{#with ... as ...}} so that it doesn't get shadowed.
{{#with view as myView}}
{{#linkTo 'machine' myView.machine}}
{{#if myView.machine.isGhost}}
<div class="remove-machine-key-association">
<button {{action "aloha" target=myView}}></button>
</div>
{{/if}}
{{/linkTo}}
{{/with}}
See this question for more details.

I guess you have somewhere else a problem, here a simple example how it works correctly: http://jsbin.com/IhojaYE/2/edit
Hope it helps.

Related

How i can create dynamic accordion component EmberJS

I found a ready accordion solution. I tried to use it, but I don't know how to give this component a variable number of records:
My component template:
{{#search-results-accordion
currentPage=currentPage
totalPages=meta.totalPages
items=items
onPageChange=(action "onPageChange")
as |item|
}}
{{requisite-accordion-item item=item}}
{{else}}
...
{{/search-results-accordion}}
Parent's template(search-results-accordion):
{{#if (gte items.length 1)}}
<div class="items" data-test-search-results>
{{#cp-panels accordion=true as |panels|}}
{{#each items as |item index|}}
{{yield item panels=panels}}
{{/each}}
{{/cp-panels}}}
</div>
...
{{/if}}
Child's template(requisite-accordion-item):
{{#panels.panel as |panel|}}
{{#panel.toggle}}
<p>Panel A</p>
<div class="name"><b>{{item.name}}</b></div>
{{/panel.toggle}}
{{#panel.body}}
{{item.info}}
{{/panel.body}}
{{/panels.panel}}
Then I get EmberError in console: "Assertion Failed: A helper named "panels.panel" could not be found"
enter image description here
How I can use this for variable amount of records?
Here are my observation in your code,
In search-results-accordion.hbs, instead of {{yield item panels=panels}} say {{yield item panels}}.
But you are receiving only item in components template but you should receive item,panels and include both arguments to requisite-accordion-item item=item panels=panels}}
I haven't used this addon. For debugging, you can try {{log 'panels object' panels}} that will print object in console.

How do I pass template variables in Meteor?

I couldnt find an answer for this but I've seen it before.
I want to render a template with a varable set from html and have access to it in js as well. Here's a simple example that covers both of these cases.
<template name="a">
{{>b param="hello"}}
</template>
<template name="b">
{{param}} {{param2}}
</template>
Template.b.param2 = function() {
if (this.param == "hello") {
return "world"
}
}
This doesnt seem to work though.
EDIT:
Well that all works apparently. I didnt include the #each:
<template name="a">
{{>b param="hello"}}
</template>
<template name="b">
{{#each something}}
{{param}}
{{/each}}
</template>
I think thats what's causing the problem. (sorry this example is a little contrived)
So this was king of a bad question but maybe it will save someone some trouble.
For the #each issue, the solution is to do {{../param}} which I found in another question.
However, this didnt work for me because I am using Autoform in which case I actually had to do {{../../param}}.

Ember {{#with ... controller=...}} gives "Uncaught TypeError: Cannot read property 'lookupFactory' of undefined"

I'm trying to access properties of a controller (actually a mixin extended by a controller) in Ember, and I need to use the {{#with}} handlebars helper. I get the error:
Cannot read property 'lookupFactory' of undefined
The place I'm trying to specify the controller for each looks like this:
{{#with orders.order controller='ordersIndex'}}
I have also tried just about every combination I can think of:
{{#with orders.order controller='orders'}}
{{#with orders.order controller='Orders'}}
Tried specifying the controller for the route that seems to work:
{{#with orders.order controller='brokerageAccount'}}
{{#with orders.order controller='BrokerageAccount'}}
{{#with orders.order controller='Brokerage'}}
No luck with any of them.
All Code is in JSBin:
http://emberjs.jsbin.com/cabak/1/edit?html,js
Output view of the two routes:
Broken one: (here if you open the console, you'll see the error)
http://emberjs.jsbin.com/cabak/1#/orders
This one works: you'll see some data.
http://emberjs.jsbin.com/cabak/1#/orders/tradier/12345
I guess there is a bug with the {{with}} helper, because if you use the {{#each elem in model}} and update the {{with}} to use the elem variable: {{#with elem.orders.order controller='ordersIndex'}} all works.
This is the updated orders/index template:
<script type="text/x-handlebars" data-template-name="orders/index">
<div class="inline-headers">
<h4><label>Brokerage: </label>{{titleize brokerage}}</h4>
</div>
{{#each elem in model}}
<h4 class="account-header"><label>Account: </label>{{account_number}}</h4>
{{#with elem.orders.order controller='ordersIndex'}}
{{partial "_orders_table"}}
{{/with}}
{{/each}}
</script>
And this is the updated jsbin http://emberjs.jsbin.com/piwuyare/1#/orders

EmberJS Handling DOM Events using Views

I want to toggle a single form (see picture below) using views.
My code basically works when i add new formset it adds an empty bracket to json and then i
print the json out using eachloop
View template
{{#each view.anotherField}}
<div class="panel panel-default">
{{action 'toggleView' 'toggleViews' target='view'}}
...
</div>
{{#unless view.toggleViews}}
...content to toggle...
{{/unless}}
View controller??
actions: {
showMoreFields: function(){
this.get('anotherField').pushObject({name: ''});
,
toggleView: function(param){
this.toggleProperty(param);
}
In this given picture u can see ive toggled organization view to truth what i would like is to toggle only the clicked part not all of the forms. Is there a solution ?
Cheers,
Kristjan
If I understand correctly you need to handle events for specific parts/forms of your view. To achieve this there are at least three approaches,
1.Use the {{action}} helper passing the object you want to modify. Then in your function modify a property of that object and reflect that in your template e.g. toggle the form. Maybe in your case it could be something like ,
....
{{#each field in view.anotherField}}
<div class="panel panel-default">
{{action 'toggleView' field target='view'}}
....
2.Make a sub view/template (e.g. SubFormView) to accomodate each of your forms and handle the event of toggle within this view. Then include this via the {{view}} helper within the template of your main view.
3.Use pure js DOM handling (no {{action}} helper) and call your ember components from there.
Example of approaches 1 and 3 can be found here,
http://emberjs.jsbin.com/acUCocu/1
hbs
<script type="text/x-handlebars" data-template-name="index">
<i>using <b>{{action}}</b> helper</i>
<ul>
{{#each color in model}}
<li {{action 'test' color}}>{{color.name}}</li>
{{/each}}
</ul>
<i>using pure js DOM event handling</i>
<ul>
{{#each color in model}}
<li onclick="Ember.View.views[$(this).closest('.ember-view').attr('id')].controller.send('test2',this)">{{color.name}}</li>
{{/each}}
</ul>
</script>
js
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return colors;
},
actions:{
test:function(param){
alert('this is color:'+param.get('name')+" ("+param+")");
},
test2:function(elem){
alert('from pure js, clicked element: '+elem);
$(elem).css('color','red');
}
}
});
App.Color = Ember.Object.extend({
name:null
});
var colors=[];
colors.pushObject(App.Color.create({name:'red'}));
colors.pushObject(App.Color.create({name:'green'}));
colors.pushObject(App.Color.create({name:'blue'}));

If statement within another if statement in Handlebars templates

These are all objects which I am passing to the handlebars template.
self.template = template({ data: self.model, lang:self.lang, page:self.mainPage, subpage:self.param });
Then inside foreach loop I have an if statement where I am not able to access the parent context element. The code which i have inside the template and the problem is shown bellow:
{{#each data}}
<h1>{{../subpage}}</h1> --> This is giving me a subpage value
{{#if this.brand}}
{{#if ../subpage}}
<h1>WHY IS THIS NOT SHOWING?</h1> --> This is what i am trying to achieve
{{/if}}
{{/if}}
{{/each}}
Any ideas how to achieve this? Thank you very much for all answers/comments!
{{#if this.brand}} goes down into context another level, so you must escape to the parent context not once, but twice.
Your template should thus be:
{{#each data}}
<h1>{{../subpage}}</h1>
{{#if this.brand}}
{{#if ../../subpage}}
<h1>This shows now!</h1>
{{/if}}
{{/if}}
{{/each}}
This should work with a self.model value similar to:
[
{
brand: "Brand A",
otherFields: "here"
}
]
Here is a jsFiddle that demonstrates the solution: nested if statement context escaping
I hope that helps!

Categories