knockout.js, automatically add new row to table when editing last one

http://stackoverflow.com/questions/7227239/knockout-js-automatically-add-new-row-to-table-when-editing-last-one

by manchagnu

HTML

<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<table>
    <thead>
        <tr>
            <th>
                Number
            </th>
            <th>
            </th>
        </tr>
    </thead>
    <tbody data-bind="template:{name:'tableRow', foreach: tableRows}">
    </tbody>
</table>
<script id="tableRow" type="text/html">
    <tr>
        <td>
            <input type="text" style="width:40px;" data-bind="value: number, valueUpdate: 'keyup'" />
        </td>
        <td>
            <button type="button" data-bind="click: function(){ $data.remove(); }">
                delete
            </button>
        </td>
    </tr>
</script>

JavaScript

function tableRow(number, ownerViewModel) {
    this.number = ko.observable(number);
    this.remove = function() {
        ownerViewModel.tableRows.destroy(this);
    }
}

function tableRowsViewModel() {
    var that = this;
    this.tableRows = ko.observableArray([]);
    this.addNewRow = function() {
        this.tableRows.push(new tableRow('', that));
    }
    this.addNewRow();
    
    //dependentObservable to represent the last row's value
    this.lastRowValue = ko.dependentObservable(function() {
       var rows = that.tableRows();
       return rows.length ? rows[rows.length - 1].number() : null; 
    }).extend({ throttle: 10 });
    
    //subscribe to changes to the last row
    this.lastRowValue.subscribe(function(newValue) {
        if (newValue) {
           that.tableRows.push(new tableRow('', that));
        }
    });
}



$(document).ready(function() {
    ko.applyBindings(new tableRowsViewModel());
});