home
  • Blog
1.10
  • Getting Started
    • Getting Started
    • Planning The Application
    • Creating a Static Mockup
    • Obtaining Ember.js and Dependencies
    • Adding the First Route and Template
    • Modeling Data
    • Using Fixtures
    • Displaying Model Data
    • Displaying a Model's Complete State
    • Creating a New Model Instance
    • Marking a Model as Complete or Incomplete
    • Displaying the Number of Incomplete Todos
    • Toggling between Showing and Editing States
    • Accepting Edits
    • Deleting a Model
    • Adding Child Routes
    • Transitioning to Show Only Incomplete Todos
    • Transitioning to Show Only Complete Todos
    • Transitioning back to Show All Todos
    • Displaying a Button to Remove All Completed Todos
    • Indicating When All Todos Are Complete
    • Toggling All Todos Between Complete and Incomplete
    • Replacing the Fixture Adapter with Another Adapter
  • Getting Ember
  • Concepts
  • The Object Model
  • Application
  • Templates
  • Routing
  • Components
  • Controllers
  • Models
  • Views
  • Enumerables
  • Testing
  • Configuring Ember.js
  • Cookbook
  • Understanding Ember.js
  • Contributing to Ember.js
Old Guides - You are viewing the guides for Ember v1.10.0.
Go to v5.0.0

Accepting Edits

Edit pencil

In the previous step we updated TodoMVC to allow a user to toggle the display of a text <input> for editing a todo's title. Next, we'll add the behavior that immediately focuses the <input> when it appears, accepts user input and, when the user presses the <enter> key or moves focus away from the editing <input> element, persists these changes, then redisplays the todo with its newly updated text.

To accomplish this, we'll create a new custom component and register it with Handlebars to make it available to our templates.

Create a new file js/views/edit_todo_view.js. You may place this file anywhere you like (even just putting all code into the same file), but this guide will assume you have created the file and named it as indicated.

In js/views/edit_todo_view.js create an extension of Ember.TextField and register it as a helper:

Todos.EditTodoView = Ember.TextField.extend({
  didInsertElement: function() {
    this.$().focus();
  }
});

Ember.Handlebars.helper('edit-todo', Todos.EditTodoView);

In index.html require this new file:

<!--- ... additional lines truncated for brevity ... -->
  <script src="js/controllers/todo_controller.js"></script>
  <script src="js/views/edit_todo_view.js"></script>
</body>
<!--- ... additional lines truncated for brevity ... -->

In index.html replace the static <input> element with our custom {{edit-todo}} component, connecting the value property, and actions:

{{! ... additional lines truncated for brevity ... }}
{{#if todo.isEditing}}
  {{edit-todo class="edit" value=todo.title focus-out="acceptChanges"
                           insert-newline="acceptChanges"}}
{{else}}
{{! ... additional lines truncated for brevity ... }}

Pressing the <enter> key will trigger the acceptChanges event on the instance of TodoController. Moving focus away from the <input> will trigger the focus-out event, calling a method acceptChanges on this view's instance of TodoController.

Additionally, we connect the value property of this <input> to the title property of this instance of TodoController. We will not implement a title property on the controller so it will retain the default behavior of proxying all requests to its model.

A CSS class edit is applied for styling.

In js/controllers/todo_controller.js, add the method acceptChanges that we called from EditTodoView:

// ... additional lines truncated for brevity ...
actions: {
  editTodo: function() {
    this.set('isEditing', true);
  },
  acceptChanges: function() {
    this.set('isEditing', false);

    if (Ember.isEmpty(this.get('model.title'))) {
      this.send('removeTodo');
    } else {
      this.get('model').save();
    }
  },
  removeTodo: function () {
    var todo = this.get('model');
    todo.deleteRecord();
    todo.save();
  }
},
// ... additional lines truncated for brevity ...

This method will set the controller's isEditing property to false and commit all changes made to the todo.

Live Preview

Ember.js • TodoMVC

Additional Resources

  • Changes in this step in diff format
  • Controller Guide
  • Ember.TextField API documentation
left arrow
Toggling between Showing and Editing States
Deleting a Model
right arrow
On this page

  • Live Preview
  • Additional Resources
Team Sponsors Security Legal Branding Community Guidelines
Twitter GitHub Discord Mastodon

If you want help you can contact us by email, open an issue, or get realtime help by joining the Ember Discord.

© Copyright 2023 - Tilde Inc.
Ember.js is free, open source and always will be.


Ember is generously supported by
blue