morestabby

by madcapnmckay

HTML

<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<h2>Before</h2>
<table class="equipment before">
<thead>
  <tr>
    <th>Item</th>
    <th>Int</th>
    <th>IAS</th>
    <th>Crit %</th>
    <th>Crit Dmg</th>
    <th>Min</th>
    <th>Max</th>
  </tr>
</thead>
<tbody data-bind="foreach: items">
  <tr>
    <td data-bind="text: item"></td>
      <td><input data-bind="value: int" /></td>
    <td><input data-bind="value: ias"/></td>
    <td><input data-bind="value: critpc"/></td>
    <td><input data-bind="value: critdmg"/></td>
    <td><input data-bind="value: min"/></td>
    <td><input data-bind="value: max"/></td>
  </tr>
</tbody>
<tfoot>
  <tr>
    <td>TOTAL</td>
    <td data-bind="text: intTotal"></td>
    <td data-bind="text: iasTotal"></td>
    <td data-bind="text: critpcTotal"></td>
    <td data-bind="text: critdmgTotal"></td>
    <td data-bind="text: minTotal"></td>
    <td data-bind="text: maxTotal"></td>
  </tr>   
</tfoot>
</table>
<h2>After</h2>
<table class="equipment after">
<thead>
  <tr>
    <th>Item</th>
    <th>Int</th>
    <th>IAS</th>
    <th>Crit %</th>
    <th>Crit Dmg</th>
    <th>Min</th>
    <th>Max</th>
  </tr>
</thead>
<tbody data-bind="foreach: after">
  <tr>
    <td data-bind="text: item"></td>
      <td><input data-bind="value: int" /></td>
    <td><input data-bind="value: ias"/></td>
    <td><input data-bind="value: critpc"/></td>
    <td><input data-bind="value: critdmg"/></td>
    <td><input data-bind="value: min"/></td>
    <td><input data-bind="value: max"/></td>
  </tr>
</tbody>
<tfoot>
  <tr>
    <td>TOTAL</td>
    <td data-bind="text: intTotal"></td>
    <td data-bind="text: iasTotal"></td>
    <td data-bind="text: critpcTotal"></td>
    <td data-bind="text: critdmgTotal"></td>
    <td data-bind="text: minTotal"></td>
    <td data-bind="text: maxTotal"></td>
  </tr>   
</tfoot>
</table>

<div class="after"></div>
<h3>Skills</h3>
Pierce The Veil? <input type='checkbox' data-bind="checked:...

CSS

body { font-family: Courier; }
td input, th { width: 30px }
h2 { font-size: 1.5em; }
h3 { font-size: 1.3em; }
h2, h3 { margin: 1em 0 0.5em; }

JavaScript

// Class to represent an item in the hero grid


function HeroItem(config, link) {
    var self = this, prop;
    self.item = config.item;
    self.int = ko.observable(config.int);
    self.ias = ko.observable(config.ias);
    self.critdmg = ko.observable(config.critdmg);
    self.critpc = ko.observable(config.critpc);
    self.min = ko.observable(config.min);
    self.max = ko.observable(config.max);

    if (link) {
        for (prop in link) {
            if (link.hasOwnProperty(prop) && ko.isObservable(link[prop])) {     
                console.log("subscribing " + prop);
                link[prop].subscribe((function(p) {
                    return function (newValue) {
                        console.log("updating " + p+ " to " + newValue);
                        self[p](newValue);
                    }
                })(prop));
            }
        }        
    }
}

// Overall viewmodel for this screen, along with initial state


function HeroViewModel() {
    var self = this;

    // Editable data
    self.items = ko.observableArray([
        new HeroItem({ item: "Helm", int: 167, ias: 0, critpc: 0, critdmg: 0, min: 0, max: 0 }),
        new HeroItem({ item: "Shoulders", int: 161, ias: 0, critpc: 0, critdmg: 0, min: 0, max: 0 }),
        new HeroItem({ item: "Amulet", int: 244, ias: 0, critpc: 0, critdmg: 55, min: 0, max: 0 })
    ]);

    self.after = ko.observableArray(ko.utils.arrayMap(self.items(), function(i) {
        return new HeroItem($.extend({}, ko.toJS(i)), i);
    }));
    
    
    // Column totals
    self.intTotal = ko.computed(function() {
        var total = 0;
        $.each(self.items(), function() {
            total += parseInt(this.int())
        })
        // Base INT - 187
        return total + 187;
    });
    self.iasTotal = ko.computed(function() {
        var astotal = 0;
        var weapontotal = 0;
        $.each(self.items(), function() {
            if (this.item != "Weapon") {
                astotal +=...