Soma de inputs financeiro com multiple

by Ivan Ferrer

HTML

<h2>Itens da lista:</h2>

<div id="qtde_elementos">
    <form action="" method="post">
     <select class="valores" name="valores" multiple>
     <option data-id="0" data-valor="25,00" value="1">opção 1</option>
     <option data-id="1" data-valor="20,00" value="1">opção 2</option>
     </select>
    </form>
</div>
<div class="total" data-total>Total: <span>R$ 0,00</span>
</div>

CSS

body {
    font-family: Arial;
    font-size:14px;
}
#qtde_elementos input[type="number"] {
    width:190px;
    padding:5px;
    margin:6px 0;
}
#qtde_elementos div {
    display:block;
}
.total span {
    font-weight: bold;
    margin-left:12px;
    margin-top:10px;
}

JavaScript

$('select.valores').change(function () {
$('select.valores option:selected').each(function() {
        var data = {
            id: $(this).data('id'),
            value: $(this).data('valor')
        }
        $('body').trigger('total.update', [data]);
    });
});

(function () {
    var Total = function (el) {
        this.$el = el;
        this.value = 0;
        this.products = new Array();
        $('body').on('total.update', $.proxy(this, 'update'));
    }

    Total.prototype.update = function (e, data) {
        this.products[data.id] = data.value
        this.value = this.products.reduce(this.reduce);
        this.render.apply(this);
    }

    Total.prototype.reduce = function (prev, current) {
        return parseFloat(current) + parseFloat(prev);
    }

    Total.prototype.render = function () {
        this.$el.find('span').html(currencyFormatted(parseFloat(this.value), 'R$'));
    }

    $(document).ready(function () {
        $el = $('[data-total]');
        var instance = $el.data('total-instance') || new Total($el);
        $el.data('total-instance', instance);
    });
})();

function currencyFormatted(value, str_cifrao) {
    return str_cifrao + ' ' + value.formatMoney(2, ',', '.');
}

Number.prototype.formatMoney = function (c, d, t) {
    var n = this,
        c = isNaN(c = Math.abs(c)) ? 2 : c,
        d = d == undefined ? "." : d,
        t = t == undefined ? "," : t,
        s = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};