diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift index 1e520cc2..a5fedef0 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButton.swift @@ -20,6 +20,12 @@ import UIKit } } + public override var isSelected: Bool { + didSet { + radioModel?.state = isSelected + } + } + public var enabledColor: UIColor = .mvmBlack public var disabledColor: UIColor = .mvmCoolGray3 public var delegateObject: MVMCoreUIDelegateObject? diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift index ee408bb4..ea1a4627 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonModel.swift @@ -55,7 +55,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public func formFieldValue() -> AnyHashable? { - return state + return fieldValue } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift index 8730a9c3..5196bb9c 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/RadioButtonSelectionHelper.swift @@ -17,15 +17,30 @@ import Foundation public var fieldKey: String? public var groupName: String = FormValidator.defaultGroupName private var selectedRadioButton: RadioButton? - private var fieldGroupName: String? + private var selectedRadioButtonModel: RadioButtonModel? public var baseValue: AnyHashable? - //-------------------------------------------------- - // MARK: - Initializer - //-------------------------------------------------- - - init(_ fieldKey: String?) { - self.fieldKey = fieldKey +//-------------------------------------------------- +// MARK: - Initializer +//-------------------------------------------------- + + public func set(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton) { + self.fieldKey = radioButtonModel.fieldKey + self.groupName = radioButtonModel.groupName + + if radioButtonModel.state { + if self.baseValue == nil, + let selected = radioButtonModel.baseValue as? Bool, selected { + self.baseValue = radioButtonModel.fieldValue + } + selectedRadioButtonModel = radioButtonModel + + // Below code is needed for cell resuse scenario. + radioButton.isSelected = true + selectedRadioButton = radioButton + } else { + radioButton.isSelected = false + } } //-------------------------------------------------- @@ -35,35 +50,33 @@ import Foundation public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, _ radioButton: RadioButton, delegateObject: MVMCoreUIDelegateObject?) { guard let groupName = radioButtonModel.fieldKey, - let formValidator = delegateObject?.formHolderDelegate?.formValidator - else { return } - - let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey) - radioButtonSelectionHelper.fieldGroupName = radioButtonModel.fieldKey - formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper - - if radioButtonModel.state { - radioButtonSelectionHelper.selectedRadioButton = radioButton + let formValidator = delegateObject?.formHolderDelegate?.formValidator else { + return } + + let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper() + radioButtonSelectionHelper.set(radioButtonModel, radioButton) + formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper FormValidator.setupValidation(for: radioButtonSelectionHelper, delegate: delegateObject?.formHolderDelegate) } - + public func selected(_ radioButton: RadioButton) { - - selectedRadioButton?.isSelected = false + // Checks because the view could be reused + if selectedRadioButton?.radioModel === selectedRadioButtonModel { + selectedRadioButton?.isSelected = false + } else { + selectedRadioButtonModel?.state = false + } + selectedRadioButton = radioButton selectedRadioButton?.isSelected = true + selectedRadioButtonModel = selectedRadioButton?.radioModel } } // MARK: - FormValidationFormFieldProtocol extension RadioButtonSelectionHelper { - - public func formFieldGroupName() -> String? { - return selectedRadioButton?.formFieldGroupName() ?? fieldGroupName - } - public func formFieldValue() -> AnyHashable? { - return selectedRadioButton?.formFieldValue() + return selectedRadioButtonModel?.fieldValue } } diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index 06c8cdf1..29690ae5 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -74,12 +74,13 @@ import MVMCore /// Validates all rule groups. Returns if valid public func validate() -> Bool { var valid = true - guard let formRules = formRules else { - return valid - } + guard let formRules = formRules else { return valid } + for group in formRules { - valid = valid && validateGroup(group) + let groupValid = validateGroup(group) + valid = valid && groupValid } + return valid } @@ -137,13 +138,16 @@ import MVMCore // TODO: Temporary hacks, rewrite architecture to support this. public extension FormValidator { + func getGroupName(forPageType pageType: String?) -> String? { + for actionItem in groupWatchers { if let buttonModel = actionItem as? ButtonModel, pageType == (buttonModel.action as? ActionOpenPageModel)?.pageType { return buttonModel.groupName } } + return nil } } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift index b40d0460..56a5a2cf 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift @@ -11,19 +11,35 @@ import Foundation open class FormGroupRule: Codable { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + var groupName: String var rules: [RulesProtocol] + //-------------------------------------------------- + // MARK: - Initializer + //-------------------------------------------------- + init(_ groupName: String, _ rules: [RulesProtocol]) { self.groupName = groupName self.rules = rules } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case groupName case rules } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) self.groupName = try typeContainer.decode(String.self, forKey: .groupName) diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift index 7535c6dd..1f50bcc7 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift @@ -9,11 +9,18 @@ import Foundation public class RuleAllValueChangedModel: RulesProtocol { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "allValueChanged" public var type: String = RuleAllValueChangedModel.identifier public var fields: [String] - + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + public func isValid(_ formField: FormFieldProtocol) -> Bool { return formField.baseValue != formField.formFieldValue() } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift index e6b338a4..05e7ad32 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift @@ -10,31 +10,41 @@ import Foundation public class RuleEqualsModel: RulesProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "equals" public var type: String = RuleEqualsModel.identifier public var fields: [String] + + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- public func isValid(_ formField: FormFieldProtocol) -> Bool { return false } public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { + var valid = true var compareValue: AnyHashable? + for formKey in fields { - guard let formField = fieldMolecules[formKey] else { - continue - } + guard let formField = fieldMolecules[formKey] else { continue } if compareValue == nil { compareValue = formField.formFieldValue() continue } - if compareValue != formField.formFieldValue(){ + + if compareValue != formField.formFieldValue() { valid = false break } } + return valid } } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift index db1c4859..68eea7e5 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift @@ -8,16 +8,27 @@ import Foundation + public class RuleRegexModel: RulesProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "regex" public var type: String = RuleRegexModel.identifier public var fields: [String] public var regex: String + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public func isValid(_ formField: FormFieldProtocol) -> Bool { + if let stringToValidate = formField.formFieldValue() as? String { return MVMCoreUIUtility.validate(stringToValidate, withRegularExpression: regex) } + return false } } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift index cfff35eb..b34a24df 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift @@ -10,21 +10,30 @@ import Foundation public class RuleRequiredModel: RulesProtocol { - + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "allRequired" public var type: String = RuleRequiredModel.identifier public var fields: [String] + //-------------------------------------------------- + // MARK: - Validation + //-------------------------------------------------- + public func isValid(_ formField: FormFieldProtocol) -> Bool { - guard let value = formField.formFieldValue() else { - return false - } + guard let value = formField.formFieldValue() else { return false } + var valid = true + if let valueString = value as? String { valid = valueString.count > 0 + } else if let valueBool = value as? Bool { valid = valueBool } + return valid } }