Merge branch 'feature/optional-readonly' into 'develop'
update to Forms See merge request BPHV_MIPS/mvm_core_ui!791
This commit is contained in:
commit
e990504ce3
@ -570,6 +570,8 @@
|
|||||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; };
|
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretLink.swift */; };
|
||||||
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
||||||
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
|
EA41F4AC2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */; };
|
||||||
|
EA05EFA9278DDE2C00828819 /* ClearFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */; };
|
||||||
|
EA05EFAB278DE53600828819 /* ClearableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */; };
|
||||||
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
|
EA5124FD243601600051A3A4 /* BGImageHeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */; };
|
||||||
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
|
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
|
||||||
EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; };
|
EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; };
|
||||||
@ -577,8 +579,8 @@
|
|||||||
EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; };
|
EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; };
|
||||||
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; };
|
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; };
|
||||||
EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; };
|
EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; };
|
||||||
EABFC1412763BB8D00E78B40 /* StateLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC1402763BB8D00E78B40 /* StateLabel.swift */; };
|
EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC1402763BB8D00E78B40 /* FormLabel.swift */; };
|
||||||
EABFC152276913E800E78B40 /* StateLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC151276913E800E78B40 /* StateLabelModel.swift */; };
|
EABFC152276913E800E78B40 /* FormLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC151276913E800E78B40 /* FormLabelModel.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -1148,6 +1150,8 @@
|
|||||||
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
||||||
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
DBC4391A224421A0001AB423 /* CaretLink.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretLink.swift; sourceTree = "<group>"; };
|
||||||
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicRuleFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
|
EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
|
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearableModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
|
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButton.swift; sourceTree = "<group>"; };
|
||||||
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
|
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = "<group>"; };
|
||||||
EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
@ -1155,8 +1159,8 @@
|
|||||||
EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = "<group>"; };
|
EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = "<group>"; };
|
||||||
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||||
EABFC1402763BB8D00E78B40 /* StateLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateLabel.swift; sourceTree = "<group>"; };
|
EABFC1402763BB8D00E78B40 /* FormLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormLabel.swift; sourceTree = "<group>"; };
|
||||||
EABFC151276913E800E78B40 /* StateLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateLabelModel.swift; sourceTree = "<group>"; };
|
EABFC151276913E800E78B40 /* FormLabelModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormLabelModel.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -1181,6 +1185,7 @@
|
|||||||
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
|
D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */,
|
||||||
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
|
012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */,
|
||||||
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
|
012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */,
|
||||||
|
EA05EFAA278DE53600828819 /* ClearableModelProtocol.swift */,
|
||||||
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
|
01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */,
|
||||||
012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */,
|
012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */,
|
||||||
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
D28A837823C7D5BC00DFE4FC /* PageModelProtocol.swift */,
|
||||||
@ -1446,8 +1451,8 @@
|
|||||||
94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */,
|
94C2D9A823872E5E0006CF46 /* LabelAttributeImageModel.swift */,
|
||||||
94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */,
|
94C2D9AA23872EB50006CF46 /* LabelAttributeActionModel.swift */,
|
||||||
DB891E822253FA8500022516 /* Label.swift */,
|
DB891E822253FA8500022516 /* Label.swift */,
|
||||||
EABFC151276913E800E78B40 /* StateLabelModel.swift */,
|
EABFC151276913E800E78B40 /* FormLabelModel.swift */,
|
||||||
EABFC1402763BB8D00E78B40 /* StateLabel.swift */,
|
EABFC1402763BB8D00E78B40 /* FormLabel.swift */,
|
||||||
);
|
);
|
||||||
path = Label;
|
path = Label;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2428,6 +2433,7 @@
|
|||||||
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */,
|
EA41F4AB2787927100F5B377 /* DynamicRuleFormFieldEffectModel.swift */,
|
||||||
EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */,
|
EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */,
|
||||||
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */,
|
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */,
|
||||||
|
EA05EFA8278DDE2C00828819 /* ClearFormFieldEffectModel.swift */,
|
||||||
);
|
);
|
||||||
path = FormFieldEffect;
|
path = FormFieldEffect;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -2570,7 +2576,7 @@
|
|||||||
324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */,
|
324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */,
|
||||||
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
|
||||||
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */,
|
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */,
|
||||||
EABFC152276913E800E78B40 /* StateLabelModel.swift in Sources */,
|
EABFC152276913E800E78B40 /* FormLabelModel.swift in Sources */,
|
||||||
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
|
||||||
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */,
|
0AF60F0926B3316E00AC3DB4 /* MVMCoreUIUtility+Extension.swift in Sources */,
|
||||||
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
|
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
|
||||||
@ -2851,6 +2857,7 @@
|
|||||||
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
|
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
|
||||||
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */,
|
011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */,
|
||||||
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */,
|
D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */,
|
||||||
|
EA05EFAB278DE53600828819 /* ClearableModelProtocol.swift in Sources */,
|
||||||
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */,
|
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */,
|
||||||
BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */,
|
BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */,
|
||||||
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */,
|
94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */,
|
||||||
@ -2995,7 +3002,7 @@
|
|||||||
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */,
|
013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */,
|
||||||
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */,
|
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */,
|
||||||
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */,
|
525239C22407BD1000454969 /* ListTwoColumnPriceDetails.swift in Sources */,
|
||||||
EABFC1412763BB8D00E78B40 /* StateLabel.swift in Sources */,
|
EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */,
|
||||||
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
|
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
|
||||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
||||||
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */,
|
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */,
|
||||||
@ -3017,6 +3024,7 @@
|
|||||||
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */,
|
52267A0723FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift in Sources */,
|
||||||
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */,
|
D2ED2812254B0EB800A1C293 /* MVMCoreTopAlertObject.m in Sources */,
|
||||||
0AA4D2E125CAEC72008DB32D /* AccessibilityModelProtocol.swift in Sources */,
|
0AA4D2E125CAEC72008DB32D /* AccessibilityModelProtocol.swift in Sources */,
|
||||||
|
EA05EFA9278DDE2C00828819 /* ClearFormFieldEffectModel.swift in Sources */,
|
||||||
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
C003506123AA94CD00B6AC29 /* Button.swift in Sources */,
|
||||||
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
DBC4391B224421A0001AB423 /* CaretLink.swift in Sources */,
|
||||||
D29C559025C095210082E7D6 /* Video.swift in Sources */,
|
D29C559025C095210082E7D6 /* Video.swift in Sources */,
|
||||||
|
|||||||
@ -17,8 +17,8 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Outlets
|
// MARK: - Outlets
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public private(set) var titleLabel: StateLabel = {
|
public private(set) var titleLabel: FormLabel = {
|
||||||
let label = StateLabel()
|
let label = FormLabel()
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
@ -26,12 +26,33 @@ import UIKit
|
|||||||
public private(set) var entryFieldContainer = EntryFieldContainer()
|
public private(set) var entryFieldContainer = EntryFieldContainer()
|
||||||
|
|
||||||
/// Provides contextual information on the TextField.
|
/// Provides contextual information on the TextField.
|
||||||
public private(set) var feedbackLabel: StateLabel = {
|
public private(set) var feedbackLabel: FormLabel = {
|
||||||
let label = StateLabel()
|
let label = FormLabel()
|
||||||
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
public private(set) var errorLabel: Label = {
|
||||||
|
let label = Label()
|
||||||
|
label.setFontStyle(.RegularMicro)
|
||||||
|
label.textColor = .mvmBlack
|
||||||
|
label.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
public lazy var stack: UIStackView = {
|
||||||
|
errorLabel.isHidden = true
|
||||||
|
let stack = UIStackView(arrangedSubviews: [titleLabel, entryFieldContainer, errorLabel, feedbackLabel])
|
||||||
|
stack.axis = .vertical
|
||||||
|
stack.alignment = .fill
|
||||||
|
stack.distribution = .fill
|
||||||
|
stack.setCustomSpacing(Padding.One, after: titleLabel)
|
||||||
|
stack.setCustomSpacing(Padding.Two, after: entryFieldContainer)
|
||||||
|
stack.setCustomSpacing(Padding.One, after: errorLabel)
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return stack
|
||||||
|
}()
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Delegate
|
// MARK: - Delegate
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -59,21 +80,26 @@ import UIKit
|
|||||||
feedbackLabel.isEnabled = enabled
|
feedbackLabel.isEnabled = enabled
|
||||||
entryFieldContainer.isEnabled = enabled
|
entryFieldContainer.isEnabled = enabled
|
||||||
entryFieldModel?.enabled = enabled
|
entryFieldModel?.enabled = enabled
|
||||||
if !enabled {
|
|
||||||
self.text = defaultText
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Toggles enabled (original) or disabled UI.
|
||||||
|
public var isRequired: Bool = true {
|
||||||
|
didSet{
|
||||||
|
titleLabel.isRequired = isRequired
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Toggles error or original UI.
|
/// Toggles error or original UI.
|
||||||
public var showError: Bool {
|
public var showError: Bool {
|
||||||
get { entryFieldContainer.showError }
|
get { entryFieldContainer.showError }
|
||||||
set (error) {
|
set (error) {
|
||||||
if error {
|
if error {
|
||||||
feedbackLabel.showError(message: self.errorMessage ?? "")
|
errorLabel.text = self.errorMessage ?? ""
|
||||||
|
errorLabel.isHidden = false
|
||||||
} else {
|
} else {
|
||||||
feedbackLabel.reset()
|
errorLabel.isHidden = true
|
||||||
}
|
}
|
||||||
entryFieldContainer.showError = error
|
entryFieldContainer.showError = error
|
||||||
entryFieldModel?.showError = error
|
entryFieldModel?.showError = error
|
||||||
@ -130,25 +156,6 @@ import UIKit
|
|||||||
model as? EntryFieldModel
|
model as? EntryFieldModel
|
||||||
}
|
}
|
||||||
|
|
||||||
///This is the value of the entryFieldModel.text on set
|
|
||||||
///This is used to update the text value on a reset or when enabled is set to false
|
|
||||||
private var defaultText: String = ""
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Constraints
|
|
||||||
//--------------------------------------------------
|
|
||||||
|
|
||||||
public var entryFieldContainerLeading: NSLayoutConstraint?
|
|
||||||
public var entryFieldContainerTrailing: NSLayoutConstraint?
|
|
||||||
|
|
||||||
public var feedbackLabelTrailing: NSLayoutConstraint?
|
|
||||||
public var feedbackLabelLeading: NSLayoutConstraint?
|
|
||||||
|
|
||||||
public var titleLabelLeading: NSLayoutConstraint?
|
|
||||||
public var titleLabelTrailing: NSLayoutConstraint?
|
|
||||||
|
|
||||||
public var titleContainerDistance: NSLayoutConstraint?
|
|
||||||
public var feedbackContainerDistance: NSLayoutConstraint?
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -188,37 +195,18 @@ import UIKit
|
|||||||
|
|
||||||
isAccessibilityElement = false
|
isAccessibilityElement = false
|
||||||
setContentCompressionResistancePriority(.required, for: .vertical)
|
setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
accessibilityElements = [titleLabel, feedbackLabel]
|
accessibilityElements = [titleLabel, errorLabel, feedbackLabel]
|
||||||
backgroundColor = .mvmWhite
|
backgroundColor = .mvmWhite
|
||||||
|
|
||||||
addSubview(titleLabel)
|
addSubview(stack)
|
||||||
|
|
||||||
titleLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
|
|
||||||
titleLabelLeading = titleLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
|
||||||
titleLabelLeading?.isActive = true
|
|
||||||
titleLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor)
|
|
||||||
titleLabelLeading?.isActive = true
|
|
||||||
|
|
||||||
addSubview(entryFieldContainer)
|
|
||||||
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
entryFieldContainer.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
setupFieldContainerContent(entryFieldContainer)
|
setupFieldContainerContent(entryFieldContainer)
|
||||||
|
|
||||||
titleContainerDistance = entryFieldContainer.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: Padding.One)
|
stack.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
|
||||||
titleContainerDistance?.isActive = true
|
stack.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
||||||
entryFieldContainerLeading = entryFieldContainer.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
layoutMarginsGuide.trailingAnchor.constraint(equalTo: stack.trailingAnchor).isActive = true
|
||||||
entryFieldContainerLeading?.isActive = true
|
layoutMarginsGuide.bottomAnchor.constraint(equalTo: stack.bottomAnchor).isActive = true
|
||||||
entryFieldContainerTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: entryFieldContainer.trailingAnchor)
|
|
||||||
entryFieldContainerTrailing?.isActive = true
|
|
||||||
|
|
||||||
addSubview(feedbackLabel)
|
|
||||||
|
|
||||||
feedbackContainerDistance = feedbackLabel.topAnchor.constraint(equalTo: entryFieldContainer.bottomAnchor, constant: Padding.Two)
|
|
||||||
feedbackContainerDistance?.isActive = true
|
|
||||||
feedbackLabelLeading = feedbackLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor)
|
|
||||||
feedbackLabelLeading?.isActive = true
|
|
||||||
feedbackLabelTrailing = layoutMarginsGuide.trailingAnchor.constraint(equalTo: feedbackLabel.trailingAnchor)
|
|
||||||
feedbackLabelTrailing?.isActive = true
|
|
||||||
layoutMarginsGuide.bottomAnchor.constraint(equalTo: feedbackLabel.bottomAnchor).isActive = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc open override func layoutSubviews() {
|
@objc open override func layoutSubviews() {
|
||||||
@ -234,10 +222,7 @@ import UIKit
|
|||||||
|
|
||||||
@objc open override func updateView(_ size: CGFloat) {
|
@objc open override func updateView(_ size: CGFloat) {
|
||||||
super.updateView(size)
|
super.updateView(size)
|
||||||
|
stack.updateView(size)
|
||||||
titleLabel.updateView(size)
|
|
||||||
feedbackLabel.updateView(size)
|
|
||||||
entryFieldContainer.updateView(size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -295,6 +280,9 @@ import UIKit
|
|||||||
titleLabel.textColor = .mvmBlack
|
titleLabel.textColor = .mvmBlack
|
||||||
feedbackLabel.font = Styler.Font.RegularMicro.getFont()
|
feedbackLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
feedbackLabel.textColor = .mvmBlack
|
feedbackLabel.textColor = .mvmBlack
|
||||||
|
errorLabel.font = Styler.Font.RegularMicro.getFont()
|
||||||
|
errorLabel.textColor = .mvmBlack
|
||||||
|
errorLabel.text = nil
|
||||||
entryFieldContainer.disableAllBorders = false
|
entryFieldContainer.disableAllBorders = false
|
||||||
feedbackLabel.text = nil
|
feedbackLabel.text = nil
|
||||||
entryFieldContainer.reset()
|
entryFieldContainer.reset()
|
||||||
@ -313,8 +301,8 @@ import UIKit
|
|||||||
titleLabel.setup(model: model.titleStateLabel, delegateObject, additionalData)
|
titleLabel.setup(model: model.titleStateLabel, delegateObject, additionalData)
|
||||||
feedbackLabel.setup(model: model.feedbackStateLabel, delegateObject, additionalData)
|
feedbackLabel.setup(model: model.feedbackStateLabel, delegateObject, additionalData)
|
||||||
|
|
||||||
defaultText = model.text ?? ""
|
isEnabled = model.enabled && !model.readOnly
|
||||||
isEnabled = model.enabled
|
isRequired = model.required
|
||||||
model.updateUI = { [weak self] in
|
model.updateUI = { [weak self] in
|
||||||
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
MVMCoreDispatchUtility.performBlock(onMainThread: {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
@ -326,6 +314,7 @@ import UIKit
|
|||||||
self.showError = false
|
self.showError = false
|
||||||
}
|
}
|
||||||
self.isEnabled = model.enabled
|
self.isEnabled = model.enabled
|
||||||
|
self.text = model.text
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,8 +365,8 @@ extension EntryField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension LabelModel {
|
extension LabelModel {
|
||||||
public convenience init(fontStyle: Styler.Font, textColor: Color) {
|
public convenience init(text: String = "", fontStyle: Styler.Font, textColor: Color) {
|
||||||
self.init(text: "")
|
self.init(text: text)
|
||||||
self.fontStyle = fontStyle
|
self.fontStyle = fontStyle
|
||||||
self.textColor = textColor
|
self.textColor = textColor
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol {
|
@objcMembers open class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, FormRuleWatcherFieldProtocol, UIUpdatableModelProtocol, ClearableModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -29,6 +29,8 @@ import Foundation
|
|||||||
public var errorMessage: String?
|
public var errorMessage: String?
|
||||||
public var errorTextColor: Color?
|
public var errorTextColor: Color?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var required: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var showError: Bool?
|
public var showError: Bool?
|
||||||
public var hideBorders = false
|
public var hideBorders = false
|
||||||
public var locked: Bool?
|
public var locked: Bool?
|
||||||
@ -38,20 +40,12 @@ import Foundation
|
|||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
public var wasInitiallySelected: Bool = false
|
public var wasInitiallySelected: Bool = false
|
||||||
|
public var title: String?
|
||||||
//text only
|
public var feedback: String?
|
||||||
//Used for re-encoding what was decoded
|
|
||||||
private var title: String?
|
|
||||||
private var feedback: String?
|
|
||||||
|
|
||||||
//label models
|
|
||||||
//Used for re-encoding what was decoded
|
|
||||||
private var titleLabel: LabelModel?
|
|
||||||
private var feedbackLabel: LabelModel?
|
|
||||||
|
|
||||||
//used to drive the EntryFieldView UI
|
//used to drive the EntryFieldView UI
|
||||||
public var titleStateLabel: StateLabelModel
|
public var titleStateLabel: FormLabelModel
|
||||||
public var feedbackStateLabel: StateLabelModel
|
public var feedbackStateLabel: FormLabelModel
|
||||||
|
|
||||||
public var isValid: Bool? = true {
|
public var isValid: Bool? = true {
|
||||||
didSet { updateUI?() }
|
didSet { updateUI?() }
|
||||||
@ -73,6 +67,7 @@ import Foundation
|
|||||||
case accessibilityIdentifier
|
case accessibilityIdentifier
|
||||||
case title
|
case title
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
case feedback
|
case feedback
|
||||||
case errorMessage
|
case errorMessage
|
||||||
case errorTextColor
|
case errorTextColor
|
||||||
@ -83,8 +78,7 @@ import Foundation
|
|||||||
case text
|
case text
|
||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
case titleLabel
|
case required
|
||||||
case feedbackLabel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -117,8 +111,15 @@ import Foundation
|
|||||||
public init(with text: String) {
|
public init(with text: String) {
|
||||||
self.text = text
|
self.text = text
|
||||||
baseValue = text
|
baseValue = text
|
||||||
self.titleStateLabel = StateLabelModel(text: "")
|
self.titleStateLabel = FormLabelModel(text: "")
|
||||||
self.feedbackStateLabel = StateLabelModel(text: "")
|
self.feedbackStateLabel = FormLabelModel(text: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
public func clear() {
|
||||||
|
self.text = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -134,30 +135,21 @@ import Foundation
|
|||||||
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
|
errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage)
|
||||||
errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor)
|
errorTextColor = try typeContainer.decodeIfPresent(Color.self, forKey: .errorTextColor)
|
||||||
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
|
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? true
|
||||||
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
locked = try typeContainer.decodeIfPresent(Bool.self, forKey: .locked)
|
||||||
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
selected = try typeContainer.decodeIfPresent(Bool.self, forKey: .selected)
|
||||||
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
text = try typeContainer.decodeIfPresent(String.self, forKey: .text)
|
||||||
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
|
hideBorders = try typeContainer.decodeIfPresent(Bool.self, forKey: .hideBorders) ?? false
|
||||||
baseValue = text
|
baseValue = text
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
titleLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .titleLabel)
|
|
||||||
feedbackLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .feedbackLabel)
|
|
||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
|
self.titleStateLabel = FormLabelModel(text: title ?? "")
|
||||||
//Setup the stateLabelModels
|
self.feedbackStateLabel = FormLabelModel(model: LabelModel(text: feedback ?? "",
|
||||||
if let titleLabel = titleLabel {
|
fontStyle: FormLabelModel.defaultFontStyle,
|
||||||
self.titleStateLabel = StateLabelModel(model: titleLabel)
|
textColor: Color(uiColor: .mvmCoolGray6)))
|
||||||
} else {
|
|
||||||
self.titleStateLabel = StateLabelModel(text: title ?? "")
|
|
||||||
}
|
|
||||||
|
|
||||||
if let feedBackLabel = feedbackLabel {
|
|
||||||
self.feedbackStateLabel = StateLabelModel(model: feedBackLabel)
|
|
||||||
} else { //feedback is the model for the error
|
|
||||||
self.feedbackStateLabel = StateLabelModel(text: feedback ?? "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -166,9 +158,7 @@ import Foundation
|
|||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||||
try container.encodeIfPresent(title, forKey: .title)
|
try container.encodeIfPresent(title, forKey: .title)
|
||||||
try container.encodeIfPresent(titleLabel, forKey: .titleLabel)
|
|
||||||
try container.encodeIfPresent(feedback, forKey: .feedback)
|
try container.encodeIfPresent(feedback, forKey: .feedback)
|
||||||
try container.encodeIfPresent(feedbackLabel, forKey: .feedbackLabel)
|
|
||||||
try container.encodeIfPresent(text, forKey: .text)
|
try container.encodeIfPresent(text, forKey: .text)
|
||||||
try container.encodeIfPresent(locked, forKey: .locked)
|
try container.encodeIfPresent(locked, forKey: .locked)
|
||||||
try container.encodeIfPresent(showError, forKey: .showError)
|
try container.encodeIfPresent(showError, forKey: .showError)
|
||||||
@ -178,7 +168,9 @@ import Foundation
|
|||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(required, forKey: .required)
|
||||||
try container.encode(hideBorders, forKey: .hideBorders)
|
try container.encode(hideBorders, forKey: .hideBorders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,7 +46,7 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
|||||||
if self.textView.isShowingPlaceholder {
|
if self.textView.isShowingPlaceholder {
|
||||||
self.textView.textColor = self.textView.placeholderTextColor
|
self.textView.textColor = self.textView.placeholderTextColor
|
||||||
} else {
|
} else {
|
||||||
self.textView.textColor = (enabled ? self.textViewEntryFieldModel?.enabledTextColor : self.textViewEntryFieldModel?.disabledTextColor)?.uiColor
|
self.textView.textColor = (self.textView.isEnabled ? self.textViewEntryFieldModel?.enabledTextColor : self.textViewEntryFieldModel?.disabledTextColor)?.uiColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,8 +282,5 @@ class TextViewEntryField: EntryField, UITextViewDelegate, ObservingTextFieldDele
|
|||||||
adjustMarginConstraints(constant: 0)
|
adjustMarginConstraints(constant: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !model.enabled {
|
|
||||||
isEnabled = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -430,7 +430,7 @@ import MVMCore
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
|
|
||||||
if (model.action != nil || model.offAction != nil) {
|
if (model.action != nil || model.offAction != nil) {
|
||||||
actionBlock = { [weak self] in
|
actionBlock = { [weak self] in
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
public var accessibilityIdentifier: String?
|
public var accessibilityIdentifier: String?
|
||||||
public var selected: Bool = false
|
public var selected: Bool = false
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var animated: Bool = true
|
public var animated: Bool = true
|
||||||
public var inverted: Bool = false
|
public var inverted: Bool = false
|
||||||
public var round: Bool = false
|
public var round: Bool = false
|
||||||
@ -54,6 +55,7 @@
|
|||||||
case accessibilityIdentifier
|
case accessibilityIdentifier
|
||||||
case checked
|
case checked
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
case inverted
|
case inverted
|
||||||
case animated
|
case animated
|
||||||
case round
|
case round
|
||||||
@ -158,10 +160,8 @@
|
|||||||
self.inverted = inverted
|
self.inverted = inverted
|
||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
self.enabled = enabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
|
|
||||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
|
||||||
|
|
||||||
@ -191,7 +191,8 @@
|
|||||||
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
|
try container.encodeIfPresent(disabledCheckColor, forKey: .disabledCheckColor)
|
||||||
try container.encodeIfPresent(animated, forKey: .animated)
|
try container.encodeIfPresent(animated, forKey: .animated)
|
||||||
try container.encodeIfPresent(round, forKey: .round)
|
try container.encodeIfPresent(round, forKey: .round)
|
||||||
try container.encodeIfPresent(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
try container.encodeModelIfPresent(offAction, forKey: .offAction)
|
try container.encodeModelIfPresent(offAction, forKey: .offAction)
|
||||||
|
|||||||
@ -62,7 +62,7 @@ import UIKit
|
|||||||
heartPath.close()
|
heartPath.close()
|
||||||
heart.path = heartPath.cgPath
|
heart.path = heartPath.cgPath
|
||||||
heart.fillColor = isSelected ? heartModel?.activeColor.cgColor : heartModel?.inActiveColor.cgColor
|
heart.fillColor = isSelected ? heartModel?.activeColor.cgColor : heartModel?.inActiveColor.cgColor
|
||||||
heart.opacity = 1.0
|
heart.opacity = isEnabled ? 1.0 : 0.5
|
||||||
heart.lineWidth = 1
|
heart.lineWidth = 1
|
||||||
heart.strokeColor = isSelected ? UIColor.clear.cgColor : UIColor.mvmBlack.cgColor
|
heart.strokeColor = isSelected ? UIColor.clear.cgColor : UIColor.mvmBlack.cgColor
|
||||||
return heart
|
return heart
|
||||||
@ -88,7 +88,7 @@ import UIKit
|
|||||||
self.additionalData = additionalData
|
self.additionalData = additionalData
|
||||||
guard let model = model as? HeartModel else { return }
|
guard let model = model as? HeartModel else { return }
|
||||||
isSelected = model.isActive
|
isSelected = model.isActive
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
updateAccessibilityLabel()
|
updateAccessibilityLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
|||||||
public var inActiveColor: Color = Color(uiColor: .clear)
|
public var inActiveColor: Color = Color(uiColor: .clear)
|
||||||
public var action: ActionModelProtocol = ActionNoopModel()
|
public var action: ActionModelProtocol = ActionNoopModel()
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
|
||||||
// MARK: - Keys
|
// MARK: - Keys
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
|||||||
case inActiveColor
|
case inActiveColor
|
||||||
case action
|
case action
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -61,9 +62,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
|||||||
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
|
if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) {
|
||||||
self.action = action
|
self.action = action
|
||||||
}
|
}
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
self.enabled = enabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -76,5 +76,6 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol {
|
|||||||
try container.encode(inActiveColor, forKey: .inActiveColor)
|
try container.encode(inActiveColor, forKey: .inActiveColor)
|
||||||
try container.encodeModel(action, forKey: .action)
|
try container.encodeModel(action, forKey: .action)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@ open class RadioBox: Control, MFButtonProtocol {
|
|||||||
accentColor = color
|
accentColor = color
|
||||||
}
|
}
|
||||||
isSelected = model.selected
|
isSelected = model.selected
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func reset() {
|
open override func reset() {
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
public var selectedAccentColor: Color?
|
public var selectedAccentColor: Color?
|
||||||
public var selected: Bool = false
|
public var selected: Bool = false
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var strikethrough: Bool = false
|
public var strikethrough: Bool = false
|
||||||
public var fieldValue: String?
|
public var fieldValue: String?
|
||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
@ -39,6 +40,7 @@
|
|||||||
case strikethrough
|
case strikethrough
|
||||||
case fieldValue
|
case fieldValue
|
||||||
case action
|
case action
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -57,9 +59,8 @@
|
|||||||
selected = isSelected
|
selected = isSelected
|
||||||
}
|
}
|
||||||
|
|
||||||
if let isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
enabled = isEnabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
|
|
||||||
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
if let isStrikeTrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||||
strikethrough = isStrikeTrough
|
strikethrough = isStrikeTrough
|
||||||
@ -79,6 +80,7 @@
|
|||||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||||
try container.encode(selected, forKey: .selected)
|
try container.encode(selected, forKey: .selected)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
try container.encode(strikethrough, forKey: .strikethrough)
|
try container.encode(strikethrough, forKey: .strikethrough)
|
||||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -42,6 +42,7 @@
|
|||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case moleculeName
|
case moleculeName
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
case selectedAccentColor
|
case selectedAccentColor
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
case accessibilityIdentifier
|
case accessibilityIdentifier
|
||||||
@ -66,9 +67,8 @@
|
|||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
self.enabled = enabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
baseValue = formFieldValue()
|
baseValue = formFieldValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,5 +81,7 @@
|
|||||||
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encode(groupName, forKey: .groupName)
|
try container.encode(groupName, forKey: .groupName)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ import UIKit
|
|||||||
open override func draw(_ rect: CGRect) {
|
open override func draw(_ rect: CGRect) {
|
||||||
guard let context = UIGraphicsGetCurrentContext() else { return }
|
guard let context = UIGraphicsGetCurrentContext() else { return }
|
||||||
|
|
||||||
let color = isEnabled ? enabledColor.cgColor : disabledColor.cgColor
|
let color = isEnabled == false ? disabledColor.cgColor : enabledColor.cgColor
|
||||||
layer.cornerRadius = bounds.width * 0.5
|
layer.cornerRadius = bounds.width * 0.5
|
||||||
layer.borderColor = color
|
layer.borderColor = color
|
||||||
layer.borderWidth = bounds.width * 0.0333
|
layer.borderWidth = bounds.width * 0.0333
|
||||||
@ -163,7 +163,7 @@ import UIKit
|
|||||||
guard let model = model as? RadioButtonModel else { return }
|
guard let model = model as? RadioButtonModel else { return }
|
||||||
|
|
||||||
isSelected = model.state
|
isSelected = model.state
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
RadioButtonSelectionHelper.setupForRadioButtonGroup(model, self, delegateObject: delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
public var accessibilityIdentifier: String?
|
public var accessibilityIdentifier: String?
|
||||||
public var state: Bool = false
|
public var state: Bool = false
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
/// The specific value to send to server. TODO: update this to be more generic.
|
/// The specific value to send to server. TODO: update this to be more generic.
|
||||||
public var fieldValue: String?
|
public var fieldValue: String?
|
||||||
@ -42,6 +43,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
case action
|
case action
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -73,10 +75,8 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
self.state = state
|
self.state = state
|
||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
self.enabled = enabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
|
|
||||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||||
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
|
||||||
|
|
||||||
@ -96,6 +96,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encode(state, forKey: .state)
|
try container.encode(state, forKey: .state)
|
||||||
try container.encode(enabled, forKey: .enabled)
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
private var selectedRadioButtonModel: RadioButtonModel?
|
private var selectedRadioButtonModel: RadioButtonModel?
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializer
|
// MARK: - Initializer
|
||||||
@ -41,6 +42,7 @@
|
|||||||
radioButton.isSelected = false
|
radioButton.isSelected = false
|
||||||
}
|
}
|
||||||
self.enabled = radioButtonModel.enabled
|
self.enabled = radioButtonModel.enabled
|
||||||
|
self.readOnly = radioButtonModel.readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -64,7 +64,7 @@ open class RadioSwatch: Control, MFButtonProtocol {
|
|||||||
self.additionalData = additionalData
|
self.additionalData = additionalData
|
||||||
bottomText.text = model.text
|
bottomText.text = model.text
|
||||||
isSelected = model.selected
|
isSelected = model.selected
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reset() {
|
public override func reset() {
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
public var text: String?
|
public var text: String?
|
||||||
public var selected: Bool = false
|
public var selected: Bool = false
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var strikethrough: Bool = false
|
public var strikethrough: Bool = false
|
||||||
public var fieldValue: String?
|
public var fieldValue: String?
|
||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
@ -38,6 +39,7 @@
|
|||||||
case strikethrough
|
case strikethrough
|
||||||
case fieldValue
|
case fieldValue
|
||||||
case action
|
case action
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -59,16 +61,14 @@
|
|||||||
self.selected = selected
|
self.selected = selected
|
||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
|
||||||
self.enabled = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
if let strikethrough = try typeContainer.decodeIfPresent(Bool.self, forKey: .strikethrough) {
|
||||||
self.strikethrough = strikethrough
|
self.strikethrough = strikethrough
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue)
|
||||||
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
|
||||||
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -83,5 +83,6 @@
|
|||||||
try container.encode(strikethrough, forKey: .strikethrough)
|
try container.encode(strikethrough, forKey: .strikethrough)
|
||||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
try container.encodeModelIfPresent(action, forKey: .action)
|
try container.encodeModelIfPresent(action, forKey: .action)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
@ -46,6 +47,7 @@
|
|||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -61,9 +63,8 @@
|
|||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
self.enabled = enabled
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
|
||||||
baseValue = formFieldValue()
|
baseValue = formFieldValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,5 +76,7 @@
|
|||||||
try container.encode(swatches, forKey: .swatches)
|
try container.encode(swatches, forKey: .swatches)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encode(groupName, forKey: .groupName)
|
try container.encode(groupName, forKey: .groupName)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -384,7 +384,7 @@ public typealias ActionBlockConfirmation = () -> (Bool)
|
|||||||
isOn = model.selected
|
isOn = model.selected
|
||||||
changeStateNoAnimation(isOn)
|
changeStateNoAnimation(isOn)
|
||||||
isAnimated = model.animated
|
isAnimated = model.animated
|
||||||
isEnabled = model.enabled
|
isEnabled = model.enabled && !model.readOnly
|
||||||
|
|
||||||
if let accessibileString = model.accessibilityText {
|
if let accessibileString = model.accessibilityText {
|
||||||
accessibilityLabel = accessibileString
|
accessibilityLabel = accessibileString
|
||||||
|
|||||||
@ -18,6 +18,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
public var selected: Bool = false
|
public var selected: Bool = false
|
||||||
public var animated: Bool = true
|
public var animated: Bool = true
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var action: ActionModelProtocol?
|
public var action: ActionModelProtocol?
|
||||||
public var alternateAction: ActionModelProtocol?
|
public var alternateAction: ActionModelProtocol?
|
||||||
public var accessibilityText: String?
|
public var accessibilityText: String?
|
||||||
@ -39,6 +40,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
case state
|
case state
|
||||||
case animated
|
case animated
|
||||||
case enabled
|
case enabled
|
||||||
|
case readOnly
|
||||||
case action
|
case action
|
||||||
case backgroundColor
|
case backgroundColor
|
||||||
case accessibilityIdentifier
|
case accessibilityIdentifier
|
||||||
@ -81,10 +83,6 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
self.selected = state
|
self.selected = state
|
||||||
}
|
}
|
||||||
|
|
||||||
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
|
||||||
self.enabled = enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
|
if let animated = try typeContainer.decodeIfPresent(Bool.self, forKey: .animated) {
|
||||||
self.animated = animated
|
self.animated = animated
|
||||||
}
|
}
|
||||||
@ -117,6 +115,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
|
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
|
||||||
|
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -136,5 +136,6 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol {
|
|||||||
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText)
|
||||||
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
|
||||||
try container.encodeIfPresent(groupName, forKey: .groupName)
|
try container.encodeIfPresent(groupName, forKey: .groupName)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,35 +9,31 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// Subclass of label that helps with different states
|
/// Subclass of label that helps with different states
|
||||||
public class StateLabel: Label {
|
public class FormLabel: Label {
|
||||||
//properties used in setting label
|
//properties used in setting label
|
||||||
private var delegateObject: MVMCoreUIDelegateObject?
|
private var delegateObject: MVMCoreUIDelegateObject?
|
||||||
private var additionalData: [AnyHashable: Any]?
|
private var additionalData: [AnyHashable: Any]?
|
||||||
|
|
||||||
//models that drive the label UI
|
//models that drive the label UI
|
||||||
private var stateModel: StateLabelModel!
|
private var formModel: FormLabelModel!
|
||||||
|
|
||||||
//public properties
|
//public properties
|
||||||
public override var isEnabled: Bool {
|
public override var isEnabled: Bool {
|
||||||
didSet{
|
didSet{
|
||||||
self.state = isEnabled ? .enabled : .disabled
|
self.formModel.enabled = isEnabled
|
||||||
|
self.set(with: isRequired ? formModel.model : formModel.requiredModel, delegateObject, additionalData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isRequired: Bool = true {
|
||||||
|
didSet{
|
||||||
|
self.set(with: isRequired ? formModel.model : formModel.requiredModel, delegateObject, additionalData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reset(){
|
public override func reset(){
|
||||||
super.reset()
|
super.reset()
|
||||||
self.state = .enabled
|
self.isEnabled = true
|
||||||
}
|
|
||||||
|
|
||||||
//current mode of label
|
|
||||||
public var state: StateLabelModel.State {
|
|
||||||
get {
|
|
||||||
return self.stateModel.state
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
self.stateModel.state = newValue
|
|
||||||
self.set(with: stateModel.model, delegateObject, additionalData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used in setting up the Label for use
|
/// Used in setting up the Label for use
|
||||||
@ -46,25 +42,18 @@ public class StateLabel: Label {
|
|||||||
/// - model: Model takes priority over a text value. The model has its own text value that will be looked at to draw the screen, this model is used for both enabled/disabled models
|
/// - model: Model takes priority over a text value. The model has its own text value that will be looked at to draw the screen, this model is used for both enabled/disabled models
|
||||||
/// - delegateObject: passed in from the creator
|
/// - delegateObject: passed in from the creator
|
||||||
/// - additionalData: passed in from the creator
|
/// - additionalData: passed in from the creator
|
||||||
public func setup(model: StateLabelModel, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
|
public func setup(model: FormLabelModel, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
|
||||||
self.additionalData = additionalData
|
self.additionalData = additionalData
|
||||||
self.delegateObject = delegateObject
|
self.delegateObject = delegateObject
|
||||||
self.stateModel = model
|
self.formModel = model
|
||||||
|
|
||||||
//default to enabled state
|
//default to enabled state
|
||||||
self.reset()
|
self.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this to switch the label into a error state
|
|
||||||
/// - Parameter message: message to show in the errorModel
|
|
||||||
public func showError(message: String){
|
|
||||||
self.stateModel.set(text: message, for: .error)
|
|
||||||
self.state = .error
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Text change that will update both enabledModel and disabledModel text values
|
/// Text change that will update both enabledModel and disabledModel text values
|
||||||
/// - Parameter text: text you want to see
|
/// - Parameter text: text you want to see
|
||||||
public func set(text: String?){
|
public func set(text: String?){
|
||||||
self.stateModel.set(text: text ?? "", for: .enabled)
|
self.formModel.set(text: text ?? "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8,35 +8,21 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class StateLabelModel {
|
public class FormLabelModel: EnableableModelProtocol {
|
||||||
static let defaultFontStyle = Styler.Font.RegularMicro
|
static let defaultFontStyle = Styler.Font.RegularMicro
|
||||||
static let defaultEnabledTextColor = Color(uiColor: .mvmBlack)
|
static let defaultEnabledTextColor = Color(uiColor: .mvmBlack)
|
||||||
static let defaultDisabledTextColor = Color(uiColor: .mvmCoolGray3)
|
static let defaultDisabledTextColor = Color(uiColor: .mvmCoolGray3)
|
||||||
static let defaultErrorTextColor = Color(uiColor: .mvmBlack)
|
static let defaultRequiredTextColor = Color(uiColor: .mvmCoolGray6)
|
||||||
|
|
||||||
private var enabledModel: LabelModel
|
private var enabledModel: LabelModel
|
||||||
private var disabledModel = LabelModel(fontStyle: StateLabelModel.defaultFontStyle, textColor: StateLabelModel.defaultDisabledTextColor)
|
private var disabledModel = LabelModel(fontStyle: FormLabelModel.defaultFontStyle, textColor: FormLabelModel.defaultDisabledTextColor)
|
||||||
private var errorLabelModel = LabelModel(fontStyle: StateLabelModel.defaultFontStyle, textColor: StateLabelModel.defaultErrorTextColor)
|
|
||||||
|
|
||||||
public enum State {
|
|
||||||
case enabled
|
|
||||||
case disabled
|
|
||||||
case error
|
|
||||||
}
|
|
||||||
|
|
||||||
//current state
|
//current state
|
||||||
public var state: State = .enabled
|
public var enabled: Bool = true
|
||||||
|
|
||||||
//model is based on current state
|
//model is based on current state
|
||||||
public var model: LabelModel {
|
public var model: LabelModel {
|
||||||
switch state {
|
return enabled ? enabledModel: disabledModel
|
||||||
case .enabled:
|
|
||||||
return enabledModel
|
|
||||||
case .disabled:
|
|
||||||
return disabledModel
|
|
||||||
case .error:
|
|
||||||
return errorLabelModel
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//init
|
//init
|
||||||
@ -48,13 +34,13 @@ public class StateLabelModel {
|
|||||||
if let modelFontStyle = model.fontStyle {
|
if let modelFontStyle = model.fontStyle {
|
||||||
self.disabledModel.fontStyle = modelFontStyle
|
self.disabledModel.fontStyle = modelFontStyle
|
||||||
} else {
|
} else {
|
||||||
model.fontStyle = StateLabelModel.defaultFontStyle
|
model.fontStyle = FormLabelModel.defaultFontStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
//ensure the textColor is set
|
//ensure the textColor is set
|
||||||
//otherwise use the defaultEnabledTextColor
|
//otherwise use the defaultEnabledTextColor
|
||||||
if model.textColor == nil {
|
if model.textColor == nil {
|
||||||
model.textColor = StateLabelModel.defaultEnabledTextColor
|
model.textColor = FormLabelModel.defaultEnabledTextColor
|
||||||
}
|
}
|
||||||
|
|
||||||
//set the enabledModel to the model passed in
|
//set the enabledModel to the model passed in
|
||||||
@ -66,26 +52,30 @@ public class StateLabelModel {
|
|||||||
|
|
||||||
public init(text: String){
|
public init(text: String){
|
||||||
//create the enabled model
|
//create the enabled model
|
||||||
self.enabledModel = LabelModel(fontStyle: StateLabelModel.defaultFontStyle, textColor: StateLabelModel.defaultEnabledTextColor)
|
self.enabledModel = LabelModel(fontStyle: FormLabelModel.defaultFontStyle, textColor: FormLabelModel.defaultEnabledTextColor)
|
||||||
self.enabledModel.text = text
|
self.enabledModel.text = text
|
||||||
|
|
||||||
//make sure the enabled & disabled text match
|
//make sure the enabled & disabled text match
|
||||||
self.disabledModel.text = self.enabledModel.text
|
self.disabledModel.text = self.enabledModel.text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var requiredModel: LabelModel {
|
||||||
|
let required = LabelModel(fontStyle: model.fontStyle!, textColor: model.textColor!)
|
||||||
|
if enabled {
|
||||||
|
required.attributes = [LabelAttributeColorModel(FormLabelModel.defaultRequiredTextColor, model.text.count + 1, 8)]
|
||||||
|
}
|
||||||
|
required.text = "\(model.text) Optional"
|
||||||
|
return required
|
||||||
|
}
|
||||||
|
|
||||||
//methods
|
//methods
|
||||||
public func reset(){
|
public func reset(){
|
||||||
self.state = .enabled
|
self.enabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
//set text for state
|
//set text for state
|
||||||
public func set(text:String, for state: State){
|
public func set(text:String){
|
||||||
switch state {
|
self.enabledModel.text = text
|
||||||
case .enabled, .disabled:
|
self.disabledModel.text = text
|
||||||
self.enabledModel.text = text
|
|
||||||
self.disabledModel.text = text
|
|
||||||
case .error:
|
|
||||||
self.errorLabelModel.text = text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -24,10 +24,14 @@
|
|||||||
case textColor
|
case textColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public init(_ textColor: Color?, _ location: Int, _ length: Int){
|
||||||
|
self.textColor = textColor
|
||||||
|
super.init(location, length)
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Codec
|
// MARK: - Codec
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
required public init(from decoder: Decoder) throws {
|
required public init(from decoder: Decoder) throws {
|
||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
|
textColor = try typeContainer.decodeIfPresent(Color.self, forKey: .textColor)
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
public var analyticsData: JSONValueDictionary?
|
public var analyticsData: JSONValueDictionary?
|
||||||
public var fieldValue: String?
|
public var fieldValue: String?
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var baseValue: AnyHashable?
|
public var baseValue: AnyHashable?
|
||||||
@ -40,6 +41,8 @@
|
|||||||
case fieldValue
|
case fieldValue
|
||||||
case fieldKey
|
case fieldKey
|
||||||
case groupName
|
case groupName
|
||||||
|
case enabled
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -57,6 +60,12 @@
|
|||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
baseValue = fieldValue
|
baseValue = fieldValue
|
||||||
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
self.enabled = enabled
|
||||||
|
}
|
||||||
|
if let readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) {
|
||||||
|
self.readOnly = readOnly
|
||||||
|
}
|
||||||
try super.init(from: decoder)
|
try super.init(from: decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,5 +76,7 @@
|
|||||||
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
try container.encodeIfPresent(peakingArrowColor, forKey: .peakingArrowColor)
|
||||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
try container.encodeIfPresent(fieldValue, forKey: .fieldValue)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import UIKit
|
|||||||
public var fieldKey: String?
|
public var fieldKey: String?
|
||||||
public var groupName: String = FormValidator.defaultGroupName
|
public var groupName: String = FormValidator.defaultGroupName
|
||||||
public var enabled: Bool = true
|
public var enabled: Bool = true
|
||||||
|
public var readOnly: Bool = false
|
||||||
|
|
||||||
public var selectable = false
|
public var selectable = false
|
||||||
public var selectedIndex: Int?
|
public var selectedIndex: Int?
|
||||||
@ -87,6 +88,8 @@ import UIKit
|
|||||||
case fieldKey
|
case fieldKey
|
||||||
case selectable
|
case selectable
|
||||||
case selectedIndex
|
case selectedIndex
|
||||||
|
case enabled
|
||||||
|
case readOnly
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -120,10 +123,16 @@ import UIKit
|
|||||||
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) {
|
||||||
self.groupName = groupName
|
self.groupName = groupName
|
||||||
}
|
}
|
||||||
|
if let enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) {
|
||||||
|
self.enabled = enabled
|
||||||
|
}
|
||||||
|
if let readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) {
|
||||||
|
self.readOnly = readOnly
|
||||||
|
}
|
||||||
baseValue = formFieldValue()
|
baseValue = formFieldValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(moleculeName, forKey: .moleculeName)
|
try container.encode(moleculeName, forKey: .moleculeName)
|
||||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||||
@ -145,6 +154,8 @@ import UIKit
|
|||||||
try container.encode(index, forKey: .index)
|
try container.encode(index, forKey: .index)
|
||||||
try container.encode(selectable, forKey: .selectable)
|
try container.encode(selectable, forKey: .selectable)
|
||||||
try container.encode(selectedIndex, forKey: .selectedIndex)
|
try container.encode(selectedIndex, forKey: .selectedIndex)
|
||||||
|
try container.encode(enabled, forKey: .enabled)
|
||||||
|
try container.encode(readOnly, forKey: .readOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// ClearableModelProtocol.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 1/11/22.
|
||||||
|
// Copyright © 2022 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public protocol ClearableModelProtocol {
|
||||||
|
func clear()
|
||||||
|
}
|
||||||
@ -13,7 +13,6 @@ import UIKit
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open var model: MoleculeModelProtocol?
|
open var model: MoleculeModelProtocol?
|
||||||
|
|
||||||
private var initialSetupPerformed = false
|
private var initialSetupPerformed = false
|
||||||
|
|||||||
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// ClearFormFieldEffectModel.swift
|
||||||
|
// MVMCoreUI
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 1/11/22.
|
||||||
|
// Copyright © 2022 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class ClearFormFieldEffectModel: FormFieldEffectProtocol {
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
public static var identifier: String = "clearFormFieldEffect"
|
||||||
|
public var fieldKey: String = ""
|
||||||
|
public var activatedRuleIds: [String]?
|
||||||
|
public var rules: [RulesProtocol]
|
||||||
|
|
||||||
|
init(_ fieldKey: String, activatedRuleIds: [String], rules: [RulesProtocol]) {
|
||||||
|
self.fieldKey = fieldKey
|
||||||
|
self.activatedRuleIds = activatedRuleIds
|
||||||
|
self.rules = rules
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Keys
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
private enum CodingKeys: String, CodingKey {
|
||||||
|
case fieldKey
|
||||||
|
case activatedRuleIds
|
||||||
|
case rules
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Codec
|
||||||
|
//--------------------------------------------------
|
||||||
|
|
||||||
|
required public init(from decoder: Decoder) throws {
|
||||||
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
self.fieldKey = try typeContainer.decode(String.self, forKey: .fieldKey)
|
||||||
|
self.activatedRuleIds = try typeContainer.decodeIfPresent([String].self, forKey: .activatedRuleIds)
|
||||||
|
self.rules = try typeContainer.decodeModels(codingKey: .rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
|
try container.encode(fieldKey, forKey: .fieldKey)
|
||||||
|
try container.encodeIfPresent(activatedRuleIds, forKey: .activatedRuleIds)
|
||||||
|
try container.encodeModels(rules, forKey: .rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setEffect(validity: Bool, field: FormFieldProtocol,form: FormValidator, group: FormGroupRule) {
|
||||||
|
guard let field = field as? ClearableModelProtocol, validity else { return }
|
||||||
|
field.clear()
|
||||||
|
if let updateField = field as? UIUpdatableModelProtocol {
|
||||||
|
updateField.updateUI?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,11 +16,18 @@ public protocol FormFieldProtocol: FormItemProtocol {
|
|||||||
/// A place to store the initial value of the field for checking if the value has changed.
|
/// A place to store the initial value of the field for checking if the value has changed.
|
||||||
var baseValue: AnyHashable? { get set }
|
var baseValue: AnyHashable? { get set }
|
||||||
|
|
||||||
|
///Bool to determine a state that is different from disabled. Readonly values will be sent
|
||||||
|
///to the server where disabled fields are not
|
||||||
|
var readOnly: Bool { get set }
|
||||||
|
|
||||||
/// Returns the value of the field. Used for validations and possibly for sending to server.
|
/// Returns the value of the field. Used for validations and possibly for sending to server.
|
||||||
func formFieldValue() -> AnyHashable?
|
func formFieldValue() -> AnyHashable?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FormFieldProtocol {
|
extension FormFieldProtocol {
|
||||||
|
|
||||||
var baseValue: AnyHashable? { nil }
|
var baseValue: AnyHashable? { nil }
|
||||||
|
|
||||||
|
var readOnly: Bool { false }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,11 +111,19 @@ import MVMCore
|
|||||||
/// - counter: keeps track of how many times causes another group validation
|
/// - counter: keeps track of how many times causes another group validation
|
||||||
/// - Returns: validity for the FormGroupRule.rules
|
/// - Returns: validity for the FormGroupRule.rules
|
||||||
public func validateGroup(_ group: FormGroupRule, counter: Int = 0) throws -> Bool {
|
public func validateGroup(_ group: FormGroupRule, counter: Int = 0) throws -> Bool {
|
||||||
let valid = group.validate(fields)
|
let tuple = group.validate(fields)
|
||||||
|
|
||||||
|
group.rules.forEach { rule in
|
||||||
|
for formKey in rule.fields {
|
||||||
|
guard let formField = fields[formKey] as? FormRuleWatcherFieldProtocol,
|
||||||
|
let fieldValidity = tuple.fieldValidity[formKey] else { continue }
|
||||||
|
formField.setValidity(fieldValidity, rule: rule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Notify the group watchers of validity.
|
// Notify the group watchers of validity.
|
||||||
for watcher in groupWatchers.filter({$0.groupName == group.groupName}) {
|
for watcher in groupWatchers.filter({$0.groupName == group.groupName}) {
|
||||||
watcher.setValidity(valid)
|
watcher.setValidity(tuple.valid)
|
||||||
}
|
}
|
||||||
|
|
||||||
var ruleChange = false
|
var ruleChange = false
|
||||||
@ -125,14 +133,14 @@ import MVMCore
|
|||||||
//get the fieldKey for the effect
|
//get the fieldKey for the effect
|
||||||
if let effected = fields[effect.fieldKey] {
|
if let effected = fields[effect.fieldKey] {
|
||||||
//get the validity
|
//get the validity
|
||||||
let validity = effect.validate(fields)
|
let effectTuple = effect.validate(fields)
|
||||||
|
|
||||||
//set the effect with the validation
|
//set the effect with the validation
|
||||||
effect.setEffect(validity: validity, field: effected, form: self, group: group)
|
effect.setEffect(validity: effectTuple.valid, field: effected, form: self, group: group)
|
||||||
|
|
||||||
//update the group form rules
|
//update the group form rules
|
||||||
if let ruleIds = effect.activatedRuleIds {
|
if let ruleIds = effect.activatedRuleIds {
|
||||||
let didChange = self.updateRules(for: group, with: validity, for: effect.fieldKey, and: ruleIds)
|
let didChange = self.updateRules(for: group, with: effectTuple.valid, for: effect.fieldKey, and: ruleIds)
|
||||||
if(didChange) {
|
if(didChange) {
|
||||||
ruleChange = didChange
|
ruleChange = didChange
|
||||||
}
|
}
|
||||||
@ -147,7 +155,7 @@ import MVMCore
|
|||||||
return try self.validateGroup(group, counter: counter + 1)
|
return try self.validateGroup(group, counter: counter + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return valid
|
return tuple.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,15 +51,10 @@ public class RuleEqualsIgnoreCaseModel: RulesProtocol {
|
|||||||
fieldValidity = false
|
fieldValidity = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for formKey in fields {
|
|
||||||
guard let formField = fieldMolecules[formKey] else { continue }
|
|
||||||
(formField as? FormRuleWatcherFieldProtocol)?.setValidity(true, rule: self)
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
previousValidity[formKey] = valid
|
previousValidity[formKey] = valid
|
||||||
(formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self)
|
|
||||||
}
|
}
|
||||||
return (valid: valid, fieldValidity: previousValidity)
|
return (valid: valid, fieldValidity: previousValidity)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,8 +43,6 @@ public class RuleEqualsModel: RulesProtocol {
|
|||||||
|
|
||||||
if compareValue != formField.formFieldValue() {
|
if compareValue != formField.formFieldValue() {
|
||||||
valid = false
|
valid = false
|
||||||
previousValidity[formKey] = valid
|
|
||||||
(formField as? FormRuleWatcherFieldProtocol)?.setValidity(valid, rule: self)
|
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
var fieldValidity = valid
|
var fieldValidity = valid
|
||||||
@ -52,8 +50,9 @@ public class RuleEqualsModel: RulesProtocol {
|
|||||||
if let validity = previousFieldValidity[formKey], !validity, fieldValidity {
|
if let validity = previousFieldValidity[formKey], !validity, fieldValidity {
|
||||||
fieldValidity = false
|
fieldValidity = false
|
||||||
}
|
}
|
||||||
(formField as? FormRuleWatcherFieldProtocol)?.setValidity(fieldValidity, rule: self)
|
|
||||||
}
|
}
|
||||||
|
previousValidity[formKey] = valid
|
||||||
|
|
||||||
}
|
}
|
||||||
return (valid: valid, fieldValidity: previousValidity)
|
return (valid: valid, fieldValidity: previousValidity)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,6 @@ public extension RulesProtocol {
|
|||||||
if let validity = previousFieldValidity[formKey], !validity, fieldValidity {
|
if let validity = previousFieldValidity[formKey], !validity, fieldValidity {
|
||||||
fieldValidity = false
|
fieldValidity = false
|
||||||
}
|
}
|
||||||
(formField as? FormRuleWatcherFieldProtocol)?.setValidity(fieldValidity, rule: self)
|
|
||||||
valid = valid && fieldValidity
|
valid = valid && fieldValidity
|
||||||
previousValidity[formKey] = fieldValidity
|
previousValidity[formKey] = fieldValidity
|
||||||
}
|
}
|
||||||
@ -66,12 +65,19 @@ public protocol RulesContainerProtocol{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public extension RulesContainerProtocol {
|
public extension RulesContainerProtocol {
|
||||||
func validate(_ fields: [String: FormFieldProtocol]) -> Bool {
|
/// This validation for Rules for the Validation or for Effects.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - fields: Fields for the group
|
||||||
|
/// - setValidity: Since this function is for validation, this bool determines if you should set the FormFields.setValidity for a rule.
|
||||||
|
/// this method can be called for Form Validation and Effect Validation (this doesn't affect the submital of the form)
|
||||||
|
/// - Returns: Tuple(valid, fieldValidity)
|
||||||
|
/// - valid: bool for all rules
|
||||||
|
/// - fieldValidity: accumulation of all fieldKey: valid
|
||||||
|
func validate(_ fields: [String: FormFieldProtocol]) -> (valid: Bool, fieldValidity: [String:Bool] ) {
|
||||||
// Validate each rule.
|
// Validate each rule.
|
||||||
var valid = true
|
var valid = true
|
||||||
var previousValidity: [String: Bool] = [:]
|
var previousValidity: [String: Bool] = [:]
|
||||||
for rule in self.rules {
|
for rule in self.rules {
|
||||||
|
|
||||||
//validate the rule against the fields
|
//validate the rule against the fields
|
||||||
let tuple = rule.validate(fields, previousValidity)
|
let tuple = rule.validate(fields, previousValidity)
|
||||||
|
|
||||||
@ -79,6 +85,6 @@ public extension RulesContainerProtocol {
|
|||||||
previousValidity = previousValidity.merging(tuple.fieldValidity) { (_, new) in new }
|
previousValidity = previousValidity.merging(tuple.fieldValidity) { (_, new) in new }
|
||||||
valid = valid && tuple.valid
|
valid = valid && tuple.valid
|
||||||
}
|
}
|
||||||
return valid
|
return (valid: valid, fieldValidity: previousValidity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -247,5 +247,6 @@ open class CoreUIModelMapping: ModelMapping {
|
|||||||
ModelRegistry.register(DynamicRuleFormFieldEffectModel.self)
|
ModelRegistry.register(DynamicRuleFormFieldEffectModel.self)
|
||||||
ModelRegistry.register(DisableFormFieldEffectModel.self)
|
ModelRegistry.register(DisableFormFieldEffectModel.self)
|
||||||
ModelRegistry.register(HideFormFieldEffectModel.self)
|
ModelRegistry.register(HideFormFieldEffectModel.self)
|
||||||
|
ModelRegistry.register(ClearFormFieldEffectModel.self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user