Search code examples
backbone.jsunderscore.js

create row with multiple cells via backbone.js


I have a rather simple backbone view that renders a tag when iterating through each item in a collection via the _.each function.

var SingleView = Backbone.View.extend({
  tagName:td,
  //other stuff
});

I have a view for the collection as well

var CollectionView = Backbone.View.extend({
//other stuff
this.collection.each(function(model ,i) {
var item = new SingleView({model: model});
 //alert(i);
//maybe in here is where I need logic to wrap a row around a <td> tag ?
 $('.collection').append(item.render().$el);

});

Then in the template:

<table class = "collection">
<!-- variables to render as html -->
</table>

What I'm hoping to do is wrap a given number of items in a table row, or <tr></tr>. It's easy to get one cell/row. I'm trying to get 2 or 3 or however many cells per row that I want. I've tried the Jquery wrap feature, and I'm guessing I need some kind of modular division but I'm kind of stuck. I'm also new to Backbone which is another hurdle.

To clarify - an individual item in the collection should be in each <td>, and I'm trying to place > 1 <td> in each row.


Solution

  • I tried to create a working example as close to your explanation as possible. It renders a collection as table cells, and I think you can go from there.

    Basically, you shouldn't manually wrap your td's in a tr tag. Create instances of TrView and TdView respectively, depending on the flow of your data. Append tr to table, and td to tr.

    Also you might want to look at CollectionView implemented in Marionette: http://marionettejs.com/docs/v2.4.3/marionette.collectionview.html

    Example #1:

    var collection = new Backbone.Collection([
      { title: 'Item 1' },
      { title: 'Item 2' },
      { title: 'Item 3' }
    ]);
    
    var TableView = Backbone.View.extend({
      tagName: "table",
      className: "collection",
      render: function(){
        var rowView = new RowView({ collection: collection });
        this.$el.html( rowView.render().el );
        return this;
      }
    });
    
    var RowView = Backbone.View.extend({
      tagName: "tr",
      render: function(){
        this.collection.each(this.appendItem, this);
        return this;
      },
      appendItem: function(model){
        var tdView = new TdView({ model:model });
        this.$el.append( tdView.render().el );
      }
    });
    
    var TdView = Backbone.View.extend({
      tagName: "td",
      render: function(){
        this.$el.text( this.model.get('title') );
        return this;
      }
    });
    
    var tableView = new TableView();
    tableView.render().$el.appendTo(document.body);
    table {
      border: 1px solid steelblue;
    }
    td {
      border: 1px solid brown;
      padding: 3px 5px;
    }
    <script src='http://code.jquery.com/jquery.js'></script>
    <script src='http://underscorejs.org/underscore.js'></script>
    <script src='http://backbonejs.org/backbone.js'></script>

    Example #2:

    var collection = new Backbone.Collection([
      { title: 'Item 1' },
      { title: 'Item 2' },
      { title: 'Item 3' },
      { title: 'Item 4' },
      { title: 'Item 5' },
      { title: 'Item 6' }
    ]);
    
    var TableView = Backbone.View.extend({
      tagName: "table",
      className: "collection",
      initialize: function(o){
        this.maxItemsInRow = o.maxItemsInRow? o.maxItemsInRow: 3;
      },
      render: function(){
        this.collection.each(this.addItem, this);
        return this;
      },
      addRow: function(){
        var rowView = new RowView({ collection: collection });
        rowView.$el.appendTo( this.el );
        this.currentRow = rowView;
        this.currentRowItemsLength = 0;
      },
      addItem: function(model){
        if( typeof this.currentRow === 'undefined') {
          this.addRow();
        }
        this.currentRow.addItem(model);
        this.currentRowItemsLength++;
        if(this.currentRowItemsLength >= this.maxItemsInRow){
          this.currentRow = undefined;
        }
      }
    });
    
    var RowView = Backbone.View.extend({
      tagName: "tr",
      addItem: function(model){
        var tdView = new TdView({ model:model });
        this.$el.append( tdView.render().el );
      }
    });
    
    var TdView = Backbone.View.extend({
      tagName: "td",
      render: function(){
        this.$el.text( this.model.get('title') );
        return this;
      }
    });
    
    var tableView = new TableView({ collection: collection, maxItemsInRow: 3 });
    tableView.render().$el.appendTo(document.body);
    table {
      border: 1px solid steelblue;
    }
    td {
      border: 1px solid brown;
      padding: 3px 5px;
    }
    <script src='http://code.jquery.com/jquery.js'></script>
    <script src='http://underscorejs.org/underscore.js'></script>
    <script src='http://backbonejs.org/backbone.js'></script>