I'm using knockout and the mapping plugin to automatically create my view model. I have a bunch of amounts in my view model that I bind to textboxes. When a user changes an amount in a textbox, all I want is to make sure what they entered is a number, and that it's greater than 0, and if it isn't I want to replace what they entered with 0. This seems like it should be SO simple... with a custom binding or subscribe function.

Everything I'm reading about knockout validation talks about extenders and read/write computed observables, or adding yet another plugin (such as jquery validation). They all seem like overkill for the situation, and the extenders/computed observables have to be explicitly declared for each observable you want to validate. I have a lot of amounts that are automatically created using the mapping plugin, so this doesn't seem reasonable.

2 Answers
2

For your specific scenario, one way to handle this is by creating a custom binding that is able to intercept the value and do your validation. This can be done by creating a writeable computed in the custom binding to bind against. The advantage is that you don't have to worry about the mapping plugin customizing your object creation.

The way that I implemented it here, you would need to call is as a function forcePositive() so the writeable is initialized. This is so that you can just use the mapping plugin without any customization and just do this on any observable that you want to use this functionality with.

Thanks for the detailed reply! It amazes me that something so simple that seems as if it should be standard with any type of input has to be this complicated. It's a simple check on user input before it gets written. I guess this is how it has to be though. I'll try your solution and confirm it later this afternoon. Thanks again.
–
wired_inSep 6 '12 at 15:55

1

You can try to simplify the code, but the solution above was meant to handle the various scenarios efficiently and allow you to continue using the mapping plugin without customizing object creation. Good luck!
–
RP NiemeyerSep 6 '12 at 15:58

There's nothing wrong on your part, I just tested it and it works perfectly. I'm just saying that it seems like knockout should offer a more simple solution for such a simple and standard case.
–
wired_inSep 6 '12 at 16:09

It seems like you need to apply the extender to every observable number in your viewmodel when it is declared. I'm using the mapping plugin to automatically create my viewmodel, so all of my number observables have already been created, and thus it's too late for me to declare them with vm.number = ko.observable(0).extend({ number: true }); Also, I have a lot of number observables in my model, and I don't want to have to explicitly apply this to every single one of them.
–
wired_inSep 6 '12 at 15:50