CXTDT-565105 - InputField - Date - Typeover text not working.
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
8a686314f5
commit
f7ded23857
@ -10,6 +10,18 @@ import UIKit
|
||||
|
||||
extension InputField {
|
||||
|
||||
public class DateRule: Rule, Withable {
|
||||
public var dateFormat: DateFormat?
|
||||
public var errorMessage: String = "Enter a valid date"
|
||||
private let dateFormatter = DateFormatter()
|
||||
|
||||
public func isValid(value: String?) -> Bool {
|
||||
guard let value, let dateFormat, !value.isEmpty else { return true }
|
||||
dateFormatter.dateFormat = dateFormat.formatString
|
||||
return dateFormatter.date(from: value) != nil
|
||||
}
|
||||
}
|
||||
|
||||
public enum DateFormat: String, CaseIterable {
|
||||
case mmyy
|
||||
case mmddyy
|
||||
@ -46,6 +58,102 @@ extension InputField {
|
||||
case .mmddyyyy: [2,4]
|
||||
}
|
||||
}
|
||||
|
||||
public func isValid(_ date: String) -> Bool {
|
||||
let allowedCharacters = CharacterSet(charactersIn: "0123456789/")
|
||||
|
||||
// Check if the input contains only allowed characters
|
||||
if date.rangeOfCharacter(from: allowedCharacters.inverted) != nil || date.isEmpty {
|
||||
return false
|
||||
}
|
||||
|
||||
let components = date.split(separator: "/")
|
||||
|
||||
|
||||
func isMonth(_ month: String) -> Bool {
|
||||
switch month.count {
|
||||
case 1:
|
||||
guard let month = Int(month), (0...1).contains(month) else { return false }
|
||||
return true
|
||||
case 2:
|
||||
guard let month = Int(month), (1...12).contains(month) else { return false }
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isDay(_ day: String) -> Bool {
|
||||
switch day.count {
|
||||
case 1:
|
||||
guard let day = Int(day),(1...3).contains(day) else { return false }
|
||||
return true
|
||||
case 2:
|
||||
guard let day = Int(day), (1...31).contains(day) else { return false }
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isYear(_ year: String, max: Int) -> Bool {
|
||||
guard year.count <= max else {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
switch self {
|
||||
case .mmyy:
|
||||
if components.count > 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate month part
|
||||
if components.count > 0, let monthPart = components.first {
|
||||
if !isMonth(String(monthPart)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Validate year part
|
||||
if components.count > 1, let yearPart = components.last {
|
||||
if !isYear(String(yearPart), max: 2) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
case .mmddyy, .mmddyyyy:
|
||||
if components.count > 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Validate month part
|
||||
if components.count > 0, let monthPart = components.first {
|
||||
if !isMonth(String(monthPart)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Validate day part
|
||||
if components.count > 1 {
|
||||
let dayPart = components[1]
|
||||
if !isDay(String(dayPart)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Validate year part
|
||||
if components.count > 2, let yearPart = components.last {
|
||||
if !isYear(String(yearPart), max: self == .mmddyy ? 2 : 4) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DateHandler: FieldTypeHandler {
|
||||
@ -58,16 +166,15 @@ extension InputField {
|
||||
|
||||
override func updateView(_ inputField: InputField) {
|
||||
minWidth = 114.0
|
||||
placeholderText = inputField.dateFormat.placeholderText
|
||||
|
||||
//placeholderText = inputField.dateFormat.placeholderText
|
||||
inputField.textField.formatText = inputField.dateFormat.placeholderText
|
||||
super.updateView(inputField)
|
||||
}
|
||||
|
||||
override func appendRules(_ inputField: InputField) {
|
||||
if let text = inputField.textField.text, text.count > 0 {
|
||||
let rule = CharacterCountRule().copyWith {
|
||||
$0.maxLength = inputField.dateFormat.maxLength
|
||||
$0.compareType = .equals
|
||||
let rule = DateRule().copyWith {
|
||||
$0.dateFormat = inputField.dateFormat
|
||||
$0.errorMessage = "Enter a valid date."
|
||||
}
|
||||
inputField.rules.append(.init(rule))
|
||||
@ -86,9 +193,13 @@ extension InputField {
|
||||
if newText.count > inputField.dateFormat.maxLength {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
if newText.count <= inputField.dateFormat.maxLength {
|
||||
textField.text = String.format(newText, indices: inputField.dateFormat.separatorIndices, with: "/")
|
||||
let rawNumber = newText.filter { $0.isNumber }
|
||||
let formatted = String.format(rawNumber, indices: inputField.dateFormat.separatorIndices, with: "/")
|
||||
if inputField.dateFormat.isValid(formatted) || formatted.isEmpty {
|
||||
textField.text = formatted
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
||||
@ -190,9 +190,11 @@ open class InputField: EntryFieldBase {
|
||||
successLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable()
|
||||
|
||||
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: .success)
|
||||
|
||||
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
|
||||
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: [.success, .focused])
|
||||
|
||||
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
|
||||
|
||||
textField.textColorConfiguration = textFieldTextColorConfiguration
|
||||
}
|
||||
|
||||
open override func getFieldContainer() -> UIView {
|
||||
@ -221,9 +223,9 @@ open class InputField: EntryFieldBase {
|
||||
|
||||
super.updateView()
|
||||
|
||||
textField.surface = surface
|
||||
textField.isEnabled = isEnabled
|
||||
textField.isUserInteractionEnabled = isEnabled && !isReadOnly
|
||||
textField.textColor = textFieldTextColorConfiguration.getColor(self)
|
||||
}
|
||||
|
||||
open override func updateAccessibility() {
|
||||
@ -248,7 +250,7 @@ open class InputField: EntryFieldBase {
|
||||
statusIcon.name = .checkmarkAlt
|
||||
statusIcon.color = iconColorConfiguration.getColor(self)
|
||||
statusIcon.surface = surface
|
||||
statusIcon.isHidden = !isEnabled
|
||||
statusIcon.isHidden = !isEnabled || state.contains(.focused)
|
||||
} else {
|
||||
successLabel.isHidden = true
|
||||
}
|
||||
@ -303,6 +305,7 @@ extension InputField: UITextFieldDelegate {
|
||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
fieldType.handler().textFieldDidBeginEditing(self, textField: textField)
|
||||
updateContainerView()
|
||||
updateErrorLabel()
|
||||
}
|
||||
|
||||
public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user