Gentenator
Gentenator

Reputation: 207

Edit List using Backbone.js/Marionette

I'll start off with I'm new to these two frameworks but I'm really excited with what I've learned so far with them. Big improvement with the way I've been doing things.

I want to display a collection of items (trip itineraries) in say a table. I only want to display a couple of the itinerary fields in the table because there are many fields. When you edit/add an item, I would like to display a form to edit all the fields in a different region or in a modal and obviously when you save the list/table is updated. I'm unsure of the best way to structure this and am hoping someone could point me in the right direction or even better an example of something similar. My searches so far have came up short. It seems I should use a composite view for the list but how to best pass the selected item off to be edited is where I'm kinda stuck at. Any pointers would be much appreciated.

Upvotes: 1

Views: 1753

Answers (1)

numbers1311407
numbers1311407

Reputation: 34072

I'd use a CompositeView for the table, and an ItemView for the form. Clearly this is incomplete, but it should get you started. Actually... I kind of got carried away.

What follows are some ideas for the basic structure & flow. The implementation details, including templates, I'll leave to you.

The table/row views:

// each row in the table
var RowView = Backbone.Marionette.ItemView.extend({
  tagName: "tr"
});

// This could be a table tag itself, or a container which holds the table.
// You want to use a CompositeView rather than a CollectionView so you can
// render the containing template (the table tag, headers), and also, it works
// if you have an actual collection model (ItineraryList, etc).
var TableView = Backbone.Marionette.CompositeView.extend({
  itemView: RowView,
  collectionEvents: {
    "change": "render"
  }
});

The form view:

// This would be a simple form wrapper that pulls default values from
// its model.  There are some plugins in this space to help with
// forms in backbone (e.g. backbone-forms), but they may or may not
// be worth the bloat, or might be tricky to work with Marionette.
var FormView = Backbone.Marionette.ItemView.extend({
  events: {
    "submit form": "onFormSubmit"
  },

  data: function () {
    // here you'd need to extract your form data, using `serializeArray`
    // or some such, or look into a form plugin.
    return {};
  },

  // Clearly this is incomplete.  You'd need to handle errors, 
  // perhaps validation, etc.  You probably also want to bind to 
  // collection:change or something to close the formview on success.
  //
  // Re-rendering the table should be handled by the collection change 
  // event handler on the table view
  onFormSubmit: function (e) {
    e.preventDefault();

    if (this.model.isNew()) {
      this.collection.create(this.data());
    } else {
      this.model.save(this.data());
    }
  }
});

Somewhere in your load process you'd instantiate a collection and show it:

// first off, somewhere on page load you'd instantiate and probably fetch
// a collection, and kick off the tableview
var itineraries = new Itineraries();
itineraries.fetch();

// For simplicity I'm assuming your app has two regions, form and table, 
// you'll probably want to change this.
app.table.show(new TableView({collection: itineraries}));

Making routes for the edit and new itinerary links makes sense, but if your form is in a modal you might want to bind to button clicks instead. Either way, you'd open the form something like this:

// in the router (/itineraries/edit/:id) or a click handler...
function editItinerary(id) {
  var itinerary = itineraries.get(id);
  // then show a view, however you do that.  If you're using a typical 
  // marionette region pattern it might look like
  app.form.show(new FormView({
    collection: itineraries, 
    model: itinerary
  });
}

// once again, a route (/itineraries/new), or a click handler...
function newItinerary() {
  app.form.show(new FormView({
    collection: itineraries, 
    model: new Itinerary()
  }));
}

Upvotes: 7

Related Questions