From a3f6d8eeada4d5b06a486f0b076378918301be80 Mon Sep 17 00:00:00 2001 From: Will Richman Date: Thu, 18 Jun 2015 10:58:34 -0700 Subject: [PATCH 1/5] Single textField validation --- .DS_Store | Bin 6148 -> 8196 bytes Validator/Validator.swift | 42 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/.DS_Store b/.DS_Store index 1713d9fe0a3e4a6c598f3625bf8c2a7be56ce9dc..7e5d1d55c602a9c22acf82ffecaa3aa6cab75911 100644 GIT binary patch delta 359 zcmZoMXmOBWU|?W$DortDU;r^WfEYvza8E20o2aMA$i6XPH}hr%jz7$c**Q2SHn1?V zZ{}eMW3Crw2xCZO$YIE2NCDC%4EYR240;R|49P%N3PUPG0g#{1kd>2e7@VA+TL3f@ z2v&vw2_kjo=DWD0l$InjFkD=*L>;UhNoPGiOLOy6@My)SvmgW6xgQu985o#ARs(4k xuoEC`0fx;9JnNXbB)EZmS5RVoid) -> Void { self.validateAllFields() From 3ca023d0b0d45d512923f8ffb6fb9a05fbea3e25 Mon Sep 17 00:00:00 2001 From: Will Richman Date: Thu, 18 Jun 2015 11:19:32 -0700 Subject: [PATCH 2/5] Added single field validation section to README --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index ba009ab..5956e8a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,35 @@ func validationFailed(errors:[UITextField:ValidationError]) { ``` +## Single Field Validation + +If you would like to have a separate validation for individual registered fields (to, for example, validate only the currently edited field), you can use the overloaded validate method: + +```swift +override func viewDidLoad() { + super.viewDidLoad() + validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()]) + validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")]) + fullNameTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) + emailTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) +} + +func enteredText(sender: UITextField) { + validator.validate(self, textField: sender) +} +``` + +This validation will not call your delegate's ```validationSuccessful()``` method. If you want a way to respond to successful validation on this single field, you must implement the optional ValidationDelegate method ```singleValidationSuccessful(field: UITextField)```. + +```swift +func singleValidationSuccessful(field: UITextField) { + validator.errors[field].errorLabel?.hidden = true + validator.errors[field].errorLabel?.text = "" + field.layer.borderColor = UIColor.greenColor().CGColor + field.layer.borderWidth = 0.5 +} +``` + ## Custom Validation We will create a ```SSNRule``` class to show how to create your own Validation. A United States Social Security Number (or SSN) is a field that consists of XXX-XX-XXXX. From 22acf080d3254edff8b968e2b6c717ad3c9e0825 Mon Sep 17 00:00:00 2001 From: Will Richman Date: Thu, 18 Jun 2015 11:32:38 -0700 Subject: [PATCH 3/5] README changes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5956e8a..a25cf82 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ func validationFailed(errors:[UITextField:ValidationError]) { ## Single Field Validation -If you would like to have a separate validation for individual registered fields (to, for example, validate only the currently edited field), you can use the overloaded validate method: +If you would like to have a separate validation for individual registered fields, you can use the overloaded validate method. This can be used, for example, to validate a field after every character is entered: ```swift override func viewDidLoad() { From 9fdc10d24bd3aff6e38423474d7641e360e9db23 Mon Sep 17 00:00:00 2001 From: Will Richman Date: Mon, 22 Jun 2015 09:46:35 -0700 Subject: [PATCH 4/5] Changed validate field to use callback instead of delegate method --- Validator/Validator.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Validator/Validator.swift b/Validator/Validator.swift index ba87641..5a49582 100644 --- a/Validator/Validator.swift +++ b/Validator/Validator.swift @@ -11,7 +11,6 @@ import UIKit @objc public protocol ValidationDelegate { func validationSuccessful() - optional func singleValidationSuccessful(field: UITextField) func validationFailed(errors: [UITextField:ValidationError]) } @@ -111,14 +110,14 @@ public class Validator { } } - public func validate(delegate:ValidationDelegate, textField: UITextField) { + public func validate(textField: UITextField, callback:(error:ValidationError?)->Void) { self.validateField(textField) if errors[textField] == nil { - delegate.singleValidationSuccessful?(textField) + callback(error: nil) } else { - delegate.validationFailed(errors) + callback(error: errors[textField]) } } From bc8d123f6cf3ef5562d57189e239186fc1de7f65 Mon Sep 17 00:00:00 2001 From: Will Richman Date: Mon, 22 Jun 2015 09:53:35 -0700 Subject: [PATCH 5/5] Updated README --- README.md | 88 ++++++++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index a25cf82..7f081bf 100644 --- a/README.md +++ b/README.md @@ -47,24 +47,24 @@ Register the fields that you want to validate ```swift override func viewDidLoad() { - super.viewDidLoad() - - // Validation Rules are evaluated from left to right. - validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()]) - - // You can pass in error labels with your rules - // You can pass in custom error messages to regex rules (such as ZipCodeRule and EmailRule) - validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")]) - - // You can validate against other fields using ConfirmRule - validator.registerField(emailConfirmTextField, errorLabel: emailConfirmErrorLabel, rules: [ConfirmationRule(confirmField: emailTextField)]) - - // You can now pass in regex and length parameters through overloaded contructors - validator.registerField(phoneNumberTextField, errorLabel: phoneNumberErrorLabel, rules: [RequiredRule(), MinLengthRule(length: 9)]) - validator.registerField(zipcodeTextField, errorLabel: zipcodeErrorLabel, rules: [RequiredRule(), ZipCodeRule(regex = "\\d{5}")]) - - // You can unregister a text field if you no longer want to validate it - validator.unregisterField(fullNameTextField) + super.viewDidLoad() + + // Validation Rules are evaluated from left to right. + validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()]) + + // You can pass in error labels with your rules + // You can pass in custom error messages to regex rules (such as ZipCodeRule and EmailRule) + validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")]) + + // You can validate against other fields using ConfirmRule + validator.registerField(emailConfirmTextField, errorLabel: emailConfirmErrorLabel, rules: [ConfirmationRule(confirmField: emailTextField)]) + + // You can now pass in regex and length parameters through overloaded contructors + validator.registerField(phoneNumberTextField, errorLabel: phoneNumberErrorLabel, rules: [RequiredRule(), MinLengthRule(length: 9)]) + validator.registerField(zipcodeTextField, errorLabel: zipcodeErrorLabel, rules: [RequiredRule(), ZipCodeRule(regex = "\\d{5}")]) + + // You can unregister a text field if you no longer want to validate it + validator.unregisterField(fullNameTextField) } ``` @@ -73,7 +73,7 @@ Validate Fields on button tap or however you would like to trigger it. ```swift @IBAction func signupTapped(sender: AnyObject) { - validator.validate(delegate:self) + validator.validate(delegate:self) } ``` @@ -83,17 +83,17 @@ Implement the Validation Delegate in your View controller // ValidationDelegate methods func validationSuccessful() { - // submit the form + // submit the form } func validationFailed(errors:[UITextField:ValidationError]) { - // turn the fields to red - for (field, error) in validator.errors { - field.layer.borderColor = UIColor.redColor().CGColor - field.layer.borderWidth = 1.0 - error.errorLabel?.text = error.errorMessage // works if you added labels - error.errorLabel?.hidden = false - } + // turn the fields to red + for (field, error) in validator.errors { + field.layer.borderColor = UIColor.redColor().CGColor + field.layer.borderWidth = 1.0 + error.errorLabel?.text = error.errorMessage // works if you added labels + error.errorLabel?.hidden = false + } } ``` @@ -104,26 +104,22 @@ If you would like to have a separate validation for individual registered fields ```swift override func viewDidLoad() { - super.viewDidLoad() - validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()]) - validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")]) - fullNameTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) - emailTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) + super.viewDidLoad() + validator.registerField(fullNameTextField, rules: [RequiredRule(), FullNameRule()]) + validator.registerField(emailTextField, errorLabel: emailErrorLabel, rules: [RequiredRule(), EmailRule(message: "Invalid email")]) + fullNameTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) + emailTextField.addTarget(self, action: "enteredText:", forControlEvents: UIControlEvents.EditingChanged) } func enteredText(sender: UITextField) { - validator.validate(self, textField: sender) -} -``` - -This validation will not call your delegate's ```validationSuccessful()``` method. If you want a way to respond to successful validation on this single field, you must implement the optional ValidationDelegate method ```singleValidationSuccessful(field: UITextField)```. - -```swift -func singleValidationSuccessful(field: UITextField) { - validator.errors[field].errorLabel?.hidden = true - validator.errors[field].errorLabel?.text = "" - field.layer.borderColor = UIColor.greenColor().CGColor - field.layer.borderWidth = 0.5 + validator.validate(sender, callback: { (error) -> Void in + if error != nil { + error!.errorLabel?.hidden = false + error!.errorLabel?.text = error!.errorMessage + error!.textField.layer.borderColor = UIColor.redColor().CGColor + error!.textField.layer.borderWidth = 1.0 + } + }) } ``` @@ -138,9 +134,9 @@ Create a class that inherits from RegexRule class SSNVRule: RegexRule { static let regex = "^\\d{3}-\\d{2}-\\d{4}$" - + convenience init(message : String = "Not a valid SSN"){ - self.init(regex: SSNVRule.regex, message : message) + self.init(regex: SSNVRule.regex, message : message) } } ```