Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single field validation #35

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified .DS_Store
Binary file not shown.
83 changes: 54 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
```

Expand All @@ -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)
}
```

Expand All @@ -83,19 +83,44 @@ 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
}
}

```

## Single Field Validation

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() {
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(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
}
})
}
```

## Custom Validation
Expand All @@ -109,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)
}
}
```
Expand Down
41 changes: 39 additions & 2 deletions Validator/Validator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import UIKit

@objc public protocol ValidationDelegate {
func validationSuccessful()
func validationSuccessful()
func validationFailed(errors: [UITextField:ValidationError])
}

Expand All @@ -28,6 +28,10 @@ public class Validator {
private func clearErrors() {
self.errors = [:]
}

private func clearFieldError(textField: UITextField) {
self.errors[textField] = nil
}

private func validateAllFields() {

Expand All @@ -52,6 +56,28 @@ public class Validator {
}
}
}

private func validateField(textField: UITextField) {

self.clearFieldError(textField)

if let currentRule: ValidationRule = validations[textField] {
if var error: ValidationError = currentRule.validateField() {
errors[textField] = error

// let the user transform the field if they want
if let transform = self.errorStyleTransform {
transform(validationError: error)
}
} else {
// No error
// let the user transform the field if they want
if let transform = self.successStyleTransform {
transform(validationRule: currentRule)
}
}
}
}

// MARK: Using Keys

Expand Down Expand Up @@ -83,7 +109,18 @@ public class Validator {
delegate.validationFailed(errors)
}
}


public func validate(textField: UITextField, callback:(error:ValidationError?)->Void) {

self.validateField(textField)

if errors[textField] == nil {
callback(error: nil)
} else {
callback(error: errors[textField])
}
}

public func validate(callback:(errors:[UITextField:ValidationError])->Void) -> Void {

self.validateAllFields()
Expand Down