Power-select not showing the selected value - ember.js

My power-select will not display the selected value.
I have three power-selects in this component and two are working fine, but the third (companyType) is acting strangely - the value is blank when you first go to the form. When you select a value it sticks for that record from then on (until you refresh the page)
Template:
// templates/components/companies/edit-new-form.hbs
{{#bs-form formLayout=formLayout model=company onSubmit=(action "save") as |form|}}
<label>State:
{{#power-select
selected=company.state
options=states
onchange=(action "chooseState")
as |name|
}}
{{name}}
{{/power-select}}
</label>
<label>County:
{{#power-select
selected=company.county
options=countyNames
onchange=(action "chooseCounty")
as |name|
}}
{{name}}
{{/power-select}}
</label>
<label>Company Type:
{{#power-select class="select"
selected=company.companyType
options=companyTypes
onchange=(action "chooseCompanyType")
as |name|
}}
{{name.companyType}}
{{/power-select}}
</label>
{{/bs-form}}
JS:
// componnents/companies/edit-new-form.js
export default Ember.Component.extend({
company: null,
router: Ember.inject.service('-routing'),
ajax: Ember.inject.service(),
store: Ember.inject.service(),
countyNames: Ember.computed('company.state', function() {
return this.get('ajax').request(config.host + '/api/counties/' + this.company.get('state')).then( (json) => json.map( (county) => {
return county.countyName;
})
)
}),
states: ['AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY'],
actions: {
// For dropdown handling
chooseState(state) {
this.set('company.state', state);
//Ember.set(this, "counties", this.get('ajax').request(config.host + '/api/counties/' + state).then((json) => json.items));
//this.set('counties', this.get('ajax').request(config.host + '/api/counties/' + state).then((json) => json));
},
chooseCounty(countyName) {
this.set('company.county', countyName);
},
chooseCompanyType(companyType) {
this.set('company.companyType', companyType);
},
}
});
And here is the route and model hook:
// routes/companies/edit.js
export default Ember.Route.extend({
model(params) {
var store = this.store;
return Ember.RSVP.hash({
companies: store.findRecord('company', params.company_id),
companyTypes: store.findAll('companyType')
});
}
});
The route that gets the companyType model is:
// routes/company-types.js
export default Ember.Route.extend({
model() {
return this.get('store').findAll('company-type');
}
});
And my models:
// models/company.js
export default DS.Model.extend({
companyName: DS.attr('string'),
street: DS.attr('string'),
county: DS.attr('string'),
city: DS.attr('string'),
state: DS.attr('string'),
zip: DS.attr('string'),
phone: DS.attr('string'),
email: DS.attr('string'),
fax: DS.attr('string'),
companyType: DS.attr('string')
});
// models/company-type.js
export default DS.Model.extend({
companyType: DS.attr('string')
});
Looking at Ember Inspector the data for the companyType is there and is a string, per my model. When I select a value from the dropbox, the data type turns into <svegbackend#model:company-type::ember1326:Environ Engineer. When I select one of the other drop downs, the value stays a string which I guess makes sense since the source for those are string arrays.
So how do I get the drop down to display the value when the form loads?

The problem is that, the companyType of the company is of type string where as the options list of the third select are of type companyType model. This creates a mismatch in setting the selected option initially.
Define the third power select as follows:
{#power-select class="select"
selected=company.companyType
options=companyTypesOptions
onchange=(action "chooseCompanyType")
as |name|
}}
{{name}}
{{/power-select}}
and define companyTypesOptions within edit-new-form.js as follows:
companyTypesOptions: Ember.computed('companyTypes.[]', function() {
return this.get('companyTypes').map((companyType)=> {
return Ember.get(companyType, 'companyType');
});
})
By this way; you will make both the options list and the selected value of type string! Do not forget if the type of the options and the selected you pass are different; you will get into trouble! Try to avoid that!

Related

How to load dependencies in Ember Data

I have an application, with 2 models: Team and User. Each team has many users, and only 1 Team Leader. On the Index view for Teams, I want to display the list of Teams, and the name of the Team leader. I can't get the name of the team leader to be displayed. Not sure what's wrong.
User Model:
export default Model.extend({
firstName: attr(),
lastName: attr(),
team: belongsTo('team', { inverse: 'users' }),
fullName: Ember.computed('firstName', 'lastName', function() {
return `${this.get('firstName')} ${this.get('lastName')}`;
})
});
Team Model:
export default Model.extend(Validations, {
name: attr(),
shortName: attr(),
description: attr(),
teamLeader: belongsTo('user', { inverse: null }),
users: hasMany('user'),
specialisationArea: attr(),
sourceEnergyTeam: attr(),
isEnergyTeam: Ember.computed('specialisationArea', function(){
return this.get('specialisationArea') == 101;
})
});
Team Index Route:
export default Ember.Route.extend({
model() {
return this.store.findAll('team');
}
});
Team List Template:
{{#each model as |team|}}
<tr>
<td>{{team.name}}</td>
<td>{{team.shortName}}</td>
<td>{{team.description}}</td>
<td>{{team.teamLeader.fullName }}</td>
<td>{{#link-to "teams.team" team}}Details{{/link-to}}</td>
</tr>
{{/each}}
And this is the mirage configuration:
this.get('/teams', () => {
return [{
id : 11,
type: 'team',
name: 'Energy',
description: 'energy desc',
shortName: 'short',
teamLeader: 12,
users: [12],
energyTeam: true
}];
});
this.get('/teams/:team_id', () => {
return {
id: 11,
type: 'team',
name: 'energy',
description: 'energy desc',
shortName: 'eg',
teamLeader: 12,
users: [12],
energyTeam: true
};
});
this.get('/users', () => {
return [{
id: 12,
type: 'user',
firstName: 'Pedro',
lastName: 'Alonso',
team: 11
}];
});
I'm not sure what's going wrong, but in the network calls I can see that only a call to '/teams' is being triggered. Any ideas?
Thanks

Ember Select changes but my model is still 'no dirty'

I have two models, MyModel and MyOptions.
MyModel has a myValue property belongsTo('myOption), and myName('string').
In the view, I have an input for myName and a select with possible values of the model MyOptions.
When I select a new related row, I expect myModel to be 'dirty'. If I change myName, myModel gets 'dirty' (correctly).
What I'm doing wrong?
Thanks,
See this jsfiddle for the code
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.IndexController = Ember.ObjectController.extend({
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
myModel: this.store.find('myModel', 1),
myOptions: this.store.find('myOption')
});
},
});
App.MyOption = DS.Model.extend({
name: DS.attr('name')
});
App.MyOption.FIXTURES = [
{ name: 'User a', id: 1 },
{ name: 'User b', id: 2 },
{ name: 'User c', id: 3 },
];
App.MyModel = DS.Model.extend({
myValue: DS.belongsTo('myOption'),
myName: DS.attr('string')
});
App.MyModel.FIXTURES = [
{
id: 1,
myValue: 2
}
];
<script type="text/x-handlebars" data-template-name="index">
<h1>Test</h1>
<lablel>My Value</label>{{input value=myModel.myValue.id}}
<lablel>My Name</label>{{input value=myModel.myName}}
{{view "select"
content=myOptions
selectionBinding=myModel.myValue
optionLabelPath="content.name"}}
{{myModel.isDirty}}
</script>
ember-data doesn't handle dirtyness for relationships, yet. You would need to implement it in user-space.
This is the relevant issue: https://github.com/emberjs/data/issues/2122
This old issue specifically discusses belongsTo: https://github.com/emberjs/data/issues/1367
Instead of using selectionBinding, you should use value:
{{view "select"
content=myOptions
value=myModel.myValue
optionLabelPath="content.name"}}

How do I load a fixture into a template with a different model in ember?

The intent of my code is to be able to load various fixtures into a template. For example:
The family template:
{{#each model as family}}
<p>{{family.name}} + "is" + {{family.age}} + "years old"</p>
{{/each}}
The brothers fixture: [{ id:1, name:"Greg", age:40 }]
The sisters fixture: [{ id:1, name:"Mary", age:35 }]
So that when I call:
#/brothers I'd get <p>Greg is 40 years old</p>
vs
#/sisters I'd get <p>Mary is 35 years old</p>
I figure I'm having trouble with 1) the correct routing. 2) usage of {{each}}/{{with}}. 3) usage of fixtures/models. You can find EVERYTHING at my github repo. Thanks in advance for the help!
Application Template - application.hbs:
<br><br>
<div class="container">
<ul class="nav nav-pills" role="tablist">
<li class="active">Home</li>
<li>Brothers</li>
<li>Sisters</li>
</ul>
<div class="container">
{{outlet}}
</div>
</div>
Family template (to go into {{outlet}} of application) - family.hbs:
<h1>Fixtures and Models</h1>
{{#each in model as family}}
<p>{{family.name}} is here</p>
{{else}}
<li>DIDN'T WORK</li>
{{/each}}
Family models and fixtures - family.js:
App.Family = DS.Model.extend({
name : DS.attr(),
age : DS.attr()
});
App.Brothers = DS.Model.extend({
name : DS.attr(),
age : DS.attr()
});
App.Sisters = DS.Model.extend({
name : DS.attr(),
age : DS.attr()
});
App.Brothers.FIXTURES = [
{
"id" : 1,
"name" : "Greg",
"age" : 10
},
{
"id" : 2,
"name" : "Mike",
"age" : 23
}
];
App.Sisters.FIXTURES =
[
{
"id" :1,
"name" :"Mary",
"age" :15
},
{
"id" :2,
"name" :"Gina",
"age" :34
}
];
My app.js file for all the routes:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function() {
this.resource('application');
this.resource('home');
this.resource('brothers');
this.resource('sisters');
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('application');
}
});
App.FamilyRouter = Ember.Route.extend({
});
App.HomeRoute = Ember.Route.extend({
});
App.FamilyRoute = Ember.Route.extend({
});
App.BrothersRoute = Ember.Route.extend({
model: function() {
this.store.find('brothers');
},
renderTemplate: function() {
return this.render('family');
}
});
App.SistersRoute = Ember.Route.extend({
model: function() {
return this.store.find('sisters');
}
});
Again, you can find all the codez here at my github repo
You need two fixes.
First, you're using wrong #each syntax. Change it to this:
<h1>Fixtures and Models</h1>
{{#each family in model}}
<p>{{family.name}} is here</p>
{{else}}
<li>DIDN'T WORK</li>
{{/each}}
Second, you're not returning brothers models. Change to:
App.BrothersRoute = Ember.Route.extend({
model: function() {
return this.store.find('brothers');
},
templateName: 'family'
});

Handling multiple checkbox array in Ember.js

Here is the thing I have a form which have multiple checkboxes and they have the same name attribute "classifications[]"
with the code:
<input type="checkbox" name="classification[]" value="Value 1" />
<input type="checkbox" name="classification[]" value="Value 2" />
<input type="checkbox" name="classification[]" value="Value 3" />
this works properly by default it posts "classification[]" like this
[ 0 => "Value 1", 1 => "Value 2"]
but I want this to work in an ember app so I did this (shortened version)
// index.html
{{input type="checkbox" name="classification[]" value="Cell Member" checked=classification}}
App.ApplicationController = Ember.Controller.extend({
var user = this.store.createRecord('user',{
classification: this.get("classification")
})
user.save();
})
App.User = DS.Model.extend({
classification: DS.attr("string")
});
but the only posted classification value is True..
try this
// index.html
{{#for possibleValues}}
<label>{{this.label}}</label>
{{input type="checkbox" value=this.isChecked}}
{{/for}}
<a {{action save}}>save</a>
var possibleValue = [{
label: 'Label for value 1',
isChecked: false,
value: 'Value 1'
},{
label: 'Label for value 2',
isChecked: false,
value: 'Value 2'
},{
label: 'Label for value 3',
isChecked: false,
value: 'Value 3'
}];
App = Ember.Application.create();
App.ApplicationAdapter = DS.RESTAdapter.extend();
App.ApplicationController = Ember.ObjectController.extend({
init: function () {
this._super();
var user = this.store.createRecord('user');
this.set('content', user);
},
actions:{
save: function () {
var user = this.get('content'),
collected = user.get('classifications');
this.set('collected', collected);
user.save();
}
},
//executes when isChecked is changed in one item of possibleValues
collectChecked: function () {
var classifications;
classifications = this.get('possibleValues').filterBy('isChecked', true); //filter checked only
classifications = classifications.mapBy('value'); //map values
this.set('classifications', classifications);
console.log(classifications);
}.observes('possibleValues.#each.isChecked'),
possibleValues: possibleValues
});
App.RawTransform = DS.Transform.extend({
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
App.User = DS.Model.extend({
classifications: DS.attr('raw')
});
http://jsbin.com/dokiwati/6/edit

template syntax for related data

This seems like it should be simple. Suppose I have the following model:
App.Folder = DS.Model.extend({
folder_id: DS.attr('number'),
folder_name: DS.attr('string'),
items: DS.hasMany('App.Item')
});
App.Item = DS.Model.extend({
item_id: DS.attr('number'),
folder_id: DS.attr('number'),
item_name: DS.attr('string'),
folder: DS.belongsTo('App.Folder')
});
...and the following data:
App.Folder.FIXTURES = [
{
id: 1,
folder_name: 'My First Folder',
items: [100]
},
{
id: 2,
folder_name: 'Another Folder',
items: [101]
},
{
id: 3,
folder_name: 'Folder 3',
items: [102]
}
];
App.Item.FIXTURES = [
{
id: 100,
folder_id: 1,
item_name: 'This is an item'
},
{
id: 101,
folder_id: 2,
item_name: 'A cleverly named item'
},
{
id: 102,
folder_id: 3,
item_name: 'This one is also an item in a folder'
}
];
Now, in my "item" template, shouldn't I be able to do something like this to show the folder related to an item:
<script type="text/x-handlebars" data-template-name="snapshot">
<div class="row-fluid property-row-alt">
<div class="span4 property-label">item name:</div>
<div class="span8">{{ item_name }}</div>
</div>
<div class="row-fluid property-row">
<div class="span4 property-label">folder:</div>
<div class="span8">{{ folder.folder_name }}</div>
</div>
</script>
"folder.folder_name" is the key syntax I'm trying to nail down here. Maybe this isn't possible, but I'm hoping to get the related folder and drill down into it's folder_name inside my item template. Can I do this in Ember? Using the latest versions.