Permalink
Browse files

added support for conditional validations

  • Loading branch information...
1 parent 2923dca commit 3412139a1e6e43ca4e39c4f5134e1b83dd1333e5 @dnagir committed Dec 22, 2011
View
@@ -105,7 +105,7 @@ class @Page extends ko.Model
@presence 'name', {message: 'give me a name, yo!'}
# Conditional validation - use the `page` model passed in as argument
- @presence 'name', if: -> @persisted?
+ @presence 'name', if: -> @persisted()
# Custom inline validation
@custom 'name', (page) ->
@@ -134,17 +134,18 @@ Here's how you would check whether the model is valid or not (assuming presence
```coffee
page = new @Page name: ''
page.isValid() # false
+page.errors.name() # "can't be blank"
page.name = 'Home'
page.isValid() # true
+page.errors.name() # null
-page.performValidation() # To force the validation, you don't need to do that really
```
-Every validator has its own set of options.
+Every validator has its own set of options. But the following are applied to all of them (including yours):
-The general format of the validator is: `validatorName field1, field2, field3, {optional: options, asA: hash}`.
-But it is really up to the falidator how to treat those.
+- `only: -> truthy or falsy` - only apply the validation when the condition is truthy. `this` points to the model so you can access it.
+- `except:` - is the opposite to only. Both `only` and `except` can be used, but you should make sure those are not mutually exclusive.
## Model Events
@@ -24,7 +24,13 @@ class ValidationContext
me._validations[field] ||= []
validatorSubscriber = ko.dependentObservable ->
- validator.call(me, me.subject, field, options)
+ {only, except} = options
+ allowedByOnly = !only or only.call(me.subject)
+ deniedByExcept = except and except.call(me.subject)
+
+ shouldValidate = allowedByOnly and not deniedByExcept
+
+ validator.call(me, me.subject, field, options) if shouldValidate
validatorSubscriber.subscribe (newError) ->
err = me.subject.errors[field]
@@ -1,6 +1,6 @@
class Page extends ko.Model
- @fields 'name', 'correct', 'multiple'
+ @fields 'name', 'correct', 'multiple', 'conditional'
@validates: (me) ->
@presence 'name'
@@ -10,6 +10,10 @@ class Page extends ko.Model
unless page.correct() then 'should be correct' else null
+ @presence 'conditional', {only: (-> @only()), except: (-> @except()) }
+
+ only: -> true
+ except: -> false
describe "Validations", ->
@@ -35,3 +39,52 @@ describe "Validations", ->
it "should join all the errors", ->
@subject.multiple ''
expect(@subject.errors.multiple()).toBe "xxx, xxx, xxx"
+
+
+
+ describe "conditional validations", ->
+
+ it "should not validate when ONLY returns false", ->
+ @subject.only = -> false
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeFalsy()
+
+ it "should validate when ONLY returns true", ->
+ @subject.only = -> true
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeTruthy()
+
+
+ it "should not validate when EXCEPT returns true", ->
+ @subject.except = -> true
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeFalsy()
+
+ it "should validate when EXCEPT returns false", ->
+ @subject.except = -> false
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeTruthy()
+
+ it "should validate when ONLY=true, EXCEPT=false", ->
+ @subject.only = -> true
+ @subject.except = -> false
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeTruthy()
+
+ it "should not validate when ONLY=true, EXCEPT=true", ->
+ @subject.only = -> true
+ @subject.except = -> true
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeFalsy()
+
+ it "should not validate when ONLY=false, EXCEPT=true", ->
+ @subject.only = -> false
+ @subject.except = -> true
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeFalsy()
+
+ it "should not validate when ONLY=false, EXCEPT=false", ->
+ @subject.only = -> false
+ @subject.except = -> false
+ @subject.conditional ' '
+ expect(@subject.errors.conditional()).toBeFalsy()

0 comments on commit 3412139

Please sign in to comment.