I have a ViewModel in Knockout that is derived mainly from the mapping plugin (ie, dynamically). This works fine. However, now my client wants me to make sure that all inputs have whitespace trimmed off before submitting to the server. Obviously, the trimming code is very simple, but being relatively new to Knockout, I'm not sure exactly where to put this code. I read about extenders, but that seems pretty verbose and repetitive to go back and add that to each observable. Plus I'm not even sure I can do that to dynamically generated observables (a la, the mapping plugin).
Is there any central mechanism I can extend/override where I can inject some trimming code every time an observable changes? Basically I'm trying to avoid hours spent going through all of our forms and adding special binding syntax in the HTML if I don't have to.
Thanks.
You can create a custom binding that calls the
value
binding internally, or you can overwrite thevalue
binding to auto-trim before it actually binds (not-recommended).The basic idea:
value
bindingcomputed
read
andwrite
from the computed instead of from the original observableIf you don't care about some unneeded
valueHasMutated
s in your modelThe tricky part is to determine what updates you want to receive in your model... The example below will not trigger
valueHasMutated
nor mutate your model's observable. However, if you change your model value to an untrimmed string, the binding handler will reset it instantly. E.g.:myObs(" test ")
will triggerChange: " test "
, andChange: "test"
If you only need trimming from the UI to the model, and don't mind some extra updates, you can use:
Overwriting the default
value
bindingTo use this behaviour as standard behaviour (again, not recommended), you can do:
I had the same problem. I wrote an extension so you can call
trimmed
in your view-model without having to change your bindings. For example:The extension:
Code is on JSFiddle with examples.
You could write a custom binding that trims the observable. Something similar to this
http://jsfiddle.net/belthasar/fRjdq/
Just in case anyone comes across this problem with newer versions of Knockout, the current top-ranked answer will not work correctly.
Here's an updated fiddle and code to show the changes needed:
If anyone knows why the
extend
is now needed, please let me know. It took me forever to figure out why it wasn't working correctly in Knockout 3.1.0Using Joe's solution as a starting point, We implemented it just a little differently.
Notice:
ko.observable()
has nothing in the parenthesestrimmed
read function simply returnsthis()
and doesn't get any null or undefined exceptions.Model code:
The extension: