Knockoutで。整形された数値

HTML

<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>
<script src="https://rawgit.com/SteveSanderson/knockout-es5/master/dist/knockout-es5.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/sugar/1.4.1/sugar-full.development.min.js"></script>
<script src="http://mbest.github.io/knockout.punches/knockout.punches.js"></script>
<h3>IMEの有効無効問わず、数値のみを入力させ、ナンバーフォーマットする</h3>
<dl>
    <dt>Formatted Price</dt>
    <dd><input type="text" class="number" data-bind="textInput:formattedPrice" /></dd>
    
    <dt>Raw Price</dt>
    <dd>{{price}}</dd>
    
    <dt>Formatted Quantity</dt>
    <dd><input type="text" class="number" data-bind="value:formattedQuantity" /></dd>
    
    <dt>Raw Quantity</dt>
    <dd>{{quantity}}</dd>
</dl>

CSS

input.number{
    text-align:right;
    width:7em;
}

JavaScript

function VM(){
    var vm = this;
    vm.price=130;
    vm.quantity=2.15;
    ko.track(vm);
    numberFormattedProperty(vm,"price",{prefix:'\u00a5'}); // u+00a5 = ¥
    numberFormattedProperty(vm,"quantity",{suffix:'kg',place:2});
    
};

ko.punches.enableAll();

ko.applyBindings(new VM());









function numberFormattedProperty(model, prop, option) {
    var _default = {
        prefix: '',
        suffix: '',
        place: 0,
        thousands: ',',
        decimal: '.',
        allowMinus: false,
        round: 'round' // round | ceil | floor  (四捨五入, 切上げ, 切り捨て)
    };
    option = ko.utils.extend(_default, option);
    ko.defineProperty(model, "formatted" + prop.camelize(), {
        get: function () {
            var value = ko.unwrap(model[prop]);
            if (value == null)
                return "";
            return option.prefix + value[option.round](option.place).format(option.place, option.thousands, option.decimal) + option.suffix;
        },
        set: function (value) {
            model[prop] = NaN; //force mutant event
            var replacer = new RegExp('[^' + (option.allowMinus ? '\\-' : '') + '0-9\\.]' + (option.place > 0 ? '||[' + RegExp.escape(option.decimal) + ']' : ''), 'g'); // 丸めるケタが小数点以下なら、 小数点文字の入力を許可
            if (value == '')
                model[prop] = null;
            else
                model[prop] = (+value.hankaku().replace(replacer, ''))[option.round](option.place);
        }
    });
};