I'm using ember-easyForm and I have a non-submit button in the form which I want the parent view to handle.
my_view.hbs:
{{#form-for model}}
<button {{action "delete"}}>Delete</button>
{{/form-for}}
You used to be able to do:
<button {{action "delete" target="parentView"}}>Delete</button>
But it doesn't seem to work in the latest version of Ember.js. Is there any other way of passing the action to the parent view?
The following will get the form to handle the action but that's not what I want:
<button {{action "delete" target="view"}}>Delete</button>
Doing a bit more digging, I got the answer from this post. So this is how you do it:
<button {{action "delete" target="view.parentView"}}>Delete</button>
Which seems to be a better implementation than target="parentView", as you now, I presume, target the parent view of the parent view.
Related
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
I want to add an action to a {{link-to}} helper.
For example, in a modal component, I use {{link-to}} to open a new route. When the user clicks the link, I want to close the modal through an action.
One possible solution is to wrap an action around a {{link-to}}:
<button {{action "close"}}>
{{#link-to 'register'}}Registreer{{/link-to}}
</button>
Is this the best / cleanest solution possible? Or can I add an action to a link-to helper?
Another approach might be to transition and close in a custom action, but this approach is not
usable for use in a component:
// template.hbs
<button {{action "link" "register"}}>Registreer</button>
...
// template-controller.js
actions: {
link: function(routeName) {
this.transitionToRoute(routeName);
this.close()
}
}
You should do teardown operations such as closing modal boxes within the willDestroyElement event of your current view.
By doing this, you could just {{link-to 'register'}} and let your view (template-view.js) manage the fact that there is a modal to close or not.
Checkout the docs of willDestroyElement HERE
Template:
{{#each document in documents}}
<div class="col-md-6" {{action "selectDocument" document}}>{{view Ember.Checkbox checked=document.isSelected}} {{document.name}}</div>
{{/each}}
Controller:
App.IndexDocumentsController = Ember.ArrayController.extend({
actions: {
selectDocument: function(document){
document.set('isSelected', !document.get('isSelected'));
}
}
});
When I click on the div, the checkbox toggles 'checked' property. But when I click on the ckeckbox - nothing happens. What can be the reason?
UPDATED
Link to jsbin: http://emberjs.jsbin.com/nuvocumuteto/1/edit?html,css,js,output
The issue is that when you click on the checkbox 2 things happen.
the checkbox toggles the isActive property, then
the selectRow action is ran which again toggles the isActive property
So the isActive property ends up staying in the same state that it was.
In your case I would get rid of the action, wrap the checkbox in a <label> and set the label to display: block.
The template would look like
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li {{bind-attr class="item.isActive:active"}}><label>{{input type="checkbox" checked=item.isActive}}{{item.name}}</label></li>
{{/each}}
</ul>
</script>
and the css would look like
label {
display: block;
}
you would then be able to get rid of the selectRow action completely because clicking on the label will trigger the checkbox.
You can see a working bin here: http://emberjs.jsbin.com/nuvocumuteto/3/edit
I would argue that you are not following "The Ember Way" in two different ways here.
First, Ember.Checkbox is an internal Ember class (http://emberjs.com/api/classes/Ember.Checkbox.html). The recommended way to render a checkbox is to use the Handlebars input helpers (http://emberjs.com/guides/templates/input-helpers/#toc_checkboxes). This is just wrapping Ember.Checkbox anyway.
Second, if you want to update the value of isSelected, the "Ember Way" is to use two-way data bindings. Your code uses one-way data-binding when it reads document.isSelected and then tries to manually re-create the the data-binding in the other direction when the user clicks by manually writing a selectDocument action and calling it from an {{action}}.
Instead, simply bind the Ember Handlebars Input Helper directly to your value like this:
{{#each document in documents}}
<div class="col-md-6">{{input type="checkbox" checked=document.isSelected}} {{document.name}}</div>
{{/each}}
I want to use itemcontroller to a render a list of comments as well as perfom CRUD on the comment. The CRUD aspect works fine. But there are two things not working wekll and they are described below. Here is the jsfiddle.
Just click on the add Comment button to see it add an additional edit form underneath the existing one.
When I click on the button to create newComment which uses the CommentNewController, it automatically also renders EmBlog.CommentEditController and comment edit form along side the form for new comment. Both forms are independent of each and use different controllers and templates, so I don't understand why rendering the form for newComment automatically adds an empty form for editComment.
The second issue is that I have an edit button which is surrounded by an #if helper. If the #if helper is true then the edit form should be displayed. To toggle the #if helper to true, I created a button that contains the {{action editComment }}. When I click the button, the edit form is not rendered. But note that, when the template first renders, it automatically displays an edit form, even when the edit button has not been clicked.
Relevant template and controllers ares pasted below.
It is when the post/show template renders that an edit form is automatically displayed without waiting for an edit button to be clicked, which sets the #if helper to true
<script type="text/x-handlebars" data-template-name="posts/show">
//displays the add button link
{{render 'comment.New' }}
<br/>
**render the comments and use CommentEdit as itemController**
{{render 'comments' comments}}
</script>
Comments Template
<script type='text/x-handlebars' data-template-name='comments'>
<ul>
{{#each controller itemController="CommentEdit"}}
<li>{{body}}</li><br/>
{{partial 'comment/edit'}}
{{/each}}
</ul>
</script>
It seems this #if helper is bye-passed as the form is rendered without clicking edit button and when you click edit button, it does nothing
<script type='text/x-handlebars' data-template-name='comment/_edit'>
{{#if controller.editComment}}
{{#if model}}
<form {{action save content on='submit'}}>
{{view Ember.TextArea valueBinding="content.body" placeholder="body"}}
<button type="submit"> save comment </button>
<button {{action cancel content}}> Cancel</button>
</form>
{{/if}}
{{/if}}
<br/>
<div>
<button {{action editComment }} {{bindAttr disabled="isEditingComment"}}> Edit Comment</button>
When you click on the addComment button, it adds a new empty edit form but it shouldn't even be calling the edit form
<script type='text/x-handlebars' data-template-name='comment/new'>
{{#if controller.isAddingNew}}
{{partial 'comment'}}
{{/if}}
<div>
<button {{action addComment}} {{bindAttr disabled="isAddingNew"}}>Add Comment</button>
</div>
</script>
The comment partial for adding new comment
<script type='text/x-handlebars' data-template-name='_comment'>
<form {{action save content on='submit'}}>
<button {{action cancel content}}> Cancel</button>
</form>
</script>
The controllers
EmBlog.CommentNewController = Em.ObjectController.extend({
needs: ['postsShow'],
isAddingNew: false,
addComment: function(){
this.set('isAddingNew', true);
}
});
EmBlog.CommentEditController = Em.ObjectController.extend({
isEditingComment: false,
editComment: function() {
this.set('isEditingComment', true);
}
});
EmBlog.CommentsController = Em.ArrayController.extend({
needs: ['postsShow'],
itemController: 'CommentEdit'
});
Thanks.
working jsfiddle based on mike's answer. Update the ember-data implementation to use Emberjs1.0Rc-6 and the CommentNewController now using Kris Seldon's buffered save as explained here, to avoid error: Attempted to handle event willSetProperty rootState.loaded.updated.inFlight. Thesame code but using ember-model as datastore instead of ember-data: http://jsfiddle.net/TVe4X/4/ and updated to use Emberjs 1.0.0-RC6 and current ember-model : http://jsfiddle.net/tHWM4/5/
When I click on the button to create newComment which uses the CommentNewController, it automatically also renders EmBlog.CommentEditController and comment edit form along side the form for new comment. Both forms are independent of each and use different controllers and templates, so I don't understand why rendering the form for newComment automatically adds an empty form for editComment.
When you click newComment, a new (unsaved) comment is created. Since your comments template uses the each helper to loop over all comments, it is updated to have a new entry. You could get around this by filtering the list based on model state (ie show if isNew), hiding new comments via css or better yet refactor to show the new-comment-form inline. Of course the comment body is blank so you normally would just see a new bullet. But the edit form shows up as well, because of the issue below.
The second issue is that I have an edit button which is surrounded by an #if helper. If the #if helper is true then the edit form should be displayed. To toggle the #if helper to true, I created a button that contains the {{action editComment }}. When I click the button, the edit form is not rendered. But note that, when the template first renders, it automatically displays an edit form, even when the edit button has not been clicked.
Agreed the {{#if editComment}} helper is not working - it always evaluates to true. This is because editComment is a function not a property. Instead you probably want to reference the property isEditingComment.
Updated jsfiddle here: http://jsfiddle.net/mgrassotti/TVe4X/1/
The jsfiddle.
From the posts#index template, I can create a new comment by using the #linkTo helper which goes to the PostNewComment Route and renders the post/newcomment form. If I click save the newly created comment is persisted using the 'save event' inside the PostNewComment Route.
You can uncomment the line below in post/comments" template, to see it working
{{#linkTo "post.newComment"}} Add comment{{/linkTo}}
I changed my UI to use a controller isAddingNew button and the render helper to determine When to display the form and now if I click the save button, I get:
Uncaught TypeError: Cannot call method 'one' of null
This how I render it:
<p> {{render "post.newComment" }} </p>
I suspect it is a scope issue because the error is only triggered when 'save' is clicked after using the render helper.
To reach the 'add new comment' button:
click -> post -> a post title -> click comments link -> add comment
Is there a way to make the 'Post/newComment form' displayed via the 'render helper' in the post/comments template to use the 'save event' defined in the PostNewComment Route.
Right now clicking on the 'save button' which is defined in that form goes directly to the parent route ie PostCommentsRoute instead of going to its own route probably because I displaying the form via the render helper.
I thought calling 'save' should go to its own controller and then bubble to its own route where it is actually defined, before attempting to bubble up the hierarchy to the PostComments Route.
There's probably a few alternatives, but this works and is pretty idiomatic: http://jsfiddle.net/GabSY/4/
In particular:
{{#if model}}
<form {{action save content on='submit'}}>
{{view Ember.TextArea valueBinding="content.body" placeholder="body"}}
<button type="submit"> save comment </button>
<button {{action cancel}}> Cancel</button>
</form>
{{else}}
<button {{action open}}> Add comment </button>
{{/if}}
The reason you were getting the Uncaught TypeError: Cannot call method 'one' of null error was that the PostNewCommentController's model was never set. What I ended up doing was using the open action on the PostNewCommentController to set the model of the controller, which can be used in a Handlebars {{if}} to determine whether the form should be displayed or not.
I prefer this approach to the alternative of setting content/model (they are aliases to each other) of the PostNewCommentController from within the PostCommentsRoute's setupController method because if you go down that route, it's easy to start mixing concerns between not-very-related controllers and routes. In my approach, all the logic for setting the content/model of the new comment takes place in the controller for new comments, which makes sense since a new comment no longer has its own route to initialize this data.