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 {
|
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 {
|
public enum DateFormat: String, CaseIterable {
|
||||||
case mmyy
|
case mmyy
|
||||||
case mmddyy
|
case mmddyy
|
||||||
@ -46,6 +58,102 @@ extension InputField {
|
|||||||
case .mmddyyyy: [2,4]
|
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 {
|
class DateHandler: FieldTypeHandler {
|
||||||
@ -58,16 +166,15 @@ extension InputField {
|
|||||||
|
|
||||||
override func updateView(_ inputField: InputField) {
|
override func updateView(_ inputField: InputField) {
|
||||||
minWidth = 114.0
|
minWidth = 114.0
|
||||||
placeholderText = inputField.dateFormat.placeholderText
|
//placeholderText = inputField.dateFormat.placeholderText
|
||||||
|
inputField.textField.formatText = inputField.dateFormat.placeholderText
|
||||||
super.updateView(inputField)
|
super.updateView(inputField)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func appendRules(_ inputField: InputField) {
|
override func appendRules(_ inputField: InputField) {
|
||||||
if let text = inputField.textField.text, text.count > 0 {
|
if let text = inputField.textField.text, text.count > 0 {
|
||||||
let rule = CharacterCountRule().copyWith {
|
let rule = DateRule().copyWith {
|
||||||
$0.maxLength = inputField.dateFormat.maxLength
|
$0.dateFormat = inputField.dateFormat
|
||||||
$0.compareType = .equals
|
|
||||||
$0.errorMessage = "Enter a valid date."
|
$0.errorMessage = "Enter a valid date."
|
||||||
}
|
}
|
||||||
inputField.rules.append(.init(rule))
|
inputField.rules.append(.init(rule))
|
||||||
@ -88,7 +195,11 @@ extension InputField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if newText.count <= inputField.dateFormat.maxLength {
|
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
|
return false
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@ -190,9 +190,11 @@ open class InputField: EntryFieldBase {
|
|||||||
successLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable()
|
successLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable()
|
||||||
|
|
||||||
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: .success)
|
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: .success)
|
||||||
|
backgroundColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forState: [.success, .focused])
|
||||||
|
|
||||||
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
|
borderColorConfiguration.setSurfaceColors(VDSColor.feedbackSuccessOnlight, VDSColor.feedbackSuccessOndark, forState: .success)
|
||||||
|
|
||||||
|
textField.textColorConfiguration = textFieldTextColorConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func getFieldContainer() -> UIView {
|
open override func getFieldContainer() -> UIView {
|
||||||
@ -221,9 +223,9 @@ open class InputField: EntryFieldBase {
|
|||||||
|
|
||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
|
textField.surface = surface
|
||||||
textField.isEnabled = isEnabled
|
textField.isEnabled = isEnabled
|
||||||
textField.isUserInteractionEnabled = isEnabled && !isReadOnly
|
textField.isUserInteractionEnabled = isEnabled && !isReadOnly
|
||||||
textField.textColor = textFieldTextColorConfiguration.getColor(self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func updateAccessibility() {
|
open override func updateAccessibility() {
|
||||||
@ -248,7 +250,7 @@ open class InputField: EntryFieldBase {
|
|||||||
statusIcon.name = .checkmarkAlt
|
statusIcon.name = .checkmarkAlt
|
||||||
statusIcon.color = iconColorConfiguration.getColor(self)
|
statusIcon.color = iconColorConfiguration.getColor(self)
|
||||||
statusIcon.surface = surface
|
statusIcon.surface = surface
|
||||||
statusIcon.isHidden = !isEnabled
|
statusIcon.isHidden = !isEnabled || state.contains(.focused)
|
||||||
} else {
|
} else {
|
||||||
successLabel.isHidden = true
|
successLabel.isHidden = true
|
||||||
}
|
}
|
||||||
@ -303,6 +305,7 @@ extension InputField: UITextFieldDelegate {
|
|||||||
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||||
fieldType.handler().textFieldDidBeginEditing(self, textField: textField)
|
fieldType.handler().textFieldDidBeginEditing(self, textField: textField)
|
||||||
updateContainerView()
|
updateContainerView()
|
||||||
|
updateErrorLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func textFieldDidEndEditing(_ textField: UITextField) {
|
public func textFieldDidEndEditing(_ textField: UITextField) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user