How to pass parameters with the action Helper of Ember.js? - javascript

I have a list of items:
<ul>
{{#each applications}}
<li>
<a {{bindAttr href="url"}}
{{action "appClicked" on="click"}}>
{{name}}
</a>
</li>
{{/each}}
</ul>
On click it calls the method appClicked of the view, that this template belongs to. I want to pass some information (for example, the name of the application) to the method appClicked. Something like, {{action "appClicked(name)" on="click"}}.
Is it possible, and how?

Apparently, Ember has evolved now and there is an ability to pass a parameter to an action:
{{action "functionName" parameter}}
In your case, that would be:
<a {{bindAttr href="url"}}
{{action "appClicked" name on='click'}}>
{{name}}
</a>
However, you could pass any attribute from the model (like the id) instead of the name.
See http://emberjs.com/guides/templates/actions/ for more information.

The API says you can pass in multiple parameters.
html and handlebars:
{{officename}}
<button {{action "actionTest" "hello" "goodbye" officename}}>See parameters through action in the console</button>
controller:
actionTest: function(a, b, c){
console.log(a);
console.log(b);
console.log(c);
},
See it in action in this jsbin

I was thinking something more along the lines of this since you'll have access to a bunch more through an actual view. But Zack, if you could explain a bit more what exactly you're trying to do if this isn't what you're looking for?
App = Ember.Application.create();
App.peopleController = Ember.ArrayController.create({
content: [ { name: 'Roy', url: '#' },
{ name: 'Mike', url: '#' },
{ name: 'Lucy', url: '#' } ]
});
App.PersonView = Ember.View.extend({
tagName: 'li',
content: null,
linkClicked: function() {
console.log(this.getPath('content.name'));
}
});
<ul>
{{#each App.peopleController}}
{{#view App.PersonView contentBinding="this"}}
<a {{bindAttr href="content.url"}} {{action "linkClicked" on="click"}}>
{{content.name}}
</a>
{{/view}}
{{/each}}
</ul>

From subviews, you can attach data-attributes and access them in your controller.
For example, in your view, if you have:
{{#view Ember.Button target="App.controller" action="publish" data-publish=false}}Unpublish{{/view}}
Then in your controller,
App.controller = Ember.Object.extend({
publish: function(v){
var status = v['data-publish'];//your additional information is appended to the view.
}
}

An improvement to Veeb's answer, remember you have the jQuery event so you can do:
// template
<ul>
{{#each applications}}
<li>
<a {{bindAttr href="url"}} param="abc" {{action "appClicked" on="click"}}>
{{name}}
</a>
</li>
{{/each}}
</ul>
// In your js code
appClicked: function (event) {
var param = $(event.target).attr('param');
...
}

You can try to make the parameter an attribute of the <li> or <a> tag and then use jQuery to access it.
Maybe something like
// template
<ul>
{{#each applications}}
<li>
<a {{bindAttr href="url"} param="abc"}
{{action "appClicked" on="click"}}>
{{name}}
</a>
</li>
{{/each}}
</ul>
// In your js code
appClicked: function (event) {
// You may have to play around and check which DOM element
// has the the param attribute. From memory it is the parent.
var param = this.$().parent().attr('param');
...
}

Related

argument is not passed to handlebars helper

I am new to handlebars, and trying to pass this as an argument to a custom helper. Pretty simple task, but in the helper, it turns out to be 0. Why doesn't it work? Here's helper:
hbs.handlebars.registerHelper('createAddressLink', function(address) {
console.log(address);
return `<li class="search-bar-container__content-item">
<a href="/address/${address.getID()}" class="search-bar-container__address-link link">
${address.getName()}
</a>
</li>`
})
Here's how I pass argument to it:
{{#each addresses}}
{{createAddressLink this}}
{{/each}}

Meteor - Passing data between helpers, events and templates

I'm not sure how to approach my issue. Whether I should set my variables in my event to my spacebars syntax fields from my template or pass my returned event data into my helpers somehow. Everything is published and subscribed properly too.
Problem: I am trying to make it so users can click an "Add" button next to any of the people in a directory list (DirectoryList collection) and have that users information be added to a Contacts List collection. Its simply a messaging app where a person can scroll a directory of everyone and add users to their contacts list. Here are my files:
templates > directoryList.html
<template name="directoryList">
{{> searchDirectory}}
<ul>
{{#each directoryList}}
<li>
{{firstname}} {{lastname}} <button name="addFriend" id="addFriend">Add</button>
</li>
{{/each}}
</ul>
</template>
helpers>directoryList.js
Template.directoryList.helpers({
'directoryList': function(){
return DirectoryList.find({}, {sort: {createdAt: -1}});
}
});
events>directoryList.js
Template.directoryList.events({
'click .addFriend': function(event){
event.preventDefault();
var currentUserId = Meteor.userId();
var currentContact = DirectoryList.findOne(this._id);
var currentContactFirstname = currentContact.firstname;
var currentContactLastname = currentContact.lastname;
var currentContactEmail = currentContact.email;
console.log("test");
ContactsList.insert({
firstname: currentContactFirstname,
lastname: currentContactLastname,
email: currentContactEmail,
createdBy: currentUserId
});
}
});
its obviously throwing me an error for the {{}} syntax in my event but i dont know what else to do or how to get this to work. Thought it might be able to inherit from the template those fields but i guess not?
You event handler is for addButton class, where you button doesn't have addButton class. You need to change id to class in your template.
<template name="directoryList">
{{> searchDirectory}}
<ul>
{{#each directoryList}}
<li>
{{firstname}} {{lastname}} <button name="addFriend" class="addFriend">Add</button> <!-- CHANGED ID TO CLASS FOR THIS BUTTON -->
</li>
{{/each}}
</ul>
</template>
And you can follow other answer to avoid unnecessary query to improve performance.
Hope it helps.
In your event handler this already contains the current contact, you don't need to look it up again. You can simplify your event handler down to:
Template.directoryList.events({
'click .addFriend': function(event){
event.preventDefault();
console.log(this);
ContactsList.insert({
firstname: this.firstname,
lastname: this.lastname,
email: this.mail,
createdBy: Meteor.userId()
});
}
});

How to get id from list of object using AngularJS?

I have api call on $on i got the Json response that is attached with the question. i was able to display fileName in the li , Now i have delete function when user click on remove icon i am calling function and trying to get rskAsesAprvAtchKy key so i can post the key to backend to delete this file.
It is coming undefined i am not sure what i am missing any help will be appreciated..
main.html
<div class="row">
<div class="col-md-6">
<ul>
<li ng - repeat="file in attachedDoc">{{file . fileName}}
<a href="" ng - click="deleteFile()">
<span class="glyph_remove"></span>
</a>
</li>
</ul>
</div>
</div>
factory.js
$scope.$on('addEditAttest', function (s, attestorObj) {
$scope.attestorObj = attestorObj;
attestorFactory.getAttachedDocument($scope.attestorObj.riskAssessmentRoleAsgnKey)
.then(function (response) {
$scope.attachedDoc = response.data;
});
});
$scope.deleteFile = function () {
var fileKey;
$scope.attachedDoc.rskAsesAprvAtchKy = fileKey;
console.log("deleted", fileKey);
}
JSON.JS
[{
"rskAsesAprvAtchKy": 1001,
"fileName": "Doc 1",
"rskAsesRoleAsgnKy": 1277
}]
You can pass the key as parameter for the ng-click method:
At the view
<li ng-repeat="file in attachedDoc">{{file.fileName}}
<a href="" ng-click="deleteFile(file.rskAsesAprvAtchKy, $index)"> //Key from the file
<span class="glyph_remove">
</span>
</a>
</li>
Change the delete method
$scope.deleteFile = function(fileKey, fileIndex){
/*Delete the file*/
$scope.attachedDoc.splice(fileIndex, 1); //remove the file at position fileIndex
}
EDIT:
Passing the $index from the ng-repeat and using Array.splice() will do the job. See above.

Computed.alias not updating bind-attr

I recently started using Ember.js. In my small application I currently have problems regarding Ember.computed.alias, because an {{#if}}-section is updated properly, but the bind-attr helper in the same template is not updated accordingly.
The application controller and the action influencing the value look as follows:
App.ApplicationController = Ember.ObjectController.extend({
isEditing: false,
actions: {
toggleEdit: function() {
var a = this.get('isEditing');
this.set('isEditing', !a);
}
}
});
The controller taking care of the template causing problems:
App.CategoriesController = Ember.ArrayController.extend({
needs: ['application'],
isEditing: Ember.computed.alias('controllers.application.isEditing'),
general: function() { // example depending on the alias
var result = this.filterBy('type', 1);
if (!this.get('isEditing')) {
result = result.filterBy('isHidden', false);
}
return result;
}.property('#each.type', '#each.isHidden', 'isEditing'),
// ......
The related template:
<ul id="categories">
{{#if isEditing}}YES!{{else}}NO!{{/if}}
{{#each general}}
<li {{bind-attr class=":general isEditing:editing"}}>
{{name}}
</li>
{{/each}}
</ul>
When the action toggleEdit is triggered, the {{#if}} section is updated and swaps between YES! and NO!, but the editing class is not applied to the list element. I tried encapsulated the alias into another property of the controller depending on the alias, but without success.
I assume it's a beginners mistake, but I can't figure out what I am overlooking.
Thanking you in anticipation.
isEditing is no longer in scope, use controller.isEditing, sorry phone response
Here's an example that would keep it in scope, but I'm fully qualifying it just to show you.
{{#each item in general}}
<li {{bind-attr class=":general controller.isEditing:editing"}}>
{{item.name}}
</li>
{{/each}}

How to pass parameters with the action Helper of Ember.js inside an input field from an Handlebars template?

In my handlebars template I have this loop:
{{#each itemController="fund"}}
<li>
<label>{{title}}</label>
<span>{{amount}}</span>
{{input type="text" placeholder="new user"
value=newFullName action="createUser"}}
{{partial 'user-list'}}
</li>
{{/each}}
and need to pass the current object as parameter to the 'createUser' action.
Something like this:
action="createUser(this)"
or:
action 'createUser' this
But it seems that ember can't handle parameters for actions inside an input field...
Am i missing something?
You can now pass a function, along with values -
submit=(action 'setName' 'Sal')
http://emberjs.com/blog/2015/06/12/ember-1-13-0-released.html#toc_closure-actions
I think that isn't possible to do this using the action property from input view helper.
A workaround could be wrap your input in a form that use the action view helper using the submit event, like the following:
Template
{{#each}}
<li>
<form {{action "createUser" this on="submit"}}>
{{name}}
{{input type="text" value=name}}
</form>
</li>
{{/each}}
Route
...
actions: {
createUser: function(user) {
alert(user.get('name'));
}
}
...
So when the user hit enter, will have the event triggered.
The main difference between the action property and the action view helper is that the action view helper is more flexible and you can supply the context and put it inside of any tag:
<div {{action "someAction" someObject}} on="click">Click me</div>
In the route:
actions: {
someAction: function(someObject) {
// do something with the someObject
}
}
See the docs for further information
Please give a look in the jsfiddle to see that sample in action http://jsfiddle.net/marciojunior/UAgjX/
I hope it helps
Finally i ended up with this solution:
Template
{{input class="newUser" type="text" value=newFullName placeholder="add user"}}
<button {{action 'createUser' this newFullName}}>Send</button>
Controller
createUser: function (fund, newFullName) {
var fullName = newFullName;
var user = this.store.createRecord('appUser', {
fullName: fullName,
fund: fund,
payments:[]
});
user.save().then(function(){
fund.get('users').pushObject(user);
fund.save().then(function(){
fund.reload();
});
});
}
You can pass a parameter to an action helper :{{action "doSomething" xxx }}
Where doSomething is your controller method ,and xxx is anything in the current context of the template.

Categories

Resources