Automatic Calculated form

An automatic calculated form with JavaScript.

by secretgspot

HTML

<table cellpadding="0" cellspacing="0" border="0">
    <tr>
        <th>Whats Included</th>
        <th>Lights N' Sights</th>
        <th>Night Venture</th>
        <th>Falls View Lights</th>
        <th>Night Hawk</th>
        <th>Evening Tourist</th>
        <th>Evening Overnighter</th>
    </tr>
    <tr align="center" data-value="25">
        <td align="left">Historic Niagara On The Lake</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
    </tr>
    <tr align="center" data-value="15">
        <td align="left">Historic Queenston Village</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
    </tr>
    <tr align="center" data-value="15">
        <td align="left">Niagara Parks Sight</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
    </tr>
    <tr align="center" data-value="85">
        <td align="left">Niagara Helicopter Ride</td>
        <td></td>
        <td></td>
        <td></td>
        <td>a</td>
        <td>a</td>
        <td></td>
    </tr>
    <tr align="center" data-value="15">
        <td align="left">Clifton Hill Tourist Shops</td>
        <td>a</td>
        <td>a</td>
        <td></td>
        <td>a</td>
        <td></td>
        <td>a</td>
    </tr>
    <tr align="center" data-value="45">
        <td align="left">Sheraton Fallsview Hotel Buffet</td>
        <td></td>
        <td></td>
        <td>a</td>
        <td></td>
        <td>a</td>
        <td></td>
    </tr>
    <tr align="center" data-value="15">
        <td align="left">Niagara Falls Natural Wonder</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
        <td>a</td>
    </tr>
    <tr align="center" data-value="15">
        <td align="left">Journey Behind the Falls</td>
        <td></td>
        <td>a</td>
        <td></td>
       ...

CSS

table th{background-color:#eee; margin-top:40px}
table td{overflow:wrap; width:130px; height:40px; line-height:20px;}
table td{border-bottom:1px solid #cccccc;}
table th{height:40px;}
table input { width: 40px; }

JavaScript

var $table = $('table'),
    $rows = $table.find('tr'),
    colNum = $rows.eq(0).find('th').length,
    columns = [],
    total = [],
    numPeople = [],
    $inputs, num, v, i, tds;

// calculate column values
$rows.each(function(r) {
    // row value
    v = parseFloat($(this).attr('data-value')) || 0;
    if (v !== 0) {
        tds = $(this).find('td');
        for (i = 0; i < colNum; i++) {
            if (tds.eq(i+1).text() !== "") {
                columns[i] = (columns[i] || 0) + v;
            }
        }
    }
});
// for this demo columns will end up with
// [85, 100, 115, 170, 215, 90]
// console.log(columns);

$table.find('input').on('click keyup', function() {
    total = [];
    numPeople = [];
    // calculate number of people and make totals
    $table.find('tr[data-discount]').each(function(j){
        v = parseFloat( $(this).attr('data-discount') );
        $inputs = $(this).find('input');
        for (i=0; i < colNum-1; i++){
            num = parseInt($inputs.eq(i).val(), 10);
            total[i] = (total[i] || 0) + (columns[i] || 0) * v * num;
            numPeople[i] = (numPeople[i] ||0) + num;
        }
    });
    // display sub totals
    $table.find('tr.sub-total').find('td:gt(0)').each(function(j){
        if (total[j] !== 0) {
            $(this).text( '$' + columns[j] );
        }
    });
    // display totals
    var final = 0;
    for (i=0; i < colNum-1; i++){
        final += total[i];
    }
    $table.find('tr.total').find('td:eq(1)').text( '$' + final );
});