Ember trigger action on wrapper component - ember.js

I have a wrapper component that has an action that needs to be triggered from within, but I can't get rid of this:
{{#wrapper-component as |wrapper|}}
<button {{action 'wrapper.myAction'}}
{{/wrapper-component}}
the above is the template of "componentA"; when I click the button I get an error saying that componentA does not have an action handler for "wrapper.myAction"; I can't get why it looks for the action on componentA instead of wrapper-component first.
of course "myAction" is defined in "actions" on "wrapper-component";
the wrapper component has this template:
{{yield (hash myAction=(action 'myAction'))}}

Replace this:
<button {{action 'wrapper.myAction'}}
with this:
<button onclick={{action wrapper.myAction}}
please make sure you understand the difference between ember actions and closure actions.

Related

Ember, No action handler when passing action from template to component

I'm trying to pass an action from a route to a template and then a component.
app/routes/application.js
actions: {
showModal(context) {
console.log("This needs to be triggered" + context)
},
}
app/templates/application.hbs
{{some-component
showModal=showModal
}}
app/components/some-component/template.hbs
<button {{action "showModal" "The context for the action"}}>Press Me</button>
When running this. I get an error saying
"had no action handler for: showModal"
Although, when I include the action inside templates/application.hbs without passing it to a component everything works fine. It's just when passing the action to a component.
app/templates/application.hbs
<button {{action "showModal" "The context for the action"}}>Press Me</button>
This works. I want to call this action in a component though. How can I pass this action to the component?
Firing route actions is a little bit different than firing actions coming from a controller in this context. When you pass in an action to a component from a controller or another component you wrap it in the action helper like so:
{{some-component showModal=(action "showModal")}}
Since the action you're attempting to pass in lives in a route, you need to have to utilize the send method from the controller to call the action in the route. You pass it into the component like so:
{{some-component showModal=(action send "showModal")}}
Here's a twiddle that helps piece it all together.

How to make a component for modal box in emberjs?

I want to make a component which generates any number of buttons passed to it.
Now, the questions is how to pass the data about the button from template to component, so that the specified action will get called on click of the corresponding button.
You can pass buttons as array. Here is an example of how to render them. In component's template:
{{#each buttons as |button|}}
<button type="button"
class="{{button.className}} button"
onclick={{action button.action}}>
{{button.text}}
</button>
{{/each}}
Then, somewhere in template where you want to use your component:
{{your-component buttons=(array (className='green' text='Save' action=(action (mut variable) 'value')))}}
array helper is a part of ember-composable-helper

how to call action of route from component?

i have button in component
<button type="button" class="btn btn-sm btn-default" {{action "applyDateFilter"}}>GO</button>
Now i have written this action applyDateFilter in component.js like this
applyDateFilter() {
var variable = this.get('dateFilter');
this.sendAction('testAction2');
}
Now i have another action in main route.js file
testAction2: function(){
alert('test');
}
Now i want to call this route action from applyDateFilter action so how can i do this.I am using ember js version 2.10.
Thanks
option 1.You need to define action in controller, and use send method to call action in route.
testAction2(){
this.send('testAction2Route');
}
option 2.Install ember route action helper addon. and you can invoke it directly from component like the below,
<button type="button" class="btn btn-sm btn-default" {{route-action "applyDateFilter"}}>GO</button>
Note using route-action instead of usual action helper
Refer this answer for classic action and closure action and route action related stuff

Prevent click into {{input}} component from propagating/bubbling up (ember)

I have an {{input}} inside of an element that itself has an action.
How do I prevent clicking into the input from triggering the click event on the parent element?
I have tried bubbles=false.
I have also tried extending {{input}} and in the extended input I caught the click event and called event.preventDefault()
Please try my test case: https://ember-twiddle.com/a2cee9abd63a7400124e2745a7820cf8?numColumns=2&openFiles=controllers.application.js%2Ctemplates.application.hbs
Example hbs:
<div {{action "alert"}}>
I don't want the click into the input to trigger the div's onlick. Help!<br/>
{{input bubbles=false}}
</div>
Define component say my-input which extends Ember.TextField and define click function and return false to prevent bubbling.
import Ember from 'ember';
export default Ember.TextField.extend({
click(){
console.log('click my input');
return false;
}
});
For my-input component, you dont need to define anything to handle click event while including the component. you can just say {{my-input }}
Here is the working twiddle

where would I define this helper in Ember for handling site search functionality

I am just starting out with Ember and am curious if I had a template like the following:
<script type="text/x-handlebars">
<input type='text' id='myVal' /><button {{action "searchInventory"}} class='search_inventory'>search inventory</button>
{{outlet}}
</script>
Where would I define the searchInventory helper? It seems like it might be in some global controller that might forward it to a search results route; I have an InventoryItemController but how can I hook up the searchInventory action to this? What would be the Ember way to set this up?
Can I tell ember when invoking the action to use that controller like:
{{action "searchInventory" controller:"InventoryItem" }}
thx
I don't know how you have structured your app, but assuming you have a controller for the template above, you should define the action on that controller within an 'actions' hash. Also, you should use the
{{input}}
handlebars helper instead of using the input tag. If you do that, you can have a property on the controller for this template, say 'searchTerm' for which you can provide a valueBinding, like this:
{{input type="text" valueBinding="controller.searchTerm"}}
This will bind the input the user types into the input element to the searchTerm property on the controller. Hope this helps.