EmberJS computed sort property conflicting with jQuery UI Sortable - ember.js

I am having an issue with getting drag-and-drop sort functionality with EmberJS working.
The tutorials that cover this issue don't provide any help on the initial sort, which I am doing through a computed property.
What I'm encountering seems to be a race condition between ember's rerender when the sortedItems computed property changes and jQueryUI Sortable updating the DOM. List Items get duplicated, or disappear altogether upon sorting.
Route
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return Ember.Object.create({
id: 1,
title: "Title",
subtitle: "Subtitle",
items: [
Ember.Object.create({
name: "Item 2",
sortOrder: 2,
id: 1
}),
Ember.Object.create({
name: "Item 1",
sortOrder: 1,
id: 2
}),
Ember.Object.create({
name: "Item 3",
sortOrder: 3,
id: 3
})
]
});
}
});
Controller
import Ember from 'ember';
export default Ember.ObjectController.extend({
sortProperties: [ 'sortOrder' ],
sortedItems: Ember.computed.sort('model.items', 'sortProperties'),
actions: {
updateSortOrder: function(indexes) {
this.get('items').forEach(function(item) {
var index = indexes[item.get('id')];
item.set('sortOrder', index);
});
}
}
});
View
import Ember from 'ember';
export default Ember.View.extend({
didInsertElement: function() {
var controller = this.get('controller');
this.$(".item-list").sortable({
update: function(event, ui) {
var indexes = {};
$(this).find('li').each(function(index) {
indexes[$(this).data('id')] = index;
});
controller.send('updateSortOrder', indexes);
}
})
}
});
Template
<h1>{{ title }}</h1>
<h2>{{ subtitle }}</h2>
<ul class="item-list">
{{#each item in sortedItems }}
<li data-id="{{ unbound item.id }}">
name: {{ item.name }}<br />
sortOrder: {{ item.sortOrder }}<br />
id: {{ item.id }}
</li>
{{/each}}
</ul>
Here's a Barebones Ember app that reproduces the issue: https://github.com/silasjmatson/test-sortable
Question
Is there a way to avoid this race condition or sort only once when the controller is initialized?
Apologies if there is already an answer on the interwebs for this. I haven't been able to resolve this despite a week of searching/experimenting.

You can sort only once when the controller is initialised:
sortedItems: Ember.computed(function() {
return Ember.get(this, 'model.items').sortBy('sortOrder');
})
Because you're using the computed sort property it is attempting to sort the list for you whenever the sortOrder property changes on any item, which is rerendering the #each and doing something funky.
Just sort once initially using the method above and then let jQuery handle the order of items - rather than jQuery and Ember.

Related

EmberError: Nothing handled the action

I have been struggling with making my Ember Application work with Firebase.
I went through all the posts here on Stackoverflow about the similar matter but I did not find the answer to my problem. So here it is:
Whenever I try to put data into input fields and submit them with a button i get the console error:
EmberError
code : undefined
description : undefined
fileName : undefined
lineNumber : undefined
message :
"Nothing handled the action 'createBook'. If you did handle the action, this error can be caused by returning true from an action handler in a controller, causing the action to bubble."
My model:
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr('string'),
author: DS.attr('string'),
picture: DS.attr('string'),
buyer: DS.attr('string'),
bought: DS.attr('boolean', { defaultValue: false }),
createdAt: DS.attr('date', { defaultValue() { return new Date(); } })
});
And my Controller:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
createBook: function(){
var newBook = this.store.createRecord('book', {
title: this.get('title'),
author: this.get('author'),
picture: this.get('picture'),
buyer: this.get('buyer'),
bought: this.set(false),
createdAt: new Date().getTime()
});
newBook.save();
//reset values after create
this.setProperties({'title' : '',
'author' : '',
'picture' : '',
'buyer' : ''
});
}
}
});
The template:
{{outlet}}
<div style ="margin-left:130px;">
<h1> blabla </h1>
{{input type="text" value=title placeholder="Add Title"}}<br>
{{input type="text" value=author placeholder="Add author"}}<br>
{{input type="text" value=picture placeholder="Add picture"}}<br>
{{input type="text" value=buyer placeholder="buyer"}}<br>
</div>
<button class="btn btn-default" {{action "createBook" }}> Create</button>
{{#each model as |book|}}
<ul>
<li>{{book.title}}</li>
</ul>
{{/each}}
The connection between the Firebase and Ember is set up 100 % properly.
For now the rules on firebase have been set to true for both read and write.
The only problem is that it does not post the data to Firebase.
Thanks #Lux for your advice.
There were several things wrong with my code.
I created model and controller called book, but route called books.
I did not know that it will have an effect on my model and controller.
So i ended up with:
app/controllers/book.js
app/model/book.js
app/routes/book.js
app/templates/book.hbs
This was not enough. I also had to edit content of my controller
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
createBook: function(){
var newBook = this.store.createRecord('book', {
title: this.get('title'),
author: this.get('author'),
picture: this.get('picture'),
buyer: this.get('buyer')
});
newBook.save();
//reset values after create
this.setProperties({'title' : '',
'author' : '',
'picture' : '',
'buyer' : ''
});
}
}
});
As you can see I have removed the lines that were setting the default values of bought and createdAt. It was enough just to set them inside the model itself.

Weird binding with Ember.Select value

I'm having a weird issue with the Ember.Select view when I try to bind its value to a model.
Here is an abstract of what I'm doing, the complete jsbin can be found here:
Using JavaScript: http://jsbin.com/jayutuzazi/1/edit?html,js,output
Using CoffeeScript: http://jsbin.com/nutoxiravi/2/edit?html,js,output
Basically what I'm trying to do is use an attribute of a model to set an attribute of another model.
I have the Age model like this
App.Age = DS.Model.extend({
label: DS.attr('string'),
base: DS.attr('number')
});
And an other model named Person like this
App.Person = DS.Model.extend({
name: DS.attr('string'),
ageBase: DS.attr('number')
});
The template looks like this:
<!-- person/edit.hbs -->
<form>
<p>Name {{input value=model.name}}</p>
<p>
Age
{{view "select" value=model.ageBase
content=ages
optionValuePath="content.base"
optionLabelPath="content.label"}}
</p>
</form>
What I am trying to do is have a select in the Person edit form that lists the ages using base as value and label as label.
I expect the correct value to be selected when loading and to change when the selected option changes.
Has can be seen in the jsbin output, the selected is correctly populated but it sets the ageBase value of the edited person to undefined and does not select any option. The model value is correctly set when an option is selected though.
Am I doing something wrong ? Is it a bug ? What am I supposed to do to make this work ?
Thank you :)
You can conditionally render based on fulfilment of the ages as follows, since select doesn't handle promises (more on that below):
{{#if ages.isFulfilled}}
{{view "select" value=ageBase
content=ages
optionValuePath="content.base"
optionLabelPath="content.label"}}
{{/if}}
I updated your JsBin demonstrating it working.
I also illustrate in the JsBin how you don't have to qualify with model. in your templates since object controllers are proxies to the models they decorate. This means your view doesn't have to be concerned with if a property comes from the model or some computed property on the controller.
There is currently a PR #9468 for select views which I made a case for getting merged into Ember which addresses some issues with selection and option paths. There is also meta issue #5259 to deal with a number of select view issues including working with promises.
From issue #5259 you will find that Ember core developer, Robert Jackson, has some candidate select replacements. I cloned one into this JsBin running against latest production release version of Ember.
There is nothing at all preventing you using Roberts code as a select view replacement in your app. Asynchronous collections/promises will just work (and it is MUCH faster rendering from the benchmarks I have seen).
The template for that component is just:
{{#if prompt}}
<option disabled>{{prompt}}</option>
{{/if}}
{{#each option in resolvedOptions}}
<option {{bind-attr value=option.id}}>{{option.name}}</option>
{{/each}}
The js of the component is:
App.AsyncSelectComponent = Ember.Component.extend({
tagName: 'select',
prompt: null,
options: null,
initialValue: null,
resolvedOptions: null,
resolvedInitialValue: null,
init: function() {
var component = this;
this._super.apply(this, arguments);
Ember.RSVP.hash({
resolvedOptions: this.options,
resolvedInitialValue: this.initialValue
})
.then(function(resolvedHash){
Ember.setProperties(component, resolvedHash);
//Run after render to ensure the <option>s have rendered
Ember.run.schedule('afterRender', function() {
component.updateSelection();
});
});
},
updateSelection: function() {
var initialValue = Ember.get(this, 'resolvedInitialValue');
var options = Ember.get(this, 'resolvedOptions') || [];
var initialValueIndex = options.indexOf(initialValue);
var prompt = Ember.get(this, 'prompt');
this.$('option').prop('selected', false);
if (initialValueIndex > -1) {
this.$('option:eq(' + initialValueIndex + ')').prop('selected', true);
} else if (prompt) {
this.$('option:eq(0)').prop('selected', true);
}
},
change: function() {
this._changeSelection();
},
_changeSelection: function() {
var value = this._selectedValue();
this.sendAction('on-change', value);
},
_selectedValue: function() {
var offset = 0;
var selectedIndex = this.$()[0].selectedIndex;
if (this.prompt) { offset = 1; }
return Ember.get(this, 'resolvedOptions')[selectedIndex - offset];
}
});
The problem is that in:
{{view "select" value=model.ageBase
When the app starts, value is undefined and model.ageBase gets synchronized to that before value is synchronized to model.ageBase. So, the workaround is to skip that initial undefined value.
See: http://jsbin.com/rimuku/1/edit?html,js,console,output
The relevant parts are:
template
{{view "select" value=selectValue }}
controller
App.IndexController = Ember.Controller.extend({
updateModel: function() {
var value = this.get('selectValue');
var person = this.get('model');
if ( value ) { // skip initial undefined value
person.set('ageBase', value);
}
}.observes('selectValue'),
selectValue: function() {
// randomly used this one
return this.store.find('age', 3);
}.property()
});
givanse's answer should work.
I don't think it's because value is undefined, but because value is just an integer (42) and not equal to any of the selects content, which are Person objects ({ id: 2, label: 'middle', base: 42 }).
You could do something similar to what givens suggests or use relationships.
Models
//
// Models
//
App.Person = DS.Model.extend({
name: DS.attr('string'),
ageBase: DS.belongsTo('age', { async: true })
});
App.Age = DS.Model.extend({
label: DS.attr('string'),
base: DS.attr('number')
});
//
// Fixtures
//
App.Person.reopenClass({
FIXTURES: [
{ id: 1, name: 'John Doe', ageBase: 2 }
]
});
App.Age.reopenClass({
FIXTURES: [
{ id: 1, label: 'young', base: 2 },
{ id: 2, label: 'middle', base: 42 },
{ id: 3, label: 'old', base: 82 }
]
});
Template:
<h1>Edit</h1>
<pre>
name: {{model.name}}
age: {{model.ageBase.base}}
</pre>
<form>
<p>Name {{input value=model.name}}</p>
<p>
Age
{{view "select" value=model.ageBase
content=ages
optionValuePath="content"
optionLabelPath="content.label"}}
</p>
</form>
Ok, I found a solution that I think is more satisfying. As I thought the issue was coming from ages being a promise. The solution was to ensure that the ages list was loaded before the page was rendered.
Here is how I did it:
App.IndexRoute = Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
person: this.store.find('person', 1),
ages: this.store.findAll('age')
});
}
});
That's it! All I need from there is to change the view according the new model:
{{#with model}}
<form>
<p>Name {{input value=person.name}}</p>
<p>
Age
{{view "select" value=person.ageBase
content=ages
optionValuePath="content.base"
optionLabelPath="content.label"}}
</p>
</form>
{{/with}}
The complete working solution can be found here: http://jsbin.com/qeriyohacu/1/edit?html,js,output
Thanks again to #givanse and #Larsaronen for your answers :)

createRecord called w/o params does not add object to collection

Using:
ember-1.0.0-pre.4.js
ember-data.js REVISION:11
handlebars-1.0.rc.2.js
Please have a look at this jsFiddle illustrating the described problem.
I have a list of items that are displayed in a template. The template contain a linkTo helper that let's the controller add an item to the collection and is shown as a text input on the page.
Adding the item to the collection is done by the controller:
App.TodoItem = DS.Model.extend({
title: DS.attr('string', { defaultValue: "unknown" })
});
App.Router.map(function () {
this.resource('todo_items')
});
App.TodoItemsRoute = Em.Route.extend({
model: function () {
return App.TodoItem.find();
}
});
App.TodoItemsController = Em.ArrayController.extend({
addTodoItem: function () {
App.TodoItem.createRecord();
}
});
If I want the new item to be shown is the list, I have to pass params to createRecord, otherwise the item is not visible. The same behaviour can be reproduced by using Chrome's inspector and then the item can be made visible as follows:
// Open the jsFiddle http://jsfiddle.net/bazzel/BkFYd/ and select 'result(fiddle.jshell.net) in the inspector, then:
var item = App.TodoItem.createRecord();
// Nothing visible yet.
item.set('title', 'Whatever');
// Now the text input appear with the title as its value.
Is this expected behaviour and if so, what am I missing here?
I took time to redo your example the way i feel things should be done properly with Emberjs. You should rather make sure of transaction and properly define your views and then all your issues get taken care of. So here's how i think you should do this
Define a view for the textfield to capture the value being entered or
just bind it to the model property.
Listing items and adding a new item to the list should be done in two different views and should not be mixed together
<script type="text/x-handlebars">
{{outlet}}
<div>
{{outlet 'addItem'}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="todo_items">
{{#linkTo 'todo_items.new'}}Add Todo Item{{/linkTo}}
<ul>
{{#each item in controller}}
<li>
{{#unless item.isNew}}
{{item.title}}
{{/unless}}
</li>
{{/each}}
</ul>
</script>
Define different states for listing items and adding a new one
To benefit from automatic binding of your text field value to the
model property, you need to associate an ObjectController to the TodoItemsNew route
Finally, make use of transaction to create and commit records to the store
window.App = Em.Application.create();
App.TodoItem = DS.Model.extend({
title: DS.attr('string')
});
App.TodoItem.FIXTURES = [{
id: 1,
title: 'Lorem'
}, {
id: 2,
title: 'Ipsum'
}];
App.store = DS.Store.create({
revision: 11,
adapter: DS.FixtureAdapter.create()
});
App.Router.map(function () {
this.resource('todo_items',function(){
this.route('new');
})
});
App.IndexRoute = Em.Route.extend({
redirect: function () {
this.transitionTo('todo_items');
}
});
App.TodoItemsRoute = Em.Route.extend({
model: function () {
return App.TodoItem.find();
}
});
App.TodoItemsNewRoute = Em.Route.extend({
transaction: App.store.transaction(),
setupController:function(controller) {
console.info(controller.toString());
controller.set('content',this.transaction.createRecord(App.TodoItem));
},
renderTemplate: function() {
this.render('addItem',{
into:'application',
outlet:'addItem',
})
},
events: {
addItem: function() {
this.transaction.commit();
this.transitionTo('todo_items');
}
}
});
App.TodoItemsController = Em.ArrayController.extend();
App.TodoItemsNewController = Em.ObjectController.extend();
App.TextField = Ember.TextField.extend({
insertNewline: function () {
this.get('controller').send('addItem')
}
});
Here' is a working version of the example on jsfiddle. Hopefully, i helped with this example clarify some of your issues.
Thank you Ken for answering my question. It indeed feels like a more proper of way of doing this in Ember. However, I still think it's difficult to get the hang of which objects are accessible from where...
Your example inspired me to do a rewrite of my code. I also made some changes to your approach:
I'm not sure if it's the best practice, my I don't create a store instance. Instead I define a Store class.
The content for the TodoItemsNewController is set by calling the model property on the corresponding route.
renderTemplate in the TodoItemsNewRoute only needs the outlet key.
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="todo_items">
{{#linkTo 'todo_items.new'}}Add Todo Item{{/linkTo}}
<ul>
{{outlet "addItem"}}
{{#each controller}}
<li>
{{#unless isNew}}
{{title}}
{{/unless}}
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="todo_items/new">
{{view Ember.TextField valueBinding="title" placeholder="Enter title"}}
window.App = Em.Application.create();
App.TodoItem = DS.Model.extend({
title: DS.attr('string', {
defaultValue: "unknown"
})
});
App.TodoItem.FIXTURES = [{
id: 1,
title: 'Lorem'
}, {
id: 2,
title: 'Ipsum'
}];
App.Store = DS.Store.extend({
revision: 11,
adapter: DS.FixtureAdapter.create()
});
App.Router.map(function() {
this.resource('todo_items', function() {
this.route('new');
});
});
App.IndexRoute = Em.Route.extend({
redirect: function() {
this.transitionTo('todo_items');
}
});
App.TodoItemsRoute = Em.Route.extend({
model: function() {
return App.TodoItem.find();
}
});
App.TodoItemsNewRoute = Em.Route.extend({
model: function() {
return App.TodoItem.createRecord();
},
renderTemplate: function() {
this.render({
outlet: 'addItem'
});
}
});
App.TodoItemsNewView = Em.View.extend({
tagName: 'li'
});
The updated example is on jsFiddle.
Any reviews are welcome.

Set a Ember.CollectionView's selected item

I have a collection view like this (CoffeeScript):
App.SearchSuggestionsList = Ember.CollectionView.extend
tagName: 'ul'
contentBinding: 'controller.controllers.searchSuggestionsController.content'
itemViewClass: Ember.View.extend
template: Ember.Handlebars.compile('{{view.content.title}}')
isSelected: (->
/* This is where I don't know what to do */
this.index == controller's selected index
).property('controller.controllers.searchSuggestionsController.selectedIndex')
emptyView: Ember.View.extend
template: Ember.Handlerbars.compile('<em>No results</em>')
As you can see there's some pseudo-code inside the isSelected method. My goal is to define the concept of the currently selected item via this yet-to-be-implemented isSelected property. This will allow me to apply a conditional className to the item that is currently selected.
Is this the way to go? If it is, then how can this isSelected method be implemented? If not, what's another way around this to achieve the same thing?
I think it solves the case that you are looking for, with a changing list.
What we do is similar to the solution above, but the selected flag is based on the collection's controller, not the selected flag. That lets us change the "selected" piece via click, url, keypress etc as it only cares about what is in the itemController.
So the SearchListController references the items and item controllers (remember to call connectController in the router)
App.SearchListController = Em.ObjectController.extend
itemsController: null
itemController: null
App.SearchListView = Em.View.extend
templateName: "templates/search_list"
The individual items need their own view. They get selected added as a class if their context (which is an item) matches the item in the itemController.
App.SearchListItemView = Em.View.extend
classNameBindings: ['selected']
tagName: 'li'
template: Ember.Handlebars.compile('<a {{action showItem this href="true" }}>{{name}}</a>')
selected:(->
true if #get('context.id') is #get('controller.itemController.id')
).property('controller.itemController.id')
the SearchList template then just loops through all the items in the itemsController and as them be the context for the single item view.
<ul>
{{each itemsController itemViewClass="App.SearchListItemView"}}
</ul>
Is that close to what you're looking for?
The trivial (or the most known) way to do this is to have your child view (navbar item) observe a "selected" property in the parent view (navbar) which is bound to a controller, so in your route you tell the controller which item is selected. Check this fiddle for the whole thing.
Example:
Handlebars template of the navbar
<script type="text/x-handlebars" data-template-name="navbar">
<ul class="nav nav-list">
<li class="nav-header">MENU</li>
{{#each item in controller}}
{{#view view.NavItemView
itemBinding="item"}}
<a {{action goto item target="view"}}>
<i {{bindAttr class="item.className"}}></i>
{{item.displayText}}
</a>
{{/view}}
{{/each}}
</ul>
</script>
your navbar controller should have a "selected" property which you'll also bind in your view
App.NavbarController = Em.ArrayController.extend({
content: [
App.NavModel.create({
displayText: 'Home',
className: 'icon-home',
routeName: 'home',
routePath: 'root.index.index'
}),
App.NavModel.create({
displayText: 'Tasks',
className: 'icon-list',
routeName: 'tasks',
routePath: 'root.index.tasks'
})
],
selected: 'home'
});
Then you have a view structure similar to this, where the child view checks if the parent view "selected" has the same name of the child
App.NavbarView = Em.View.extend({
controllerBinding: 'controller.controllers.navbarController',
selectedBinding: 'controller.selected',
templateName: 'navbar',
NavItemView: Em.View.extend({
tagName: 'li',
// this will add the "active" css class to this particular child
// view based on the result of "isActive"
classNameBindings: 'isActive:active',
isActive: function() {
// the "routeName" comes from the nav item model, which I'm filling the
// controller's content with. The "item" is being bound through the
// handlebars template above
return this.get('item.routeName') === this.get('parentView.selected');
}.property('item', 'parentView.selected'),
goto: function(e) {
App.router.transitionTo(this.get('item.routePath'), e.context.get('routeName'));
}
})
});
Then, you set it in your route like this:
App.Router = Em.Router.extend({
enableLogging: true,
location: 'hash',
root: Em.Route.extend({
index: Em.Route.extend({
route: '/',
connectOutlets: function(r, c) {
r.get('applicationController').connectOutlet('navbar', 'navbar');
},
index: Em.Route.extend({
route: '/',
connectOutlets: function (r, c) {
// Here I tell my navigation controller which
// item is selected
r.set('navbarController.selected', 'home');
r.get('applicationController').connectOutlet('home');
}
}),
// other routes....
})
})
})
Hope this helps

select dropdown with ember

I'm trying to produce a select input and pass the selected object to the change event on the view. The ember contact example uses a <ul> but with a select the view needs to be outside the each otherwise the change even isn't fired.
Here is the view js:
App.SelectView = Ember.View.extend({
change: function(e) {
//event for select
var content = this.get('content');
console.log(content);
App.selectedWidgetController.set('content', [content]);
},
click: function(e) {
//event for ul
var content = this.get('content');
console.log(content);
App.selectedWidgetController.set('content', [content]);
}
});
The ul from the example works:
<ul>
{{#each App.widgetController.content}}
{{#view App.SelectView contentBinding="this"}}
<li>{{content.name}}</li>
{{/view}}
{{/each}}
</ul>
But if I replace html directly, the change event isn't fired (which makes sense)
<select>
{{#each App.widgetController.content}}
{{#view App.SelectView contentBinding="this"}}
<option>{{content.name}}</option>
{{/view}}
{{/each}}
</select>
So I guess the select has to be wrapped in the view.. in which case how do I pass the relevant object?... This code results in the entire array being passed:
{{#view App.select_view contentBinding="App.widgetController.content"}}
<select>
{{#each App.widgetController.content}}
<option>{{name}}</option>
{{/each}}
</select>
{{/view}}
Ember now has a built-in Select view.
Here's a usage example:
var App = Ember.Application.create();
App.Person = Ember.Object.extend({
id: null,
firstName: null,
lastName: null,
fullName: function() {
return this.get('firstName') + " " + this.get('lastName');
}.property('firstName', 'lastName').cacheable()
});
App.selectedPersonController = Ember.Object.create({
person: null
});
App.peopleController = Ember.ArrayController.create({
content: [
App.Person.create({id: 1, firstName: 'Yehuda', lastName: 'Katz'}),
App.Person.create({id: 2, firstName: 'Tom', lastName: 'Dale'}),
App.Person.create({id: 3, firstName: 'Peter', lastName: 'Wagenet'}),
App.Person.create({id: 4, firstName: 'Erik', lastName: 'Bryn'})
]
});
Your template would look like:
{{view Ember.Select
contentBinding="App.peopleController"
selectionBinding="App.selectedPersonController.person"
optionLabelPath="content.fullName"
optionValuePath="content.id"}}
Again, here's a jsFiddle example: http://jsfiddle.net/ebryn/zgLCr/
check out the answers to a similar question: How to bind value form input select to attribute in controller
In the examples a CollectionView is used with an tagName=select. You may find this helpful in getting it work.
EDIT: Since I was looking to implement a select myself, here is the solution I came up with:
views/form.js.hjs:
{{#view contentBinding="App.typeController" valueBinding="type" tagName="select"}}
{{#each content}}
<option {{bindAttr value="title"}}>{{title}}</option>
{{/each}}
{{/view}}
{{#view Ember.Button target="parentView" action="submitEntry"}}Save{{/view}}
The select is part of a form. I do check for the submit event and in there read the value:
app.js.coffee
# provides the select, add value: 'my_id' if you need differentiation
# between display name (title) and value
app.typeController = Ember.ArrayProxy.create
content: [{title:'Energy'}, {title:'Gas'}, {title:'Water'}]
# simplified version, but should prove the point
app.form_view = Ember.View.create
templateName: 'views_form'
type: null
submitEntry: () ->
console.log this.$().find(":selected").val()
Hope this helps.
This isn't an Answer, just a fix on the broken jsfiddle link.. Apparently jsfiddle has no love for ember :/ But JsBin does! http://jsbin.com/kuguf/1/edit