Composite View: Grid View with itemview replacement and Testing for zombie

A grid view build w/ Marionette

by isochronous

HTML

<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.modelbinding/master/backbone.modelbinding.min.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.memento/master/backbone.memento.min.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.marionette/master/lib/backbone.marionette.js"></script>
<script id="grid-template" type="text/template">
    <thead>        
        <tr>
            <th>Username</th>
            <th>Full Name</th>
            <th>Action</th>
        </tr>
    </thead>
    <tbody></tbody>
</script>

<script id="row-template" type="text/template">
        <td>
            <%= username %>
        </td>
        <td>
            <%= fullname %>
        </td>
        <td>
            <a href="#edit" class="edit" >Edit</a>&nbsp;<a href="#Delete" class="delete">Delete</a>
        </td>        
</script>

<script id="edit-row-template" type="text/template">
        <td>
            <input type="text" name="username" value="<%= username %>">
        </td>
        <td>
            <input type="text" name="fullname" value="<%= fullname %>">
        </td>
        <td>
            <a href="#Save" class="save" >Save</a>&nbsp;<a href="#Cancel" class="cancel">Cancel</a>
        </td>        
</script>
                
<div id="grid">
</div>

CSS

table, tr, td, th, thead {
    padding: 5px;
    margin: 5px;
    border: 2px solid #ccc;
}

thead {
    background-color: #555;
    color: #fff;
}

JavaScript

// A Grid Row
var GridRow = Backbone.Marionette.ItemView.extend({
    template: "#row-template",
    tagName: "tr",
    
    events: {
        "click .edit": "editRow",
        "click .delete": "deleteRow",
         "keyup ":"handleKeys"
       
    },
    
    initialize: function(){
        _.bindAll(this,"modelChanged");
        var thisView = this;
        this.model.on('change', this.modelChanged);
    },
    
    onRender:function(){
    //add id="#cid" to the tr
        this.$el.attr('id',this.model.cid);        
    },
    
    onClose: function(){
         this.model.unbind("change", this.modelChanged);
    },
    
    modelChanged: function () {
            var thisView= this;
            console.log(thisView.cid+":"+JSON.stringify(thisView.model.toJSON()));
    },
    
    editRow: function(){
        vent.trigger("editRow",this.model);
    },
    
    deleteRow: function(){
    },
    
    handleKeys: function(e) {
         console.log(this.cid+"Handle Keys");
    }
});
//Edit Grid Row
var EditGridRow = Backbone.Marionette.ItemView.extend({
    template: "#edit-row-template",
    tagName: "tr",
    
    events: {
        "click .save": "saveRow",
        "click .cancel": "cancelRow",
         "keyup ":"handleKeys"
    },
    
    initialize: function(){
        _.bindAll(this,"modelChanged");
        var thisView = this;
        this.model.on('change', this.modelChanged);
    },
    
    onRender:function(){
    //add id="#cid" to the tr
        this.$el.attr('id',this.model.cid);        
    },
    
    onClose: function(){
         this.model.unbind("change", this.modelChanged);
    },
    
    modelChanged: function () {
         var thisView= this;
         console.log(thisView.cid+":"+JSON.stringify(thisView.model.toJSON()));
    },
    
    saveRow: function(){
        this.model.set('fullname',$("input[name='fullname']").val());
        this.model.set('username',$("input[name='username']").val());
        vent.trigger("saveRow",this.model);
   ...