diff --git a/VDS/Components/TextFields/InputField/FieldTypes/CreditCard.swift b/VDS/Components/TextFields/InputField/FieldTypes/CreditCard.swift index 0b8c89b6..7137d895 100644 --- a/VDS/Components/TextFields/InputField/FieldTypes/CreditCard.swift +++ b/VDS/Components/TextFields/InputField/FieldTypes/CreditCard.swift @@ -10,7 +10,7 @@ import UIKit extension InputField { - public enum CreditCardType: CaseIterable { + public enum CreditCardType: String, CaseIterable { case generic case visa case mastercard @@ -45,6 +45,14 @@ extension InputField { } } + var securityCodeLength: Int { + if self == .amex { + return 4 + } else { + return 3 + } + } + var maxLength: Int { switch self { case .dinersClub: return 14 @@ -86,13 +94,13 @@ extension InputField { private override init() { super.init() + self.validateOnChange = false self.keyboardType = .numberPad } override func updateView(_ inputField: InputField) { minWidth = 288.0 leftImageName = inputField.cardType.imageName(surface: inputField.surface) - super.updateView(inputField) } diff --git a/VDS/Components/TextFields/InputField/FieldTypes/FieldType.swift b/VDS/Components/TextFields/InputField/FieldTypes/FieldType.swift index a52dcfae..039275b2 100644 --- a/VDS/Components/TextFields/InputField/FieldTypes/FieldType.swift +++ b/VDS/Components/TextFields/InputField/FieldTypes/FieldType.swift @@ -45,6 +45,7 @@ extension InputField { var isSecureTextEntry = false var placeholderText: String? var value: String? + var validateOnChange = false internal override init() { keyboardType = .default diff --git a/VDS/Components/TextFields/InputField/FieldTypes/SecurityCode.swift b/VDS/Components/TextFields/InputField/FieldTypes/SecurityCode.swift index f49800f4..fc219044 100644 --- a/VDS/Components/TextFields/InputField/FieldTypes/SecurityCode.swift +++ b/VDS/Components/TextFields/InputField/FieldTypes/SecurityCode.swift @@ -18,10 +18,25 @@ extension InputField { self.keyboardType = .numberPad } + override func appendRules(_ inputField: InputField) { + if let text = inputField.textField.text, text.count > 0 { + let rule = CharacterCountRule().copyWith { + $0.maxLength = inputField.cardType.securityCodeLength + $0.compareType = .equals + $0.errorMessage = "Enter a valid security code." + } + inputField.rules.append(.init(rule)) + } + } + override func updateView(_ inputField: InputField) { minWidth = 88.0 isSecureTextEntry = true + let title: String = inputField.cardType.rawValue + let content: String = "looking for \(inputField.cardType.securityCodeLength) digits" + toolTipModel = .init(title: title, content: content) + super.updateView(inputField) } @@ -29,7 +44,7 @@ extension InputField { // Allow only numbers and limit the length of text. let allowedCharacters = CharacterSet.decimalDigits let characterSet = CharacterSet(charactersIn: string) - return allowedCharacters.isSuperset(of: characterSet) && ((textField.text?.count ?? 0) + string.count - range.length) <= 4 + return allowedCharacters.isSuperset(of: characterSet) && ((textField.text?.count ?? 0) + string.count - range.length) <= inputField.cardType.securityCodeLength } } diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index e4985bee..a01cbc79 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -196,8 +196,12 @@ open class InputField: EntryFieldBase { textField .textPublisher .sink { [weak self] newText in + guard let self else { return } print("textPublisher newText: \(newText)") - self?.sendActions(for: .valueChanged) + if self.fieldType.handler().validateOnChange { + self.validate() + } + self.sendActions(for: .valueChanged) }.store(in: &subscribers) stackView.addArrangedSubview(successLabel)