diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index eb67c255..00e7404f 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -165,11 +165,12 @@ open class InputField: EntryFieldBase { controlStackView.addArrangedSubview(textField) textField.heightAnchor.constraint(equalToConstant: 20).isActive = true + textField.delegate = self textField .textPublisher .sink { [weak self] newText in print("textPublisher newText: \(newText)") - self?.text = newText + self?.process(text: newText) self?.validate() self?.sendActions(for: .valueChanged) }.store(in: &subscribers) @@ -280,6 +281,7 @@ open class InputField: EntryFieldBase { var toolTipModel: Tooltip.TooltipModel? = tooltipModel var isSecureTextEntry = false var rules = [AnyRule]() + var placeholderText: String? if self.isRequired { let rule = RequiredRule() @@ -326,6 +328,7 @@ open class InputField: EntryFieldBase { case .date: minWidth = 114.0 + placeholderText = dateFormat.placeholderText case .securityCode: minWidth = 88.0 @@ -364,6 +367,9 @@ open class InputField: EntryFieldBase { minWidthConstraint?.isActive = true } + //placeholder + textField.placeholder = placeholderText + //tooltip tooltipModel = toolTipModel } @@ -421,6 +427,47 @@ open class InputField: EntryFieldBase { open var hidePasswordButtonText: String = "Hide" { didSet { setNeedsUpdate() } } open var showPasswordButtonText: String = "Show" { didSet { setNeedsUpdate() } } + + //-------------------------------------------------- + // MARK: - Date + //-------------------------------------------------- + open var dateFormat: DateFormat = .mmddyy { didSet { setNeedsUpdate() } } + +} + +extension InputField: UITextFieldDelegate { + public func process(text changedText: String) { + var newText: String = changedText + switch fieldType { + case .date: + guard newText.count <= dateFormat.maxLength else { return } + let numericText = newText.compactMap { $0.isNumber ? $0 : nil } + var formattedText = "" + + for (index, char) in numericText.enumerated() { + if (index == 2 || (index == 4 && (dateFormat != .mmyy))) && index < dateFormat.maxLength { + formattedText += "/" + } + formattedText.append(char) + } + newText = formattedText + + default: break + } + } + + public func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { + switch fieldType { + case .date: + // 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) <= dateFormat.maxLength + + default: + return true + } + } } extension InputField.FieldType { @@ -442,3 +489,36 @@ extension InputField.FieldType { } } } + +extension InputField { + public enum DateFormat: String, CaseIterable { + case mmyy + case mmddyy + case mmddyyyy + + public var placeholderText: String { + switch self { + case .mmyy: "MM/YY" + case .mmddyy: "MM/DD/YY" + case .mmddyyyy: "MM/DD/YYYY" + } + } + + public var formatString: String { + switch self { + case .mmyy: "MM/yy" + case .mmddyy: "MM/dd/yy" + case .mmddyyyy: "MM/dd/yyyy" + } + } + + public var maxLength: Int { + switch self { + case .mmyy: 5 + case .mmddyy: 8 + case .mmddyyyy: 10 + } + } + + } +}