JSFiddle - React, Tailwind, and code Playground

by pxfunc

HTML

<table width="100%" cellspacing="0" cellpadding="0" class="basket-bsol">
         <thead>
            <tr>
                <th width="10%" valign="baseline">Remove item</th>
                <th width="10%" valign="baseline">Quantity</th>
                <th width="44%" valign="baseline">Item</th>
              <th width="12%" valign="baseline" class="grey-disabled">Unit price</th>
                <th width="12%" valign="baseline">Member price</th>
                <th width="12%" valign="baseline" class="subtotal-price">Subtotal</th>
            </tr>
        </thead>
        <tbody>
            <tr class="basket-row">
                <td align="center" valign="baseline"></td>
                <td align="center" valign="baseline"><input id="basket-quantity1" class="search-input" type="text" value="99999" name="" maxlength="6" /></td>
                <td class="basket-item-bname" align="center" valign="baseline">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vestibulum, leo vel auctor tristique, orci dui aliquam enim, eu accumsan eros purus ac nulla.</td>
                  <td class="grey-disabled" align="center" valign="baseline"><b>&pound;99999999.99</b></td>
                  <td class="price-enabled highlight" align="center" valign="baseline"><b>&pound;99999999.99</b></td>
                  <td class="subtotal-price highlight" align="center" valign="baseline"><b>&pound;99999999.99</b></td>
            </tr>
            <tr class="basket-row">
                <td align="center" valign="baseline"></td>
                <td align="center" valign="baseline"><input id="basket-quantity2" class="search-input" type="text" value="99999" name="" maxlength="6" /></td>
                <td class="basket-item-bname" align="center" valign="baseline">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur vestibulum, leo vel auctor tristique, orci dui aliquam enim, eu accumsan eros purus ac nulla.</td>
                  <td class="grey-disabled"...

CSS

.basket-bsol{
    font-size:0.688em;
    color:#000;
    border-bottom:#FFF 2px solid;
}

.basket-bsol th{
    text-align:center;
    background-color:#d0e4f5;
    border-bottom:#FFF 2px solid;
    border-left:#FFF 2px solid;
    padding:2%  1%;/*22px 11px 13px 11px;*/
}

.basket-bsol td{
    background-color:#e9f1f8;
    padding:1%;/*22px 11px 13px 11px;*/
    border-left:#FFF 2px solid;
    text-align:center;
}

.basket-bsol td.basket-item-bname{
    text-align:left;
}

#basket-quantity{
    width:55px;
    padding-left:0;
    font-size:1em;
    color:#000;
    text-align:center;
}

.basket-bsol td.price-enabled{
    background-color:#d0e4f5;
}

.basket-bsol td.subtotal-price,
.basket-bsol th.subtotal-price{
    background-color:#9dd4f3;
}

.basket-bsol td.highlight,
.basket-bsol th.highlight{
    background-color:#ffbc0a;
}

.basket-bsol tfoot td{
    background:none;
}

.basket-bsol td.total-price{
    background-color:#9dd4f3;
}

.basket-bsol td.table-note,
.basket-bsol td.basket-alert-col{
    background:none;
    text-align:left;
    padding:0;
}

.basket-bsol td.basket-alert-col{
    position:relative;
}

.basket-alert{ /*Basket Alert*/
    position:absolute;
    top:-7px;
    left:0px;
    z-index:2;
    width:225px;
    height:61px;
    background:url(../images/basket-alert-bg.png) no-repeat top left;
}

@-moz-document url-prefix() { /* Hack Firefox*/
    .basket-alert {
        left: 614px;
    }
} 

.basket-alert p{
    color:#095f9e;
    text-align:center;
    padding:14px 20px;
}

.alert-message{
    background-color:#fff2de;
    color:#db5902;
    font-size:0.75em;
}

.alert-message p{
    margin-bottom:5px;
}

.alert-icon{
    background-position:-26px -148px;
}

JavaScript

// traditional setInterval to check if input changed...
var isPriceChanged = function() {
        $('.search-input').each(function() {
            var $that = $(this),
                oldvalue = $that.data('oldvalue');
            
            // initialize oldvalue
            if (oldvalue === undefined) {
                $that.data('oldvalue', $that.val());
            } else {
                // update/highlight fields if value has changed
                if ($.trim($that.val()) !== $.trim(oldvalue)) {
                    highlightChangedFields($that);
                    $that.data('oldvalue', $that.val());
                }
            }
        });
    },
    priceChangedTimer = setInterval(isPriceChanged, 500); // check input fields every half sec

// *new html5* 'input' event
$('.search-input').bind('input', function() {
    highlightChangedFields($(this));
    // disable traditional way if this event is called
    clearInterval(priceChangedTimer);
});

var timer = undefined,
    highlightChangedFields = function($that) {
        var $row = $that.closest('.basket-row')
            $price = $row.find('.price-enabled'),
            $subtotal = $row.find('.subtotal-price'),
            $fields = $.merge($price, $subtotal);
        
        // clear previous timers
        clearTimeout(timer);
        
        // update price values
        // probably use some kind of money formatter
        // such as: http://stackoverflow.com/questions/149055/how-can-i-format-numbers-as-money-in-javascript
        $price.text('£' + $that.val());
        $subtotal.text('£' + $that.val());
        
        // highlight price fields
        $fields.stop(true, true).effect('highlight', {color: '#ffbc0a'}, 2000);
    };