http://stackoverflow.com/questions/42030918/how-do-i-make-a-knockout-custom-binding-for-textboxes-that-formats-numbers

by jlspake

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.min.js"></script>
<div>

  <label>Raw value: </label><span data-bind="text: marketRate"></span>
  <br/>  <br/>
  <label>Formatted: </label>
  <input type="text" data-bind="numericValue: marketRate, precision: 2" />
  
</div>

JavaScript

var viewModel = function(){
	var self = this;    
  self.isSelected = ko.observable(true);
  self.marketRate = ko.observable(5.01375).extend({
        required: { message: 'Required', onlyIf: function() { return self.isSelected(); }},
        min: { params: 0, onlyIf: function () { return self.isSelected(); } },
        max: { params: 999999.99, onlyIf: function() { return self.isSelected(); } },
        pattern: { message: 'Maximum 2 decimal places', params: /^\d*(\.\d{1,2})?$/, onlyIf: function () { return self.isSelected(); } }
    });
  
  return self;
}

ko.bindingHandlers.numericValue = {
		init: function (element, valueAccessor, allBindings) {
      var valueObservable = valueAccessor();

      ko.utils.registerEventHandler(element, "change", function () {
        valueObservable($(element).val());
      });
		},
  	update: function (element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()),
            precision = ko.utils.unwrapObservable(allBindingsAccessor().precision) || ko.bindingHandlers.numericValue.defaultPrecision;

        var formattedValue = '';
        if (value) {
            if (typeof value === "string") {
                value = parseFloat(value);
            }
            formattedValue = value.toFixed(precision);
        } else {
            value = 0;
            formattedValue = value.toFixed(precision);
        }
        $(element).val(formattedValue);
    },
    defaultPrecision: 1
}


ko.validation.init();
ko.validation.makeBindingHandlerValidatable('numericValue');
ko.applyBindings(new viewModel());