Knockout Custom Binding for number values
by homer2
HTML
<script src="http://rniemeyer.github.com/KnockMeOut/Scripts/jquery.tmpl.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css">
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
value: <input type="text" data-bind="value: number" /><br/>
valueNumeric: <input type="text" data-bind="valueNumeric: number" /><br/>
valuePercent: <input type="text" data-bind="valuePercent: number" /><br/>
textPercent: <span data-bind="textPercent: number" ></span><br/>
text number extend Percent: <span data-bind="text: number.extend({ percent: 2 })" ></span><br/>
value number extend Percent: <input type="text" data-bind="value: number.extend({ percent: 2 })" /><br/>
text numberPercent: <span data-bind="text: number.extend({ percent: 4 })" ></span><br/>
value number extend Percent: <input type="text" data-bind="value: number.extend({ percent: 4 })" /><br/>
<button>val</button>
<div data-bind="text: ko.toJSON($root)"></div>
CSS
.header {
font-size: 16px;
font-family: sans-serif;
font-weight: bold;
margin-bottom: 20px;
}
JavaScript
ko.bindingHandlers.valueNumeric = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: underlyingObservable,
write: function (newValue) {
var parsedValue = parseFloat(newValue.replace(/[^\d.]/g, ''));
underlyingObservable(isNaN(parsedValue) ? newValue : parsedValue);
}
});
ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
},
update: ko.bindingHandlers.value.update
};
ko.bindingHandlers.valuePercent = {
init: function (element, valueAccessor, allBindingsAccessor) {
var underlyingObservable = valueAccessor();
var interceptor = ko.computed({
read: underlyingObservable,
write: function (newValue) {
var parsedValue = parseFloat(newValue.replace(/[^\d.]/g, '')) / 100;
underlyingObservable(isNaN(parsedValue) ? newValue : parsedValue);
}
});
ko.bindingHandlers.value.init(element, function () { return interceptor }, allBindingsAccessor);
},
update: function (element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor();
element.value=ko.utils.unwrapObservable(value)*100;
}
};
ko.bindingHandlers.textPercent = {
//init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
// //init logic
//},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var val = parseFloat(ko.utils.unwrapObservable(valueAccessor()));
element.innerHTML = (val * 100).toFixed(2) + "%";
}
}
ko.extenders.percent = function(target, precision) {
//create a writeable computed observable to intercept writes to our observable
var result = ko.computed({
read: function(){
//return...