Mastering EmberJS 2.7: The Definitive Guide to Binding the 'disabled' Attribute for Buttons

Here is an official guide explaining how to bind a boolean property to the disabled attribute of an HTML element. However, it references a controller in the process.

I have a button that, when clicked, transitions the route (it must be a button and not a link-to):

Located in /templates/trails.hbs

<button type="button" class="btn btn-primary" disabled={{isEditing}} 
              onclick={{route-action 'addNew'}}>Add New</button>

(The route-action helper enables me to use closure actions in routes)

Located in /routes/trails.js

import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    addNew() {
      this.transitionTo('trails.new');
    } 
  }
});

After clicking the button, the route is changed to 'trails.new'

Located in /routes/trails/new.js

import Ember from 'ember';

export default Ember.Route.extend({
  isEditing: true,
});

Despite my expectations, this property seems to be ignored and not bound as intended. I even tried adding a controller:

Located in /controllers/trails/new.js

import Ember from 'ember';

export default Ember.Controller.extend({
  isEditing: true,
});

Why does the official guide suggest something that doesn't seem to work as expected? What aspect of Ember am I overlooking here?

Answer №1

The current template being used is templates/trails.hbs, however the isEditing variable is being set in a subroute controller called controllers/trails/new.js.

To resolve this issue, you should create a controllers/trails.js file and define the isEditing variable within it.

To accomplish this, add the following code to your routes/trails.js file:

actions: {
    willTransition: function(transition) {
      if(transition.targetName === 'trails.new'){
        this.controller.set('isEditing', true);
      }
      else{
        this.controller.set('isEditing', false);
      }
    }
  }

Answer №2

After doing some investigation, I realized that the approach I was taking was not the correct way to handle this situation. I needed to create a controller/trails.js file and place the property 'isEditing' in it.

As a result, I converted this into a component called add-new-button, which aligns better with the structure of Ember.

To begin, I required an initializer (credit to this question):

app/initializers/router.js

export function initialize(application) {
  application.inject('route', 'router', 'router:main');
  application.inject('component', 'router', 'router:main');
}

export default {
  name: 'router',
  initialize
};

(this injects the router into the component, allowing me to monitor it for changes and access the currentRoute)

I restructured my code within the component:

app/components/add-new-button.js

import Ember from 'ember';

export default Ember.Component.extend({
  isEditing: function() {
    let currentRoute = this.get('router.currentRouteName');
    return ~currentRoute.indexOf('new');
  }.property('router.currentRouteName')
});

templates/components/add-new-button.hbs

<button type="button" class="btn btn-primary" disabled={{isEditing}} 
        onclick={{route-action 'addNew'}}>Add New</button>

templates/trails.hbs

{{add-new-button}}

One advantage of this approach is that I can now utilize this button in other main templates to initiate route changes to the new route for each resource (and disable the button once the new route is reached).

NOTE

return ~currentRoute.indexOf('new');

This line checks for the substring 'new' within the route. If found, it returns true; otherwise, it returns false. Refer to this.

In ES6, this can be replaced with (which I have done!):

return currentRoute.includes('new);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Information failed to load into the datatable

i've implemented this code snippet to utilize ajax for loading data into a datatable. However, I'm encountering an issue where the data is not being loaded into the database. $('#new_table').DataTable({ "processing": true, "ser ...

Use Javascript to toggle the display to none for a specific table row (tr)

Is there a way to implement JavaScript code that will hide a specific table row using display:none;, and then reveal it again when a button is clicked? ...

Removing a CSS Class Using Tampermonkey: A Step-by-Step Guide

I'm completely new to CSS and javascript, so please bear with me. My goal is to remove the class disable-stream from each of the div elements located under the div with the class "stream-notifications". Below is an image for reference: Even though I ...

Error encountered: WebResource.axd is not found on the .net webforms website when accessed through Cloudfront

I am facing a challenge with migrating an existing .NET webforms site to work behind Cloudfront as all the webforms are breaking. Upon further investigation, it has been discovered that the site appears fine, but the webforms are breaking because the < ...

Can values be extracted from a JSON object that is saved in a separate JavaScript file?

In my current project, I am creating unique tables dynamically and displaying them using JavaScript after making an AJAX call. Instead of writing individual code for each table, I'm looking to establish a standard layout where I can customize the desi ...

Issue with JavaScript not generating a header element within a specified div

function searchingFunction() { var searchInput = document.getElementById("searchbar"); if (searchInput.value != null) { var resultElement = document.createElement("h2"); resultElement.innerHTML = "Search results for " + searchInput.value; d ...

Shifting JavaScript from Client to Server in Node/Express: A Step-by-Step Guide

Within my .handlebars file, I have a combination of HTML and JS code (provided below). The code represents a basic form which users can expand by clicking on a "New Form Field" button. Clicking on this button will simply add a new text field to the form. U ...

Having trouble accessing the session of next-auth.js within my _app.js file

I'm facing an issue where I have two providers, but I can't use both of them simultaneously. When I try to log in a user using useSession, I get an existence time error and not a user (an empty object is returned). I have a backend that returns t ...

Best practices for incorporating and leveraging node packages with Laravel Mix

As I embark on my Laravel (v 8.x) Mix project, I am encountering challenges when it comes to incorporating JavaScript from node modules. To kick things off, here is a snippet from my webpack.mix.js: mix.js('node_modules/mxgraph/javascript/mxClient.mi ...

Adding rows to a Datatable using an object array in rows.add()

Attempting to refresh my current Datatable by fetching new data using an Ajax function. Despite trying various solutions from other sources, the table does not update as expected. The function being used is shown below: $.ajax({ url: "<?php echo s ...

Received an error while attempting an AJAX GET request to a distinct server hosting a WebAPI

This is my first time encountering an issue with an Ajax request in client-side code. I'm hoping that there's a simple mistake in my code that I'm just overlooking. Just to give some background, when I manually access the URL mentioned below ...

Guide to saving an http response as a file and automatically retrying on a 503 error

When it comes to piping the response of an http request to a file, the process is pretty straightforward: http.get(url, function (res) { var file = fs.createWriteStream(filename) res.pipe(file) file.on('finish', function () { file.clos ...

Adjust element sizes in real time with Angular 5

In my current setup, I have 2 interconnected div elements. The left div contains a list of images while the right div displays the details of each image. By clicking on an image in the left div, the right div expands and shows the corresponding information ...

The Response.Write function is not functioning properly in the production environment

I have created a C# WebService (ASMX) with the code snippet below: if (!SomeValidation()) { //context.Response.ContentType = "application/json"; //context.Response.ContentType = "text/plain"; context.Response.ContentType = "application/text"; ...

Ways to serve JSON response following a 400 error code

After a user submits incorrect form details, such as an invalid username or blank email address, I make an Ajax request to my REST API. The response data I receive is structured as follows: HTTP 400 Bad Request Allow: POST, OPTIONS Content-Type: applicati ...

How do I programmatically switch the Material-UI/DatePicker to year view in React?

I have a DatePicker component set up in my project, and it works perfectly fine. However, for my specific use case, I only need the year view to be displayed. Within the child component of the DatePicker (Calendar), there is a function called: yearSelect ...

The JSON file is not filling the options in the dropdown menu

procedure Add the objects from the dropdown into the dropdown menu. The Json file is located in root/ajax/.json and the working file is stored in root/.html. Problem: None of the objects from the JSON file are appearing in the dropdown menu. I attempted ...

The Javascript query is returning an [object Object] data type

I am facing an issue with a JavaScript file that is querying a SharePoint list. Specifically, the Priority drop down in the query result is displaying as [object OBJECT]. I suspect it has something to do with the var query string where I have added the &ap ...

Analyzing the contents of a JSON file and matching them with POST details in order to retrieve

When comparing an HTTP Post body in node.js to a JSON file, I am looking for a match and want the details from the JSON file. I've experimented with different functions but I'm unsure if my JSON file is not formatted correctly for my needs or if ...

Using the setInterval function in conjunction with the remoteCommand to create a

I am attempting to create a remote command that calls a bean function and updates a progress bar every 2 seconds until cancelled. The remote command looks like this: <p:remoteCommand id="usedCall" name="queryUsed" onco ...