inline autocorrection
by bman654
HTML
<button type="button" data-bind="click: toggleStuff">Toggle stuff</button>
<hr />
<div data-bind="if: showStuff">
<label>Number: <input type="text" data-bind="value: number, autocorrect: numeric" /></label>
<label>No spaces: <input type="text" data-bind="value: name, autocorrect: nospaces, valueUpdate: 'keyup'" /></label>
<label>non-negative and less than Number: <input type="text" data-bind="value: number2, autocorrect: clip(0,number())" /></label>
<label>Number (no autocorrection): <input type="text" data-bind="value: number" /></label>
<label>Name (no autocorrection): <input type="text" data-bind="value: name, valueUpdate: 'keyup'" /></label>
</div>
CSS
label { display:block; }
JavaScript
var key = "__Vkey";
ko.bindingHandlers.value.preprocess = function (valueExpression, bindingName, addBinding) {
var x = "(ko.utils.domData.get($element,'" + key + "')||("+valueExpression+"))";
console.log("preprocess",bindingName,valueExpression, x);
addBinding(key, valueExpression);
return x;
};
ko.bindingHandlers.value.after.push("autocorrect");
ko.bindingHandlers.autocorrect = {
preprocess: function (valueExpression) {
//return "(with(window.V){" + valueExpression + "})";
return "window.V." + valueExpression;
},
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("V init", valueAccessor);
if (allBindings.has("value")) {
var c = ko.computed({
disposeWhenNodeIsRemoved: element,
read: function() {
var v = allBindings.get(key);
return ko.unwrap(v);
},
write: function (value) {
var validator = valueAccessor();
var oldValue = ko.unwrap(v);
var newValue = validator(value, oldValue);
var v = allBindings.get(key);
console.log("writing", value, newValue);
if (ko.isWriteableObservable(v)) {
v(newValue);
c.notifySubscribers(v()); // temporary
}
}
});
ko.utils.domData.set(element, key, c);
}
}
};
// autocorrectors
window.V = {
numeric: function (n, o) {
return parseFloat(n);
},
clip: function (min, max) {
return function (n, o) {
if (n < min) return min;
if (n > max) return max;
return n;
};
},
nospaces: function (n, o) {
return (""+n).replace(/ /g,"");
}
};
// viewmodel
var vm = {
name:...