Search code examples
javascriptbackbone.jsmarionette

Backbone.Marionette: Add header to collection view


Using Backbone.Marionette, I would like to render a collection of items along with a header.

I'm aware that Marionette.CollectionView does not have a template, as it only renders ItemViews.

I'm currently using Marionette.LayoutView, but have to define an extra DOM element for the 'list' region.

Is there any other way to do this? Possibly without the extra DOM element?

Maybe I could change open() for this particular region?


Current Result:

<div class='collection'>
  <h3>Featured</h3>
  <div class="list"></div>
</div>

Desired Result:

<div class='collection'>
  <h3>List Name</h3>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
   </ul>
</div>

Render Code:

var col = new LCollection([{name: "foo"}, {name: "bar"}]); // Defined earlier, not relevant here
var list = new ListView({collection: col});
var layout = new MyLayout({model: new Backbone.Model({name: "Featured"})});

app.featured.show(layout);
layout.list.show(list);

Views:

var ListItemView = Backbone.Marionette.ItemView.extend({
  template: '#list-item',
  tagName: 'li'
});

var LessonListView = Backbone.Marionette.CollectionView.extend({
  tagName: 'ul',
  itemView: ListItemView
});

var MyLayout = Backbone.Marionette.Layout.extend({
  template: "list-layout",

  regions: {
    list: '.list'
  }
});

Templates:

<script type="text/template" id="list-item">
  <%= name %>
</script>

<script type="text/template" id="list-layout">
  <h3><%= name %></h3>
  <div class="list"></div>
</script>

Solution

  • https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.compositeview.md

    Applied for you :

    Templates

    <script id="list-item" type="text/html">
      <%= name %>
    </script>
    
    <script id="list-layout" type="text/html">
        <div class='collection'>
            <h3><%= name %></h3>
            <ul></ul>
        </div>
    </script>
    

    JS

    RowView = Backbone.Marionette.ItemView.extend({
      tagName: "li",
      template: "#list-item"
    });
    
    TableView = Backbone.Marionette.CompositeView.extend({
      itemView: RowView,
      // specify a jQuery selector to put the itemView instances in to
      itemViewContainer: "ul",
      template: "#list-layout"
    });