Knockout.js Custom Money Binding
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<body class='ui-widget'>
<header class='ui-widget-header'>
<h1>Give me all of your money</h1>
<br />
<h2> All your hugs and kisses too</h2>
</header>
<div class='ui-widget-content'>
<p>
<label>How Much?</label> <input type="text" data-bind="money:Cash" /> or? <input type="text" data-bind="value:Cash" /></p>
<p>
<label>Non inputs too!</label> <span data-bind="money:Cash" /></p>
<p>
<label>Normal binding:</label> <span data-bind="text:Cash" /></p>
</div>
</body>
CSS
.money {text-align:right}
.money.negative{color:#f00}
JavaScript
if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (str) {
return this.substring(0, str.length) === str;
}
};
function setSelectionRange(input, selectionStart, selectionEnd) {
if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
}
else if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
}
}
function setCaretToPos (input, pos) {
setSelectionRange(input, pos, pos);
}
(function ($) {
var cleanInput = function (value) {
value = value || '0';
value = value == "-" ? "0" : value;
console.log("dirty str: " + value);
var isNegative = value.startsWith('(') || value.startsWith('-');
var cleanStr = value.replace(/[^0-9.]/g, '');
console.log("cleaned str:" + cleanStr);
var result = parseFloat(cleanStr) * (isNegative? -1 : 1);
console.log("cleaned: " + result);
return result == Number.NaN ? 0 : result;
}
var formatInput = function (value) {
toks = value.toFixed(2).replace('-', '').split('.');
var display = '$' + $.map(toks[0].split('').reverse(), function (elm, i) {
return [(i % 3 == 0 && i > 0 ? ',' : ''), elm];
}).reverse().join('') + '.' + toks[1];
display = value < 0 ? '(' + display + ')' : display;
console.log("formatted: " + display);
return display;
}
ko.bindingHandlers.money = {
init: function (elm, valueAccessor) {
$(elm).keydown(
function(e){
-1!==$.inArray(e.keyCode,[46,8,9,27,13,110,190])||/65|67|86|88/.test(e.keyCode)&&(!0===e.ctrlKey||!0===e.metaKey)||35<=e.keyCode&&40>=e.keyCode||(e.shiftKey||48>e.keyCode||57<e.keyCode)&&(96>e.keyCode||105<e.keyCode)&&e.preventDefault();
...