fixed credit card issues with formatting for different card types also added an min/max length based on card type.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
f5380532ff
commit
2e46759857
@ -9,7 +9,20 @@ import Foundation
|
||||
import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
class CreditCardNumberRule: Rule, Withable {
|
||||
var cardType: CreditCardType?
|
||||
var errorMessage: String = "You have exceeded the character limit."
|
||||
|
||||
func isValid(value: String?) -> Bool {
|
||||
guard let count = value?.count, let min = cardType?.minLength, let max = cardType?.maxLength else { return true }
|
||||
if min == max {
|
||||
return count == max
|
||||
} else {
|
||||
return count >= min && count <= max
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum CreditCardType: String, CaseIterable {
|
||||
case generic
|
||||
case visa
|
||||
@ -38,15 +51,22 @@ extension InputField {
|
||||
}
|
||||
}
|
||||
|
||||
var separatorIndices: [Int] {
|
||||
func separatorIndices(_ length: Int) -> [Int] {
|
||||
var indices: [Int] = [4, 8, 12]
|
||||
switch self {
|
||||
case .dinersClub:
|
||||
return [4, 10]
|
||||
case .amex, .dinersClub:
|
||||
indices = [4, 10]
|
||||
case .unionPay:
|
||||
if length == 19 {
|
||||
indices = [5]
|
||||
}
|
||||
default:
|
||||
return [4, 8, 12]
|
||||
break
|
||||
}
|
||||
|
||||
return indices
|
||||
}
|
||||
|
||||
|
||||
var securityCodeLength: Int {
|
||||
if self == .amex {
|
||||
return 4
|
||||
@ -55,9 +75,21 @@ extension InputField {
|
||||
}
|
||||
}
|
||||
|
||||
var minLength: Int {
|
||||
switch self {
|
||||
case .visa: return 13
|
||||
case .amex: return 15
|
||||
case .dinersClub: return 14
|
||||
default: return 16
|
||||
}
|
||||
}
|
||||
|
||||
var maxLength: Int {
|
||||
switch self {
|
||||
case .visa: return 19
|
||||
case .amex: return 15
|
||||
case .dinersClub: return 14
|
||||
case .unionPay: return 19
|
||||
default: return 16
|
||||
}
|
||||
}
|
||||
@ -131,9 +163,8 @@ extension InputField {
|
||||
|
||||
override func appendRules(_ inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.cardType.maxLength
|
||||
$0.compareType = .equals
|
||||
let rule = CreditCardNumberRule().copyWith {
|
||||
$0.cardType = inputField.cardType
|
||||
$0.errorMessage = "Enter a valid credit card."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
@ -205,8 +236,8 @@ extension InputField {
|
||||
|
||||
/// Private
|
||||
internal func formatCreditCardNumber(_ cardType: CreditCardType, number: String) -> String {
|
||||
let formattedInput = number.filter { $0.isNumber } // Remove any existing slashes
|
||||
return String.format(formattedInput, indices: cardType.separatorIndices, with: " ")
|
||||
let rawNumber = number.filter { $0.isNumber } // Remove any existing slashes
|
||||
return String.format(rawNumber, indices: cardType.separatorIndices(rawNumber.count), with: " ")
|
||||
}
|
||||
|
||||
internal func updateCardTypeIcon(_ inputField: InputField, rawNumber: String) {
|
||||
@ -224,9 +255,8 @@ extension InputField {
|
||||
guard rawNumber.count == cardType.maxLength else { return formatCreditCardNumber(cardType, number: number) }
|
||||
let lastFourDigits = rawNumber.suffix(4)
|
||||
let maskedSection = String(repeating: "•", count: 12)
|
||||
let formattedMaskSection = String.format(maskedSection, indices: cardType.separatorIndices, with: " ")
|
||||
let formattedMaskSection = String.format(maskedSection, indices: cardType.separatorIndices(rawNumber.count), with: " ")
|
||||
return formattedMaskSection + " " + lastFourDigits
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user