Handlebars outputting table data

by Ben Clayton

HTML

<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars.min-c90cfe2.js"></script>
<script id="grid-template" type="text/x-handlebars-template">
    <div class='close'>Close X</div>
<table>
    <thead>
        <tr>
        {{#each gridheader}}
            <th>{{this}}</th>
        {{/each}}
        </tr>
    </thead>
    <tbody>
    {{#each exgriddata}}
        <tr class='row'>
            {{#each this}}
            <td class='col'>({{row}},{{col}})<input id='{{id}}' class='cell' value="{{this.data}}" /></td>
            {{/each}}
            <td><button data-row="{{@index}}" class='delete'>-</button></td>
        </tr>
    {{/each}}
    </tbody>
</table>
</script>

<div class="output"></div>

CSS

.close {cursor:pointer;}

JavaScript

function hbgrid(cfg){
    this.cfg = cfg || {};
    this.cfg.renderto = this.cfg.renderto || '.body';
    this.gridheader = this.cfg.header || ['header1','header2','header3'];
    this.griddata = this.cfg.data || [[1,2,3],[4,5,6],[7,8,9]];
    
    this.exgriddata;
    
    this.extenddata = function(){
        var cnt=0;
        this.exgriddata=[];
        for(var i=0;i<this.griddata.length;i++){
            var rr = [];
            for(var j=0;j<this.griddata[i].length;j++){
                var ex={
                        parentIndex:i,
                    row:i,col:j,
                        id:'cell'+(cnt++),
                        data:this.griddata[i][j]
                       };
                 rr.push(ex);
            }
            this.exgriddata.push(rr);
        }
    }
    
    this.render = function(){
        this.extenddata();
        this.source = $("#grid-template").html();
        this.template = Handlebars.compile(this.source);
        $(this.cfg.renderto).html(this.template(this));
        
        var p=this;
        $(this.cfg.renderto+' .row').each(function(r){
            $(this).data('row' ,r);
            $(this).find('.col').each(function(c){
                var inp=$(this).find('input');
                //console.log('idx'+idx);
                // add data attributes to each cell
                inp.data('obj',p)
                .data('bind',p.exgriddata[r][c])
                .data('row' ,r)
                .data('col' ,c);
     
                // add listeners to each cell
                inp.on('click',function(){
                    p.click(inp);
                });
                inp.on('change',function(){
                    p.change(inp);
                });
            })
            $(this).find('.delete').on('click',function(){
               p.delete($(this)); 
            });
        });
        $(this.cfg.renderto+' .close').on('click',function(){
           p.close(); 
        });
    };

    this.delete =...