     }
 
     override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        return 7
+        return self.items.count
     }
 
     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
-        if indexPath.row == 0 || indexPath.row == 3 {
+        let item = self.items[indexPath.row]
+        if item.type == .Header {
             let cell = tableView.dequeueReusableCellWithIdentifier(HeaderCell.Identifier, forIndexPath: indexPath) as! HeaderCell
-
-            switch indexPath.row {
-            case 0:
-                cell.textLabel?.text = "Cardholder".uppercaseString
-                break
-            case 3:
-                cell.textLabel?.text = "Billing info".uppercaseString
-                break
-            default: break
-            }
+            cell.textLabel?.text = item.title.uppercaseString
             return cell
         } else {
             let cell = tableView.dequeueReusableCellWithIdentifier(FormTextFieldCell.Identifier, forIndexPath: indexPath) as! FormTextFieldCell
             cell.textField.textFieldDelegate = self
-
-            switch indexPath.row {
-            case 1:
-                cell.textLabel?.text = "First name"
-                cell.textField.placeholder = "First name"
-                cell.textField.inputType = .Name
-
-                var validation = Validation()
-                validation.required = true
-                let inputValidator = InputValidator(validation: validation)
-                cell.textField.inputValidator = inputValidator
-
-                break
-            case 2:
-                cell.textLabel?.text = "Last name"
-                cell.textField.placeholder = "Last name"
-                cell.textField.inputType = .Name
-
-                var validation = Validation()
-                validation.required = true
-                let inputValidator = InputValidator(validation: validation)
-                cell.textField.inputValidator = inputValidator
-
-                break
-            case 4:
-                cell.textLabel?.text = "Number"
-                cell.textField.placeholder = "Card Number"
-                cell.textField.inputType = .Integer
-                cell.textField.formatter = CardNumberFormatter()
-
-                var validation = Validation()
-                validation.minimumLength = "1234 5678 1234 5678".characters.count
-                validation.maximumLength = "1234 5678 1234 5678".characters.count
-                validation.required = true
-                let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
-                characterSet.addCharactersInString(" ")
-                validation.characterSet = characterSet
-                let inputValidator = InputValidator(validation: validation)
-                cell.textField.inputValidator = inputValidator
-
-                break
-            case 5:
-                cell.textLabel?.text = "Expires"
-                cell.textField.placeholder = "MM/YYYY"
-                cell.textField.inputType = .Integer
-                cell.textField.formatter = CardExpirationDateFormatter()
-
-                var validation = Validation()
-                validation.required = true
-                let inputValidator = CardExpirationDateInputValidator(validation: validation)
-                cell.textField.inputValidator = inputValidator
-                break
-            case 6:
-                cell.textLabel?.text = "CVV"
-                cell.textField.placeholder = "Security Code"
-                cell.textField.inputType = .Integer
-
-                var validation = Validation()
-                validation.maximumLength = "CVC".characters.count
-                validation.minimumLength = "CVC".characters.count
-                validation.characterSet = NSCharacterSet.decimalDigitCharacterSet()
-                let inputValidator = InputValidator(validation: validation)
-                cell.textField.inputValidator = inputValidator
-                break
-            default: break
-            }
+            cell.textLabel?.text = item.title
+            cell.textField.placeholder = item.placeholder ?? item.title
+            cell.textField.inputType = item.inputType
+            cell.textField.inputValidator = item.inputValidator
+            cell.textField.formatter = item.formatter
             return cell
         }
     }
 
     override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
-        if indexPath.row == 0 || indexPath.row == 3 {
+        let item = self.items[indexPath.row]
+        if item.type == .Header {
             return 60
         } else {
             return 45

    }

    func validate() -> Bool {
        let rows = [1, 2, 4, 5, 6]
        var valid = true
        for row in rows {
            let cell = self.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: 0)) as! FormTextFieldCell
            let validField = cell.textField.validate()
            if validField == false {
                valid = validField

import Validation
import FormTextField

enum FieldType {
    case Header, Field
}

struct Field {
    let type: FieldType
    let title: String
    let placeholder: String?
    var inputType: FormTextFieldInputType = .Default
    var inputValidator: InputValidatable?
    var formatter: Formattable?

    init(type: FieldType, title: String, placeholder: String? = nil) {
        self.type = type
        self.title = title
        self.placeholder = placeholder
    }
}

class Controller: UITableViewController {
    lazy var items: [Field] = {
        var items = [Field]()

        items.append(Field(type: .Header, title: "Cardholder"))

        var requiredValidation = Validation()
        requiredValidation.required = true
        let requiredInputValidator = InputValidator(validation: requiredValidation)

        var firstNameField = Field(type: .Field, title: "First name")
        firstNameField.inputType = .Name
        firstNameField.inputValidator = requiredInputValidator
        items.append(firstNameField)

        var lastNameField = Field(type: .Field, title: "Last name")
        lastNameField.inputType = .Name
        lastNameField.inputValidator = requiredInputValidator
        items.append(lastNameField)

        items.append(Field(type: .Header, title: "Billing info"))

        var cardNumberField = Field(type: .Field, title: "Number", placeholder: "Card Number")
        cardNumberField.inputType = .Integer
        cardNumberField.formatter = CardNumberFormatter()

        var cardNumberValidation = Validation()
        cardNumberValidation.minimumLength = "1234 5678 1234 5678".characters.count
        cardNumberValidation.maximumLength = "1234 5678 1234 5678".characters.count
        cardNumberValidation.required = true
        let characterSet = NSMutableCharacterSet.decimalDigitCharacterSet()
        characterSet.addCharactersInString(" ")
        cardNumberValidation.characterSet = characterSet
        let cardNumberInputValidator = InputValidator(validation: cardNumberValidation)
        cardNumberField.inputValidator = cardNumberInputValidator
        items.append(cardNumberField)

        var expirationDateField = Field(type: .Field, title: "Expires", placeholder: "MM/YYYY")
        expirationDateField.formatter = CardExpirationDateFormatter()
        expirationDateField.inputType = .Integer
        var expirationDateValidation = Validation()
        expirationDateValidation.required = true
        let expirationDateInputValidator = CardExpirationDateInputValidator(validation: expirationDateValidation)
        expirationDateField.inputValidator = expirationDateInputValidator
        items.append(expirationDateField)

        var securityCodeField = Field(type: .Field, title: "CVV", placeholder: "Security Code")
        securityCodeField.inputType = .Integer
        var securityCodeValidation = Validation()
        securityCodeValidation.maximumLength = "CVC".characters.count
        securityCodeValidation.minimumLength = "CVC".characters.count
        securityCodeValidation.characterSet = NSCharacterSet.decimalDigitCharacterSet()
        let securityCodeInputValidator = InputValidator(validation: securityCodeValidation)
        securityCodeField.inputValidator = securityCodeInputValidator
        items.append(securityCodeField)

        return items
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1)
