Disable a button component with Ember

How to enable or disable a button in realtime using Ember

This article is referring to Ember 1.5.1, if you are on a newer or older version this might not apply.

I want to share some code that I have written when making a component that needs to enable/disable a button in realtime.

This is Ember’s strong suit, but it took me some searching and playing about to get the right solution, so hopefully this helps someone else.

I am using Ember-CLI to build the Ember application, so some of the export syntax might not be immediately understandable but I will explain as I go along.

The problem is that I want a box people could compose a tweet in and I want this to be available pretty much anywhere in my application. Because of these requirements it makes perfect sense that the view side of things should be handled by a component and the controller side by a mixin.

I have removed a lot of code to help me make my point, so sorry if you were looking for a copy/paste twitter box solution!

First up I will show you my mixin app/mixins/tweet-controller.js

export default Ember.Mixin.create({
  tweetContent: 'Write your tweet here',
  buttonText: "Post to Twitter",

  invalidTweet: function() {
    return !(this.get('tweetContent').length <= 140);
  }.property('tweetContent')
});

So this mixin will decorate any controller that uses it with some extra information, the strings at the top are used for adding some text to the component we are making, you can also see we have an invalidTweet function, which will tell us if the tweet is invalid or not, this looks at the property ‘tweetContent’ which is the text of our tweet.

I have called my main component make-a-tweet.js, this doesn’t have anything relevant to our needs in it but it does mean that the component call is; {{make-a-tweet tweetContent=tweetContent buttonText=buttonText invalidTweet=invalidTweet}} note that I have passed all the controller options into it.

The template for my component is found at app/templates/components/make-a-tweet.hbs


{{textarea value=tweetContent}}
{{twitter-button buttonText=buttonText disabled=invalidTweet}}

As you can see I have used Ember’s built in textarea component for the textarea but I have made my own custom sub-component for the button and importantly here I am passing in disabled=invalidTweet this will be used in our component, which you can see I have called twitter-button so it lives at app/components/twitter-button.js

export default Ember.Component.extend({
  tagName: ['button'],

  attributeBindings: ['disabled'],

  didInsertElement: function() {
    this.$().text(this.get('buttonText'));
  },
});

Here I am telling the component that it is a button, and importantly for our purposes I have set attributeBindings: ['disabled']. What this will do is update the generated HTML with disabled= and then the value of whatever invalidTweet is. Because invalidTweet cares about changes to tweetContent, when it changes it will update.


Recent posts View all

Ruby

Forcing a Rails database column to be not null

How you can force a table column to always have something in it with Rails

Writing Marketing

We've deleted an article's worth of unhelpful words

We've improved several pages across our site by removing words that add no value, and often detract from the article.