How to use sortProperties: ['lastName'] - ember.js

I'd like to sort an Array or users which gets fetched by ember-data. I can't figure out to sort the array be lastName. The following code doesn't do the job. How can I fix it?
app.js
App.UsersRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
App.UsersController = Ember.ArrayController.extend({
sortProperties: ['lastName'],
sortAscending: true
})
index.html
<script type="text/x-handlebars" data-template-name="users">
<table class='table table-striped'>
{{#each model itemController="user"}}
<tr>
<td>{{lastName}}</td>
</tr>
{{/each}}
</table>
</script>

Kudos to Bradley Priest for answering the question. Using this in the template does the trick.
index.html
<script type="text/x-handlebars" data-template-name="users">
<table class='table table-striped'>
{{#each this itemController="user"}}
<tr>
<td>{{lastName}}</td>
</tr>
{{/each}}
</table>
</script>

Related

emberjs instead of rendering component this was rendered <!---->

i am new to emberjs and i am trying to iterate through arr and render a table with the content of elements of the array the each loop renders <!----> instead of rows in the table
what am i doing wrong?
here is my code:
app.js
arr=[{id:1,name:foo,completed:'yes'},{id:2,name:'bar', completed:'no'}]
App= Ember.Application.create();
App.Router.map(function(){
})
App.IndexRoute=Ember.Route.extend({
model: function(){
return arr;
}
})
App.SingleTaskComponent = Ember.Component.extend({
templateName: "components/single-task",
tagName: ""
});
App.TasksCollectionComponent = Ember.Component.extend({
templateName: "components/tasks-collection",
tagName: "tbody",
actions: {
newTask: function(){
console.log("here");
}
}
});
and here is the hbs code:
<script type="text/x-handlebars" id="components/single-task">
<tr {{bind-attr id=id}}>
<td>
<input type="text" name="task" {{bind-attr value=name}} >
</td>
<td>
<input type="checkbox" name="completed">
</td>
</tr>
</script>
<script type="text/x-handlebars" id="components/tasks-collection">
<tr>
<td><button>+</button></td>
<td>Tasks</td>
</tr>
{{#each model as |task|}}
{{single-task id=task.id name=task.name completed=task.completed}}
{{/each}}
</script>
<script type="text/x-handlebars" id="index">
<table>
{{tasks-collection}}
</table>
</script>
Your coding looks like you are not using ember-cli. please use it. In this link you can go through enormous projects which are using ember, you can learn from them how are they using it. You can even play with ember-twiddle for easy learning. I will encourage you to follow ember guides tutorial.
Regarding your question,
You need to pass the required data to components,
{{tasks-collection model=model}}
In single-task component, you can avoid bind-attr instead you can use it like
<tr id={{id}}>
Refer deprecation guide bind-attr for more details

ember link-to from the component

i am new at EmberJs.
I tried to link from the component "invoices-list" to invoice.
invoices-list.hbs
{{#each invoices as |invoice|}}
<tr>
<td>{{invoice.kdnr}}</td>
<td>{{invoice.rnr}}</td>
<td>{{invoice.invoiceId}}</td>
<td>**{{#link-to 'invoice' invoice.invoiceId}}Click here{{/link-to}}**</td>
</tr>
{{else}}
<p>No datas</p>
{{/each}}
invoices.hbs
{{invoices-list invoices=model}}
router.js
Router.map(function() {
this.route('invoices');
this.route('invoice', { path: '/invoice/:invoice_id' });
});
My problem is, the template will not rendered and i get the error: "props.parentView.appendChild is not a function"
What is wrong?
Thanks for help.
Fabian
Let me give you first an example how to use Link-to
Suppose this is your Route.js
Router.map(function() {
this.route('photos', function(){
this.route('edit', { path: '/:photo_id' });
});
});
and this is app/templates/photos.hbs
<ul>
{{#each photos as |photo|}}
<li>{{#link-to "photos.edit" photo}}{{photo.title}}{{/link-to}}</li>
{{/each}}
</ul>
then rendered HTML would be
<ul>
<li>Happy Kittens</li>
<li>Puppy Running</li>
<li>Mountain Landscape</li>
</ul>
so in your case this is Route
Router.map(function() {
this.route('invoices');
this.route('invoice', { path: '/invoice/:invoice_id' });
});
then you may use this
{{#each invoices as |invoice|}}
<tr>
<td>{{invoice.kdnr}}</td>
<td>{{invoice.rnr}}</td>
<td>{{#link-to 'invoice' invoice}}{{/link-to}}</td>
</tr>
{{else}}
<p>No datas</p>
{{/each}}
another example to clarify:
//Route.js
this.route('contacts');
this.route('contact', { path: 'contacts/:contact_id' });
//Contacts.hbs
{{#each model as |contact|}}
<tr>
<td>{{link-to contact.name 'contact' contact}}</td>
<td>{{link-to contact.email 'contact' contact}}</td>
<td>{{contact.country}}</td>
</tr>
{{/each}}
Hope it works for you. more info.

template rendering is not working properly in ember js

I am very new to Ember js. when i route one template to another it working properly.but the problem is when i was render same template it won't work.
My code is follows:
index.html:Manager template in index.html
<script type="text/x-handlebars" data-template-name="manager">
{{#each model.manager}}
<div class="pure-g-r content-ribbon">
<div class="pure-u-1-3">
<div class="img-viewer-profile">
<img {{bindAttr src="image"}}>
</div>
</div>
<div class="pure-u-2-3">
<div class="l-box">
<h4 class="content-subhead">{{name}}</h4>
<table class="pure-table">
<tbody>
<tr class="pure-table-odd">
<td>Id</td>
<td><b>ATL-{{id}}</b></td>
</tr>
<tr class="pure-table-odd">
<td>Team</td>
<td><b>{{team}}</b></td>
</tr>
<tr>
<td>Division</td>
<td><b>{{division}}</b></br>
</tr>
<tr class="pure-table-odd">
<td>Manager</td>
<td>
<b>
<a href="#" {{action "managerinfo" manager_id}}>
{{manager_name}}
</a>
</b>
</td>
</tr>
{{/each}}
<tr>
<td>Reportees</td>
<td>
{{#each model.results}}
<br><b>
<a href="#" {{action "profileinfo" id}}>
{{reportees}}
</a>
</b></br>
{{/each}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{{outlet}}
</script>
app.js:
=========
App.ManagerController = Ember.ObjectController.extend({
manager_id: '',
id: '',
actions:{
managerinfo: function(manager_id) {
// the manager id of selected manager field
var manager_id = manager_id;
alert("profile");
alert(manager_id);
managerdata = $.ajax({
dataType: "json",
url: "/manager?manager_id=" + manager_id,
async: false}).responseJSON
managerdata.manger_id = manager_id;
console.log(managerdata);
this.transitionToRoute('manager', managerdata);
}
)}
Now my problem is when render the new manager data to manager it wont be displayed.
After refresh only it shows the data.
what mistake i was done in this code , i dont understand.so please provide me solution.
i added my complete code here with proper tags order.
As per your comment, the way you are doing is not suggested. You can pass manager_id in the route url. I will give you very basic skeleton which you can make further changes. Do remember, if you want to set model data from ajax, use model hook in the route
First Router
App.Router.map(function() {
this.resource("managers", function(){
this.route("all");
this.route("manager", { path: "/:manager_id" });
});
});
So here with #/manager/all displays all managers list
#/manager/:manager_id displays manager with id manager_id
Next ManagerAll route
App.ManagersAllRoute = Ember.Route.extend({
model: function() {
//do ajax and return managers data which sets as model for this route
}
});
sameway
App.ManagersManagerRoute = Ember.Route.extend({
model: function(params) {
//do ajax and return managers data which sets as model for this route
//here params will have the manager_id passed through url
//as it is ajax, create a promise
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
dataType: "json",
url: "/manager?manager_id=" + params.manager_id,
async: false}).then(function(data){
resolve(data);
})
});
}
});
Next is template for managers
{{#each model.manager}}
{{#link-to 'managers.manager' manager_id}}{{{manager_name}}{{/link-to}}
{{/each}}
Now a template for manager
{{manager_id}}
{{manager_name}} blah blah blah
You didn't close the each tag properly.
<script type="text/x-handlebars" data-template-name="manager">
{{#each model.manager}}
<a href="#" {{action "managerinfo" manager_id}}>
{{manager_name}}
</a>
{{/each}}
</script>
Also you haven't closed the ManagerController correctly in the given above. Double check that.
App.ManagerController = Ember.ObjectController.extend({
manager_id: '',
id: '',
actions:{
managerinfo: function(manager_id) {
// the manager id of selected manager field
var self=this;
var manager_id = manager_id;
alert("profile");
alert(manager_id);
managerdata = $.ajax({
dataType: "json",
url: "/manager?manager_id=" + self.manager_id,
async: false}).responseJSON.then(function(managerdata) {
managerdata.manger_id = self.manager_id;
console.log(managerdata);
this.transitionToRoute('manager', managerdata);
})
}
)}

Ember.js dynamic link

I need some information about the {{link-to}} on ember. I've made some test and there is something I really don't understand..
Example :
I have a blog with with different post like that :
App.Router.map(function() {
this.resource('login', { path: '/' });
this.resource('home');
this.resource('posts', function(){
this.resource('post', { path: '/:post_id' }, function(){
this.route('update');
});
this.route('create');
});
});
Let's say that I have this template :
<script type="text/x-handlebars" data-template-name="enquiries">
<table>
<thead>
<tr>
<th>id</th>
<th>type</th>
<th>name</th>
<th>last update</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
{{#each post in model}}
<tr>
<td>{{post.id}}</td>
<td>{{post.type}}</td>
<td>{{post.name}}</td>
<td>{{post.updatedAt}}</td>
<td>{{#link-to 'post' post}}View{{/link-to}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
My simple post template
<script type="text/x-handlebars" data-template-name="post">
<div class="post-info">
<button {{action "update"}}>Update</button>
<table>
<tr>
<td>{{title}}</td>
</tr>
<tr>
<td>{{content}}</td>
</tr>
<tr>
<td>{{author}}</td>
</tr>
</table>
</div>
</script>
Those link a dynamic one and there is on all of them the good url such as localhost/posts/1 or 2 etc...
When I click on the link, nothing happend. I have to had {{oulet}} to show it. but my problem is that its show on the same page as my table (underneath), but I wanted to only display the post template..
I have some trouble to understand why, and also what is the main purpose of the outlet in my case...
Thanks.
The reason the post is shown within the posts template is because your Router defines it that way. If you want a separate page, try this:
App.Router.map(function() {
this.resource('login', { path: '/' });
this.resource('home');
this.resource('posts');
this.resource('post', { path: 'posts/:post_id' }, function(){
this.route('update');
});
this.route('create');
});
When you have a nested resource, the {{outlet}} helper designates where the nested template will be rendered.

Mark the current detail entry in a master list

I have a list of users which are displayed in a master view on the left side (Twitter Bootstrap CSS). Details of each user can be shown by clicking the show button. They will be displayed on the right side (detail).
How can I remove the show button for the currently displayed user? e.g. #/users/1 shouldn't render the show button for the first user.
index.html
<script type="text/x-handlebars" data-template-name="users">
<div class='row'>
<div class='span4'>
<table class='table table-striped'>
{{#each model}}
<tr>
<td>{{lastName}}</td>
<td>{{#linkTo 'user' this}}<button class="btn" type="button">show</button>{{/linkTo}}</td>
</tr>
{{/each}}
</table>
</div>
<div class='span8'>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="user">
<h1>{{firstName}} {{lastName}}</h1>
</script>
app.js
App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
})
App.Router.map(function() {
this.resource('users', function() {
this.resource('user', { path: ':user_id' })
})
});
App.UsersRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
})
App.User.FIXTURES = [{
id: 1,
firstName: "Bill",
lastName: "Clinton"
}, {
id: 2,
firstName: "Barack",
lastName: "Obama"
}]
Ember provides some support for doing what you want. By default it sets the "active" css class on the selected element. You can find more information about that here: http://emberjs.com/api/classes/Ember.LinkView.html (note that the {{#linkTo}} is just a helper based on the LinkView).
The simplest way to override this behavior, since instead of "active" you want to hide the button, would be to make use of the hide class that comes with Twitter Bootstrap. So your users template would look like:
<script type="text/x-handlebars" data-template-name="users">
<div class='row'>
<div class='span4'>
<table class='table table-striped'>
{{#each model}}
<tr>
<td>{{lastName}}</td>
<td>{{#linkTo 'user' this activeClass="hide"}}<button class="btn" type="button">show</button>{{/linkTo}}</td>
</tr>
{{/each}}
</table>
</div>
<div class='span8'>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="user">
<h1>{{firstName}} {{lastName}}</h1>
</script>