Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding enabled state of button in Ember.js

I'm just getting my feet wet with Ember.js, and I've hit something that I'm sure I'm not understanding.

I've got a selected object controller. It has content, which is an Ember.Object, which is the currently selected model. The model has a property (isDirty), and basically I'd like my save button on my form to be enabled only when the object is dirty and needs to be saved.

I've managed to bind up the form just fine, but the isEnabledBinding property on the save button is either not doing anything or I'm not hooking up the binding properly.

I've prepared a jsfiddle demonstrating my basic set up.

http://jsfiddle.net/blargity/fqc73/1/

How do I get the button to be enabled only when isDirty is true? The bindings should also work if the content property on the selected object controller changes.

like image 715
KevinBrownTech Avatar asked Mar 26 '12 06:03

KevinBrownTech


2 Answers

I found a way to do this without using the now-deprecated Ember.Button.

In the handlebars template:

<button {{action "save" target="controller"}} {{bindAttr disabled="view.isNotDirty"}}>Save</button>

In the view:

isNotDirty: function(){ 
    return !this.get('controller.content.isDirty') 
}.property('controller.content.isDirty').cacheable()

(With the version of Ember I have, Ember.Binding.not does not exist. Maybe I need to update, but the docs don't show it either so perhaps it was actually removed.)

like image 163
webjprgm Avatar answered Oct 30 '22 11:10

webjprgm


The problem is that there is no isEnabled property on Ember.Button. You need to bind to the disabled property.

One possibility is to create a custom Ember.Button which handles this for you, see http://jsfiddle.net/LabpW/.

Handlebars:

{{#view App.SaveModelButton modelBinding="model"}}Save{{/view}}

JavaScript:

App.SaveModelButton = Ember.Button.extend({
    disabledBinding: Ember.Binding.not('model.isDirty')
});

The used Ember.Binding.not is just a shortcut for writing your own computed property, which would look like this:

App.SaveModelButton = Ember.Button.extend({
    disabled: function() {
        return !Ember.getPath(this, 'model.isDirty');
    }.property('model.isDirty').cacheable()
});

I also refactored your code a bit:

  • You mixed create and extend: use create for instances and extend for classes. There is a good blog post about this

  • It's kind of a convention to use lowerCase for instances and UpperCase for classes, so it should be App.controller instead of App.Controller

like image 10
pangratz Avatar answered Oct 30 '22 11:10

pangratz