I have a model Currencies. Fields in the model are name:string and default:boolean.
On the backend only one of records in database can have default:true. I want it to be selected by default in select in Ember js.
Please give me an example how to make such select and use it
Example:
name: type1 default: false
name: type2 default: true
name: type3 default: false
I want to generate such select :
<selected>
<option>type1</option
<option selected=selected>type2</option
<option>type3</option
</selected>
Route.js
#route 'addincome', { path: 'operations/addincome' }
EmberMoney.AddincomeRoute = Ember.Route.extend
model: ->
EmberMoney.IncomeOperation.createRecord()
setupController: (controller, model) ->
controller.set('currencies', EmberMoney.Currency.find())
controller.set('content', model)
addincome.handlebars
// Some output with Incomes records
{{view EmberMoney.Select viewName="select"
contentBinding="controller.currencies"
optionLabelPath="content.name"
optionValuePath="content.id"
selectionBinding="controller.defaultType"}}
addincome_controller.js
EmberMoney.AddincomeController = Ember.ObjectController.extend({
setDefaultCurrency: function(){
if(this.get('currencies.isLoaded')){
this.set('defaultType', this.get('currencies').findProperty('default'));
}
}.observes('currencies.isLoaded')
})
My answer builds upon that one already posted. The answer is to use the selectionBinding and a clever way to set it up:
{{view Ember.Select
contentBinding="controller.types"
optionLabelPath="content.name"
optionValuePath="content.id"
selectionBinding="controller.selectedCurrency"
}}
EmberMoney.IncomesController = Ember.ArrayController.extend({
selectedCurrency : null,
currenciesObserver: function(){
var currencies = this.get("currencies");
var default = currencies.findProperty("default");
if(default)
this.set("selectedCurrency", default);
}.observes('currencies.#each')
});
How does the solution work?
We set up a selectionBinding (two way) between the Select control and your controller. If you set a currency in your controller in the property 'selectedCurrency', it will be the selected value in the Select control. Vice versa if you select a currency in the Select Box, it will be set in your controller.
I am doing the initial setup with the helper of an observer. The observer is called each time the watched currencies array changes.
Every time it is called, it tries to find a default currency. If it finds one, it sets it in your selectedCurrency property. Now the selectionBinding kicks and does its magic for you.
An additional advantage of this solution is, that you can grab the selected value easily from the property, if the user chooses another currency.
Use selectionBinding for the selection, and ComputedProperty to find the appropriate item
Update
EmberMoney.AddincomeController = Ember.ObjectController.extend({
setDefaultCurrency: function(){
if(this.get('currencies.isLoaded')){
this.set('defaultType', this.get('currencies').findProperty('default'));
}
}.observes('currencies.isLoaded')
})
The advantage of using isLoaded over #each for the observer is that the observer wont get fired everytime a currency is added instead it makes sure to set the value once the entire collection is loaded, Again it is upto the use case to determine which to use when
Details about findProperty
Hope this helps
Screenshot
Related
I am setting up a "saved item" feature for logged-in users. I have the modeling worked out already (it relates the saved item list to both the user and products). But I am having trouble with how to have a computed property on my saveditem model. The model:
// saveditem.js model
export default DS.Model.extend({
user: belongsTo('user'),
product: belongsTo('product'),
dateAdded: attr('string')
});
I am currently using the product id as the id of that model.
I need a computed property on that model because anytime a product is shown on the site, the UI needs to reflect whether the item is already in the saveditem ember-data store or not.
Example of if the item is not on the list (but can be added):
Example of an item that is on the list (but can be removed):
I was thinking that on my userprofile service which manages the user's data across the app, I could have a computed property that outputs an array of ids from the saveditem model:
savedItemsList: computed('WHAT.IS.DEPENDENT.KEY?.[]', function() {
return this.get('store').peekAll('saveditem').map(item => item.id);
}),
And then in the template I could use a composable helper to see if the item being displayed is in the list or not:
{{#if (contains product.id userprofile.savedItemsList)}}
...show already-saved button...
{{else}}
...show save button...
{{/if}}
The question: what would the dependent key be for this computed property? OR...is this method stinky and and there's a better way to do it?
I have tried:
savedItemsList: computed('store.saveditem.[]', function() {
(after of course injecting the store). Seems like the obvious one but it doesn't update when records are added or removed from the saveditem store. Also tried 'store.saveditems.[]', permutations with and without array brackets, and NO dependent key - all no worky.
Makes me wonder whether this is not possible for a good reason ;) I might be "fighting the framework" here. Any help appreciated!
You can introduce computed property which will return all the items in the store and use that property for your savedItemsList computed property.
allSavedItemsList: computed(function() {
return this.get('store').findAll('saveditem');
}),
savedItemsList: computed('allSavedItemsList.[]',function() {
return this.get('store').peekAll('saveditem').map(item => item.id);
}),
what is the best way to define and use dates , datetime and datetime-tz in emberjs ?
I can put
App.Customer = DS.Model.extend({
testDate: DS.attr('date', {defaultValue: '2013-09-13'),
testDateTime: DS.attr('date', {defaultValue: '2013-09-13T20:47:20+01:00'),
into the model, but it seems to me that I can only put
{{input type="datetime-local"
into the template. this allows me to update the field according to the local time (which may not be what I want), but has a nice drop-down calendar and allows me to enter the time
Any other type (datetime-tz for example) seems to only show as a text input.
thanks for your time
datetime-tz is not a valid input type. http://www.w3.org/TR/html-markup/input.html
The way that datetime-local is styled is not part of the spec and is left up to the browser.
You might want to use something like the jQueryUI datepicker to ensure that things work the same across browsers. In that case you could extend the Ember.TextField view to handle setting up and tearing down the datepicker widget.
App.DatePicker = Ember.TextField.extend({
didInsertElement : function(){
this.$().datepicker();
},
willDestroyElement : function(){
this.$().datepicker('destroy');
}
});
{{view App.DatePicker valueBinding="date"}}
Here's a JSBin : http://jsbin.com/ucanam/1054/edit
using ember.js 1.0 and ember-data 1.0 beta2
I have a model (state) with the following properties
state: DS.attr('string'),
stateName: DS.attr('string'),
and a model (customer) with the following properties
name: DS.attr('string'),
stateID: DS.attr('string'),
state: DS.belongsTo("state")
I want to be able to edit the customer and choose the state from a drop-down (that has the stateID + name showing : eg "FL - Florida" and when selected, to store the state.stateID into the customer.stateID property
this is the first time I've tried something like this , and am slightly confused about the process.
In my customer route I've set up the following:
setupController: function(controller, model) {
this._super(controller, model);
this.controllerFor('state').set('content', this.store.find('state'));
}
and my select is this:
{{view Ember.Select
contentBinding="controllers.state.content"
optionValuePath="content.stateName"
optionLabelPath="content.stateName"
valueBinding="content.stateID"
selectionBinding="content.stateID"
prompt="Select a state"
}}
now I'm confused about where to go from here.
thanks
update
changed the view to say
{{view Ember.Select
contentBinding="controllers.state.content"
optionValuePath="content.stateID"
optionLabelPath="content.stateName"
valueBinding="customer.stateID"
}}
and I still don't get the stateid property to change . I've also tried
selectionBinding="customer"
to no avail.
update #2
I suspect that my problem may be linked to the property name. I changed the customer.stateID property to be customer.foobar and changed the select to read
{{view Ember.Select
contentBinding="controllers.state.content"
optionValuePath="content.stateName"
optionLabelPath="content.stateName"
valueBinding="foobar"
class="form-control"
}}
and now customer.foobar is updated with the value from the select.
Is there a problem with a property called stateID on customer ? I have a state model and state controller etc so is there a conflict ?
after all that - the problem was in the models themselves. The state model does not have a stateID field, it's state.state ...
My heartfelt apologies to all that wasted their time on this. Such a stupid error.
Okay, maybe not the best solution, but it works well:
App.ItemModalController = Ember.ObjectController.extend({
content: [],
availableCategories: function() {
return this.store.find('category');
}.property(),
//...
});
And the select:
{{view Ember.Select
contentBinding="availableCategories"
valueBinding="categorySelected"
optionLabelPath="content.title"
optionValuePath="content.id"
prompt="Please select a category"
class="form-control"
}}
See: http://jsfiddle.net/cyclomarc/VXT53/8/
I have a select view in which I simply want to list all the authors available in the fixtures data. I therefore try to use a separate controller in which I want to set the content = App.Author.find(), but that doesn't work ...
App.AuthorsController = Ember.ArrayController.extend({
//content: App.Store.findAll(App.Author)
//content: App.Author.find()
});
I then want to use the AuthorController for contentBinding in the selectView, but also this is not succsesful ...
{{view Ember.Select
contentBinding="App.AuthorsController"
optionValuePath="content.id"
optionLabelPath="content.name"
valueBinding="App.PublicationsEditController.author"
prompt="Select an author"
}}
The use case is that I have a publication in which an author is set (e.g. Marc) and I want to allow the user to change this to one of the available authors and then bind the new selected author to the publication model so that after a save the new author is saved.
I guess this what you are after: http://jsfiddle.net/VXT53/10/
I had to do a couple of changes, first your router map where slightly wrong, the edit segment had to go after the id to match your template name pulications/edit:
App.Router.map(function () {
this.resource('publications', { path: '/' }, function () {
this.route("edit", { path: "/edit/:publication_id" });
});
});
Your Ember.Select where binding to a class instead to some content, to set it up correctly I've defined a PublicationsEditControllet to requiere trough the needs API access to the AuthorsController's content:
App.PublicationsEditController = Ember.ObjectController.extend({
needs: ['authors'],
...
});
this is how you then use it for your select:
{{view Ember.Select
contentBinding="controllers.authors.content"
optionValuePath="content.id"
optionLabelPath="content.name"
valueBinding="content.name"
selectionBinding="selectedAuthor"
prompt="Select an author"
}}
Furthermore I've created a setupController hook which is used to set the AuthorsController's content to the list of authors:
App.PublicationsRoute = Ember.Route.extend({
model: function () {
return App.Publication.find();
},
setupController: function(controller, model) {
this._super(controller, model);
this.controllerFor('authors').set('content', App.Author.find());
}
});
And lastly on you PublicationsEditController is a new property attached selectedAuthor to hold the currently selected author for binding etc.
App.PublicationsEditController = Ember.ArrayController.extend({
needs: ['authors'],
selectedAuthor: null
});
I guess this should work now and brings you one step further.
Hope it helps.
This fiddle requires user to select option B , so it gives that message when other than B option is selected. Still, I need to set default option as B in select dropdown.
http://jsfiddle.net/fortm/YpEMH/
I tried this but seems not working for setting selectedName in SearchController ..
selectedName = this.get('model').objectAt('firstChild')
You can set the selectedName controller property in the route's setupController hook:
setupController: function(controller, model) {
controller.set('model', model);
controller.set('selectedName', model.findProperty('firstName', 'B'));
}
That way when the route is rendered, the select will default to "B".
I updated the fiddle.
Ember select now allows you to set a default value based on a controller property. See http://emberjs.com/api/classes/Ember.Select.html for more details but here is a summary:
App.TreesIndexController = Ember.ArrayController.extend({
defaultTree: 'enzyme',
treeTypes: ['enzyme', 'chembl']
});
{{view Ember.Select
content=treeTypes
prompt="Please select a target class"
value=defaultTree}}
The option select would default to 'enzyme' in this example.