From 3ec024ff270efbcd63aea24bf939590362ae3552 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 3 Mar 2020 20:32:57 -0500 Subject: [PATCH 01/19] changes --- MVMCoreUI.xcodeproj/project.pbxproj | 76 ++++++++++++ MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 24 ++-- MVMCoreUI/Atoms/Buttons/PillButton.swift | 22 ++-- ...maryButton+MoleculeProtocolExtension.swift | 11 +- .../Atoms/TextFields/EntryFieldModel.swift | 22 +++- .../MFTextField+ModelExtension.swift | 116 ++++++++--------- .../Atoms/TextFields/MdnEntryField.swift | 42 +++---- .../Atoms/TextFields/TextEntryField.swift | 53 ++++---- .../TextFields/TextEntryFieldModel.swift | 1 - MVMCoreUI/Atoms/Views/Checkbox.swift | 91 +------------- MVMCoreUI/Atoms/Views/CheckboxModel.swift | 24 ++-- .../Atoms/Views/MFView+ModelExtension.swift | 2 +- .../Atoms/Views/MVMCoreUISwitch+Model.swift | 5 +- MVMCoreUI/Atoms/Views/RadioButton.swift | 62 +++------- MVMCoreUI/Atoms/Views/RadioButtonModel.swift | 15 ++- MVMCoreUI/Atoms/Views/Toggle.swift | 4 +- MVMCoreUI/Atoms/Views/ToggleModel.swift | 7 +- .../MFViewController+Form.swift | 22 ++++ MVMCoreUI/BaseControllers/MFViewController.m | 15 +-- .../FormValidator+FormParams.swift | 18 --- .../FormValidator+TextFields.swift | 117 +++++++++--------- MVMCoreUI/FormUIHelpers/FormValidator.swift | 106 ++++++++-------- .../New/FormActionFieldProtocol.swift | 15 +++ .../FormUIHelpers/New/FormFieldProtocol.swift | 15 +++ .../New/FormHolderProtocol.swift | 17 +++ .../FormUIHelpers/New/FormItemProtocol.swift | 13 ++ .../FormUIHelpers/New/FormProtocol.swift | 15 +++ .../New/Rules/FormGroupRule.swift | 49 ++++++++ .../New/Rules/RuleAnyModel.swift | 20 +++ .../New/Rules/RuleEqualsModel.swift | 20 +++ .../New/Rules/RuleRegexModel.swift | 19 +++ .../New/Rules/RuleRequiredModel.swift | 30 +++++ .../New/Rules/RuleValueChangeModel.swift | 20 +++ .../New/Rules/RulesProtocol.swift | 61 +++++++++ .../FormUIHelpers/New/ValidProtocol.swift | 15 +++ MVMCoreUI/Legacy/Views/MFTextField.m | 6 +- MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m | 4 +- MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m | 13 +- MVMCoreUI/Legacy/Views/PrimaryButton.m | 2 +- .../TemplateModelProtocol.swift | 2 +- MVMCoreUI/Molecules/RadioButtonLabel.swift | 32 ++--- .../Molecules/RadioButtonLabelModel.swift | 17 +++ .../RadioButtonSelectionHelper.swift | 37 +++--- .../MVMCoreUIDelegateObject.swift | 6 +- .../OtherHandlers/MoleculeObjectMapping.swift | 11 +- .../Templates/ListPageTemplateModel.swift | 7 ++ .../Templates/MoleculeListTemplate.swift | 7 +- .../Templates/MoleculeStackTemplate.swift | 5 + .../StackCenteredPageTemplateModel.swift | 27 ++++ .../Templates/StackPageTemplateModel.swift | 6 + MVMCoreUI/Templates/TemplateProtocol.swift | 8 +- .../ThreeLayerPageTemplateModel.swift | 4 + MVMCoreUI/Templates/ThreeLayerTemplate.swift | 5 + 53 files changed, 863 insertions(+), 500 deletions(-) create mode 100644 MVMCoreUI/BaseControllers/MFViewController+Form.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/FormProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift create mode 100644 MVMCoreUI/Molecules/RadioButtonLabelModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 339735f3..d15c400c 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -15,7 +15,22 @@ 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */; }; 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */; }; 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */; }; + 011D958524042432000E3791 /* RulesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D958424042432000E3791 /* RulesProtocol.swift */; }; + 011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D958624042492000E3791 /* FormFieldProtocol.swift */; }; + 011D95892404249B000E3791 /* FormProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95882404249B000E3791 /* FormProtocol.swift */; }; + 011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959A240451E3000E3791 /* RuleRequiredModel.swift */; }; + 011D959D2404536F000E3791 /* RuleAnyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959C2404536F000E3791 /* RuleAnyModel.swift */; }; + 011D959F240453A1000E3791 /* RuleValueChangeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */; }; + 011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */; }; + 011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A2240453F8000E3791 /* RuleRegexModel.swift */; }; + 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A4240455DC000E3791 /* FormGroupRule.swift */; }; + 011D95A924057AC7000E3791 /* FormActionFieldProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */; }; + 011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AA2405C553000E3791 /* FormItemProtocol.swift */; }; + 011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */; }; 011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95AE2407266E000E3791 /* RadioButtonModel.swift */; }; + 011D9602240DA20A000E3791 /* ValidProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9601240DA20A000E3791 /* ValidProtocol.swift */; }; + 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */; }; + 011D9628240EFA1E000E3791 /* MFViewController+Form.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D9627240EFA1E000E3791 /* MFViewController+Form.swift */; }; 012A889C23889E8400FE3DA1 /* TemplateModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */; }; 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */; }; 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */; }; @@ -370,7 +385,22 @@ 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonSelectionHelper.swift; sourceTree = ""; }; 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModelProtocol.swift; sourceTree = ""; }; 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownListItemModel.swift; sourceTree = ""; }; + 011D958424042432000E3791 /* RulesProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RulesProtocol.swift; sourceTree = ""; }; + 011D958624042492000E3791 /* FormFieldProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormFieldProtocol.swift; sourceTree = ""; }; + 011D95882404249B000E3791 /* FormProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormProtocol.swift; sourceTree = ""; }; + 011D959A240451E3000E3791 /* RuleRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRequiredModel.swift; sourceTree = ""; }; + 011D959C2404536F000E3791 /* RuleAnyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModel.swift; sourceTree = ""; }; + 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleValueChangeModel.swift; sourceTree = ""; }; + 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsModel.swift; sourceTree = ""; }; + 011D95A2240453F8000E3791 /* RuleRegexModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRegexModel.swift; sourceTree = ""; }; + 011D95A4240455DC000E3791 /* FormGroupRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormGroupRule.swift; sourceTree = ""; }; + 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormActionFieldProtocol.swift; sourceTree = ""; }; + 011D95AA2405C553000E3791 /* FormItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormItemProtocol.swift; sourceTree = ""; }; + 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormHolderProtocol.swift; sourceTree = ""; }; 011D95AE2407266E000E3791 /* RadioButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonModel.swift; sourceTree = ""; }; + 011D9601240DA20A000E3791 /* ValidProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidProtocol.swift; sourceTree = ""; }; + 011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonLabelModel.swift; sourceTree = ""; }; + 011D9627240EFA1E000E3791 /* MFViewController+Form.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFViewController+Form.swift"; sourceTree = ""; }; 012A889B23889E8400FE3DA1 /* TemplateModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModelProtocol.swift; sourceTree = ""; }; 012A88AC238C418100FE3DA1 /* TemplateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateProtocol.swift; sourceTree = ""; }; 012A88AE238C626E00FE3DA1 /* CarouselModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselModel.swift; sourceTree = ""; }; @@ -748,6 +778,34 @@ path = ModelProtocols; sourceTree = ""; }; + 011D9583240422BF000E3791 /* New */ = { + isa = PBXGroup; + children = ( + 011D958A24042794000E3791 /* Rules */, + 011D95882404249B000E3791 /* FormProtocol.swift */, + 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */, + 011D95AA2405C553000E3791 /* FormItemProtocol.swift */, + 011D958624042492000E3791 /* FormFieldProtocol.swift */, + 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */, + 011D9601240DA20A000E3791 /* ValidProtocol.swift */, + ); + path = New; + sourceTree = ""; + }; + 011D958A24042794000E3791 /* Rules */ = { + isa = PBXGroup; + children = ( + 011D958424042432000E3791 /* RulesProtocol.swift */, + 011D959A240451E3000E3791 /* RuleRequiredModel.swift */, + 011D959C2404536F000E3791 /* RuleAnyModel.swift */, + 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */, + 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */, + 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, + 011D95A4240455DC000E3791 /* FormGroupRule.swift */, + ); + path = Rules; + sourceTree = ""; + }; 012A88EF23985E0100FE3DA1 /* CustomPrimitives */ = { isa = PBXGroup; children = ( @@ -768,6 +826,7 @@ 01C74D87224298E2009C25A3 /* FormUIHelpers */ = { isa = PBXGroup; children = ( + 011D9583240422BF000E3791 /* New */, 0198F79E225679870066C936 /* FormValidationProtocol.swift */, 0105618A224BBE7700E1557D /* FormValidator.swift */, 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */, @@ -1203,6 +1262,7 @@ D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */, D28A838423CCCA8900DFE4FC /* ScrollerModel.swift */, D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */, + 011D9625240EBB16000E3791 /* RadioButtonLabelModel.swift */, 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */, 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */, 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */, @@ -1217,6 +1277,7 @@ D29DF16021E69996003B2FB9 /* MFViewController.h */, D29DF15F21E69996003B2FB9 /* MFViewController.m */, 017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */, + 011D9627240EFA1E000E3791 /* MFViewController+Form.swift */, D29DF28F21E7ADB8003B2FB9 /* MFScrollingViewController.h */, D29DF29021E7ADB8003B2FB9 /* MFScrollingViewController.m */, D29DF29121E7ADB8003B2FB9 /* ProgrammaticScrollViewController.h */, @@ -1731,6 +1792,7 @@ D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, D2B18B7F2360913400A9AEDC /* Control.swift in Sources */, + 011D95A924057AC7000E3791 /* FormActionFieldProtocol.swift in Sources */, 0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */, D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */, 012A88C8238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift in Sources */, @@ -1744,9 +1806,11 @@ 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */, 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */, D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */, + 011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */, D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, + 011D9602240DA20A000E3791 /* ValidProtocol.swift in Sources */, D260106323D0C05000764D80 /* StackItemModel.swift in Sources */, D2E2A99823D8D63C000B42E6 /* ActionDetailWithImageModel.swift in Sources */, D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, @@ -1786,6 +1850,7 @@ AA11A42123F15D7000D7962F /* ListRightVariablePaymentsModel.swift in Sources */, 01EB369223609801006832FA /* MoleculeStackModel.swift in Sources */, 012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */, + 011D9626240EBB16000E3791 /* RadioButtonLabelModel.swift in Sources */, D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, 944589232385DA9600DE9FD4 /* ImageViewModel.swift in Sources */, D213347723843825008E41B3 /* Line.swift in Sources */, @@ -1801,6 +1866,7 @@ DBEFFA04225A829700230692 /* Label.swift in Sources */, D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */, 0A7EF85F23D8ABC500B2AAD1 /* MdnEntryFieldModel.swift in Sources */, + 011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */, 01509D952327ED1900EF99AA /* HeadlineBodyLinkToggle.swift in Sources */, 31BE15CB23D8924D00452370 /* CheckboxLabelModel.swift in Sources */, D260105523CEA7DC00764D80 /* MVMCoreUISwitch+Model.swift in Sources */, @@ -1844,6 +1910,7 @@ D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, 017BEB7B236763000024EF95 /* LineModel.swift in Sources */, 94C2D9A523872C350006CF46 /* LabelAttributeFontModel.swift in Sources */, + 011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */, 011D95AF2407266E000E3791 /* RadioButtonModel.swift in Sources */, 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */, D274CA332236A78900B01B62 /* FooterView.swift in Sources */, @@ -1856,6 +1923,7 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, + 011D958524042432000E3791 /* RulesProtocol.swift in Sources */, 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, @@ -1865,6 +1933,7 @@ 012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, 9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */, + 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */, D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */, @@ -1915,13 +1984,16 @@ 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, + 011D9628240EFA1E000E3791 /* MFViewController+Form.swift in Sources */, 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, 52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */, D26C5A6B23F4A40D007AEECE /* ListItemModel.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, + 011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, + 011D95892404249B000E3791 /* FormProtocol.swift in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, @@ -1950,6 +2022,7 @@ D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, 014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, + 011D959D2404536F000E3791 /* RuleAnyModel.swift in Sources */, D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */, C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, @@ -1958,6 +2031,7 @@ D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, + 011D95AB2405C553000E3791 /* FormItemProtocol.swift in Sources */, D21EE53C23AD3AD4003D1A30 /* NSLayoutConstraintAxis+Extension.swift in Sources */, C6FA7D5223C77A4A00A3614A /* UnOrderedList.swift in Sources */, 01509D8F2327EC6F00EF99AA /* MoleculeTableViewCell.swift in Sources */, @@ -1966,6 +2040,8 @@ D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */, C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */, D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */, + 011D959F240453A1000E3791 /* RuleValueChangeModel.swift in Sources */, + 011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */, 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */, 01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */, D260106523D0CEA700764D80 /* StackModel.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index f02eaf5c..77b7addc 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -18,7 +18,8 @@ public enum ButtonSize: String, Codable { case tiny } -public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { +public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormActionFieldProtocol { + public static var identifier: String = "button" public var backgroundColor: Color? public var title: String @@ -32,9 +33,15 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { public var disabledFillColor: Color? public var disabledTextColor: Color? public var disabledBorderColor: Color? - public var required: Bool? - public var requiredGroups: [String]? - + public var groupName: String? + + public func updateEnable(_ enabled: Bool) { + self.enabled = enabled + updateUI?() + } + + public var updateUI: (() -> Void)? + init(with title: String, action: ActionModelProtocol) { self.title = title self.action = action @@ -66,8 +73,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { case disabledFillColor case disabledTextColor case disabledBorderColor - case required - case requiredGroups + case groupName } required public init(from decoder: Decoder) throws { @@ -76,8 +82,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) - required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) - requiredGroups = try typeContainer.decodeIfPresent([String].self, forKey: .requiredGroups) + groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) if let style = try typeContainer.decodeIfPresent(ButtonStyle.self, forKey: .style) { self.style = style } @@ -110,7 +115,6 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol { try container.encodeIfPresent(disabledFillColor, forKey: .disabledFillColor) try container.encodeIfPresent(disabledTextColor, forKey: .disabledTextColor) try container.encodeIfPresent(disabledBorderColor, forKey: .disabledBorderColor) - try container.encodeIfPresent(required, forKey: .required) - try container.encodeIfPresent(requiredGroups, forKey: .requiredGroups) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atoms/Buttons/PillButton.swift b/MVMCoreUI/Atoms/Buttons/PillButton.swift index d7fa8db5..da8cf0c7 100644 --- a/MVMCoreUI/Atoms/Buttons/PillButton.swift +++ b/MVMCoreUI/Atoms/Buttons/PillButton.swift @@ -8,7 +8,7 @@ import UIKit -open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidationEnableDisableProtocol { +open class PillButton: Button, MVMCoreUIViewConstrainingProtocol { // Used to size the button. var size = MVMCoreUIUtility.getWidth() @@ -125,11 +125,12 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation guard let model = model as? ButtonModel else { return } setTitle(model.title, for: .normal) - - if let required = model.required, - required { - FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) + + model.updateUI = { [weak self] in + self?.enableField(model.enabled) } + + FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { @@ -163,17 +164,8 @@ open class PillButton: Button, MVMCoreUIViewConstrainingProtocol, FormValidation open func horizontalAlignment() -> UIStackView.Alignment { return .center } - - // MARK: - FormValidationEnableDisableProtocol - public func isValidationRequired() -> Bool { - return buttonModel?.required ?? false - } - - public func requiredGroups() -> [String]? { - return buttonModel?.requiredGroups - } public func enableField(_ enable: Bool) { - isEnabled = isValidationRequired() ? enable : true + isEnabled = enable } } diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift index 0e2368b8..f354ac85 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift @@ -16,13 +16,10 @@ extension PrimaryButton: ModelMoleculeViewProtocol { setTitle(model.title, for: .normal) backgroundColor = model.backgroundColor?.uiColor - self.validationRequired = model.required ?? false - self.requiredGroupsList = model.requiredGroups - - if self.validationRequired, - let selfForm = self as? FormValidationEnableDisableProtocol { - FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) - } +// if self.validationRequired, +// let selfForm = self as? FormValidationEnableDisableProtocol { +// FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) +// } if let style = model.style { switch style { diff --git a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift index e4a794bc..e9ca5e65 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift @@ -9,7 +9,8 @@ import Foundation -@objcMembers public class EntryFieldModel: MoleculeModelProtocol { +@objcMembers public class EntryFieldModel: MoleculeModelProtocol, FormFieldProtocol, ValidProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -26,8 +27,18 @@ import Foundation public var isLocked: Bool? public var isSelected: Bool? public var fieldKey: String? - public var isValid: Bool? public var isRequired: Bool? + public var text: String? + + public var isValid: Bool? { + didSet { + updateUI?() + } + } + public var updateUI: (() -> Void)? + public func setValidity(_ isValid: Bool) { + self.isValid = isValid + } //-------------------------------------------------- // MARK: - Keys @@ -45,6 +56,11 @@ import Foundation case fieldKey case isValid case isRequired = "required" + case text + } + + public func formFieldValue() -> Any? { + return text } //-------------------------------------------------- @@ -62,6 +78,7 @@ import Foundation isSelected = try typeContainer.decodeIfPresent(Bool.self, forKey: .isSelected) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid) + text = try typeContainer.decodeIfPresent(String.self, forKey: .text) } public func encode(to encoder: Encoder) throws { @@ -76,5 +93,6 @@ import Foundation try container.encode(isSelected, forKey: .isSelected) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(isValid, forKey: .isValid) + try container.encodeIfPresent(text, forKey: .text) } } diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift b/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift index e57cec9c..63e01b3a 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift +++ b/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift @@ -16,64 +16,64 @@ enum TextType: String { } extension MFTextField: ModelMoleculeViewProtocol { // - public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - //TODO: Need to create setWithModel in ViewConstraining View - #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.") - //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView. - setUpDefaultWithModel(model, delegateObject, additionalData) - - guard let textFieldModel = model as? TextFieldModel, - let delegateObject = delegateObject else { - return - } - - if let delegate = delegateObject.formValidationProtocol { - let formValidator = FormValidator.getFormValidatorFor(delegate: delegate) - mfTextFieldDelegate = formValidator - uiTextFieldDelegate = delegateObject.uiTextFieldDelegate - if let textField = textField { - MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) - } - } - - formText = textFieldModel.label as NSString? - text = textFieldModel.value as NSString? - if let disabled = textFieldModel.disabled { - enable(disabled) - } - errMessage = textFieldModel.errorMsg - fieldKey = textFieldModel.fieldKey - groupName = textFieldModel.groupName - - - switch textFieldModel.type { - case TextType.dropDown.rawValue: - dropDownCarrotLabel?.isHidden = true - hasDropDown = true - break - case TextType.password.rawValue: - textField?.isSecureTextEntry = true - break - case TextType.number.rawValue: - textField?.keyboardType = .numberPad - break - case TextType.email.rawValue: - textField?.keyboardType = .emailAddress - break - default: - print("default") - } - - if let regex = textFieldModel.regex { - validationBlock = {(enteredValue: String?) -> Bool in - if let enteredValue = enteredValue { - return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: regex) - } - return true - } - } else { - setDefaultValidationBlock() - } + public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { +// //TODO: Need to create setWithModel in ViewConstraining View +// #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.") +// //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView. +// setUpDefaultWithModel(model, delegateObject, additionalData) +// +// guard let textFieldModel = model as? TextFieldModel, +// let delegateObject = delegateObject else { +// return +// } +// +// if let delegate = delegateObject.formValidationProtocol { +// let formValidator = FormValidator.getFormValidatorFor(delegate: delegate) +// mfTextFieldDelegate = formValidator +// uiTextFieldDelegate = delegateObject.uiTextFieldDelegate +// if let textField = textField { +// MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) +// } +// } +// +// formText = textFieldModel.label as NSString? +// text = textFieldModel.value as NSString? +// if let disabled = textFieldModel.disabled { +// enable(disabled) +// } +// errMessage = textFieldModel.errorMsg +// fieldKey = textFieldModel.fieldKey +// groupName = textFieldModel.groupName +// +// +// switch textFieldModel.type { +// case TextType.dropDown.rawValue: +// dropDownCarrotLabel?.isHidden = true +// hasDropDown = true +// break +// case TextType.password.rawValue: +// textField?.isSecureTextEntry = true +// break +// case TextType.number.rawValue: +// textField?.keyboardType = .numberPad +// break +// case TextType.email.rawValue: +// textField?.keyboardType = .emailAddress +// break +// default: +// print("default") +// } +// +// if let regex = textFieldModel.regex { +// validationBlock = {(enteredValue: String?) -> Bool in +// if let enteredValue = enteredValue { +// return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: regex) +// } +// return true +// } +// } else { +// setDefaultValidationBlock() +// } } } diff --git a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift index a0a893a6..b42349c6 100644 --- a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift @@ -97,25 +97,25 @@ import MVMCore return MVMCoreUIUtility.validateInternationalMDNString(MDN) } - @objc public override func validateTextField() -> Bool { + @objc public override func validateTextField() { - guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else { - isValid = true - return true - } - - let isValid = hasValidMDN() - - if isValid { - showError = false - - } else { - errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") - showError = true - UIAccessibility.post(notification: .layoutChanged, argument: textField) - } - - return isValid +// guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else { +// isValid = true +// return true +// } +// +// let isValid = hasValidMDN() +// +// if isValid { +// showError = false +// +// } else { +// errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") +// showError = true +// UIAccessibility.post(notification: .layoutChanged, argument: textField) +// } +// +// return isValid } @objc public func getContacts(_ sender: Any?) { @@ -186,9 +186,9 @@ import MVMCore proprietorTextDelegate?.textFieldDidEndEditing?(textField) - if validateTextField() && isNationalMDN { - textField.text = MVMCoreUIUtility.formatMdn(textField.text) - } +// if validateTextField() && isNationalMDN { +// textField.text = MVMCoreUIUtility.formatMdn(textField.text) +// } } @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 61f6c82c..870d669a 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -49,7 +49,7 @@ import UIKit /// Validate when user resigns editing. Default: true public var validateWhenDoneEditing: Bool = true - + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -218,34 +218,33 @@ import UIKit @discardableResult @objc override open func resignFirstResponder() -> Bool { - if validateWhenDoneEditing { validateTextField() } - textField.resignFirstResponder() isSelected = false return true } /// Validates the text of the entry field. - @discardableResult - @objc public func validateTextField() -> Bool { - - isValid = validationBlock?(text) ?? true - + @objc public func validateTextField() { + text = textField.text + FormValidator.validate(delegate: delegateObject?.formHolderDelegate) + } + + @objc public func updateValidation(_ isValid: Bool) { + self.isValid = isValid if isValid { showError = false observingTextFieldDelegate?.isValid?(textfield: self) - + } else { showError = true observingTextFieldDelegate?.isInvalid?(textfield: self) } - - return isValid } - + + /// Executes on UITextField.textDidBeginEditingNotification @objc func startEditing() { @@ -263,17 +262,14 @@ import UIKit /// Executes on UITextField.textDidEndEditingNotification @objc func endInputing() { - + resignFirstResponder() if isValid { showError = false entryFieldContainer.bottomBar?.backgroundColor = UIColor.black.cgColor } - - resignFirstResponder() } @objc func dismissFieldInput(_ sender: Any?) { - resignFirstResponder() } @@ -281,9 +277,14 @@ import UIKit super.set(with: model, delegateObject, additionalData) guard let model = model as? TextEntryFieldModel else { return } - - FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - + + model.updateUI = { [weak self] in + if self?.isSelected ?? false { + self?.updateValidation(model.isValid ?? true) + } + } + self.delegateObject = delegateObject + FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate) textColor.enabled = model.enabledTextColor?.uiColor textColor.disabled = model.disabledTextColor?.uiColor text = model.text @@ -312,11 +313,9 @@ import UIKit defaultValidationBlock() } - if let formValidationProtocol = delegateObject?.formValidationProtocol { - observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol) - } - +// observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: delegateObject?.formHolderDelegate) uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate + observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) } } @@ -330,9 +329,7 @@ extension TextEntryField { guard let delegateObject = delegateObject, let dictionary = json else { return } - - FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol) - + if let enabledTextColorHex = dictionary["enabledTextColor"] as? String { textColor.enabled = UIColor.mfGet(forHex: enabledTextColorHex) } @@ -374,11 +371,9 @@ extension TextEntryField { defaultValidationBlock() } - if let formValidationProtocol = delegateObject.formValidationProtocol { - observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: formValidationProtocol) - } uiTextFieldDelegate = delegateObject.uiTextFieldDelegate + observingTextFieldDelegate = delegateObject.observingTextFieldDelegate MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) } } diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/TextEntryFieldModel.swift index 27b0e933..8b8e582e 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryFieldModel.swift @@ -16,7 +16,6 @@ return "textField" } - public var text: String? public var placeholder: String? public var enabledTextColor: Color? public var disabledTextColor: Color? diff --git a/MVMCoreUI/Atoms/Views/Checkbox.swift b/MVMCoreUI/Atoms/Views/Checkbox.swift index fd186d7e..a87c3e3e 100644 --- a/MVMCoreUI/Atoms/Views/Checkbox.swift +++ b/MVMCoreUI/Atoms/Views/Checkbox.swift @@ -127,9 +127,10 @@ import MVMCore didSet { if !updateSelectionOnly { layoutIfNeeded() + (model as? CheckboxModel)?.isChecked = isSelected shapeLayer?.removeAllAnimations() updateCheckboxUI(isSelected: isSelected, isAnimated: isAnimated) - FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol) + FormValidator.validate(delegate: delegateObject?.formHolderDelegate) updateAccessibilityLabel() } } @@ -397,76 +398,12 @@ import MVMCore //layoutIfNeeded() } - - public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - self.delegateObject = delegateObject - FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - - guard let dictionary = json else { return } - - groupName = dictionary.optionalStringForKey("groupName") - fieldValue = dictionary.optionalStringForKey("value") - if let fieldKey = dictionary[KeyFieldKey] as? String { - self.fieldKey = fieldKey - } - - if let isRequired = dictionary[KeyRequired] as? Bool { - self.isRequired = isRequired - } - - if let borderColorHex = dictionary["borderColor"] as? String { - layer.borderColor = UIColor.mfGet(forHex: borderColorHex).cgColor - } - - if let borderWidth = dictionary["borderWidth"] as? CGFloat { - layer.borderWidth = borderWidth - } - - if let checkColorHex = dictionary["checkColor"] as? String { - checkColor = UIColor.mfGet(forHex: checkColorHex) - } - - if let isChecked = dictionary["isChecked"] as? Bool, isChecked { - checkAndBypassAnimations(selected: isChecked) - } - - if let unCheckedBackgroundColorHex = dictionary["unCheckedBackgroundColor"] as? String { - unCheckedBackgroundColor = UIColor.mfGet(forHex: unCheckedBackgroundColorHex) - } - - if let checkedBackgroundColorHex = dictionary["checkedBackgroundColor"] as? String { - checkedBackgroundColor = UIColor.mfGet(forHex: checkedBackgroundColorHex) - } - - if let isAnimated = dictionary["isAnimated"] as? Bool { - self.isAnimated = isAnimated - } - - if let isRound = dictionary["isRound"] as? Bool { - self.isRound = isRound - } - - if let enabled = dictionary["isEnabled"] as? Bool { - isEnabled = enabled - } - - if let actionMap = dictionary.optionalDictionaryForKey("action") { - actionBlock = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } - } - } - + public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) - guard let model = model as? CheckboxModel else { return } - self.delegateObject = delegateObject - FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - - groupName = model.groupName - fieldValue = model.value - isRequired = model.required + FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate) if let fieldKey = model.fieldKey { self.fieldKey = fieldKey @@ -500,23 +437,3 @@ import MVMCore } } } - -// MARK:- FormValidationProtocol -extension Checkbox: FormValidationFormFieldProtocol { - - public func formFieldGroupName() -> String? { - return groupName - } - - public func isValidField() -> Bool { - return isRequired ? isSelected : true - } - - public func formFieldName() -> String? { - return fieldKey - } - - public func formFieldValue() -> Any? { - return isSelected ? fieldValue : nil - } -} diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift index 706597ff..60aade23 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxModel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -8,7 +8,8 @@ import Foundation -@objcMembers public class CheckboxModel: MoleculeModelProtocol { +@objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol { + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -16,10 +17,6 @@ import Foundation public static var identifier: String = "checkbox" public var backgroundColor: Color? - public var groupName: String? - public var value: String? - public var fieldKey: String? - public var required: Bool = false public var borderColor: Color = Color(uiColor: .black) public var borderWidth: CGFloat = 1 public var isChecked: Bool = false @@ -33,17 +30,16 @@ import Foundation public var disabledBackgroundColor: Color = Color(uiColor: .clear) public var disabledBorderColor: Color = Color(uiColor: .mvmCoolGray3) public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3) - + + public var fieldKey: String? + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { case moleculeName - case groupName - case value case fieldKey - case required case borderColor case borderWidth case isChecked @@ -61,16 +57,17 @@ import Foundation init(isChecked: Bool = false) {} + public func formFieldValue() -> Any? { + return isChecked + } + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) - value = try typeContainer.decodeIfPresent(String.self, forKey: .value) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) - required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) ?? false borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) ?? 1 borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor) ?? Color(uiColor: .black) checkColor = try typeContainer.decodeIfPresent(Color.self, forKey: .checkColor) ?? Color(uiColor: .black) @@ -89,10 +86,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) - try container.encodeIfPresent(groupName, forKey: .groupName) - try container.encodeIfPresent(value, forKey: .value) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) - try container.encodeIfPresent(required, forKey: .required) try container.encodeIfPresent(borderColor, forKey: .borderColor) try container.encode(borderWidth, forKey: .borderWidth) try container.encode(isChecked, forKey: .isChecked) diff --git a/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift b/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift index af14bc44..840a5d18 100644 --- a/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift +++ b/MVMCoreUI/Atoms/Views/MFView+ModelExtension.swift @@ -18,7 +18,7 @@ extension MFView { } extension ModelMoleculeViewProtocol where Self: MFView { - func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { setUpDefaultWithModel(model, delegateObject, additionalData) } } diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift index aeccf2ff..1b7ad307 100644 --- a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch+Model.swift @@ -13,10 +13,7 @@ extension MVMCoreUISwitch: ModelMoleculeViewProtocol { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { guard let model = model as? ToggleModel else { return } - if let castSelf = self as? FormValidationProtocol { - FormValidator.setupValidation(molecule: castSelf, delegate: delegateObject?.formValidationProtocol) - } - + FormValidator.setupValidation(molecule: model, delegate: delegateObject?.formHolderDelegate) setState(model.state, animated: false) guard let action = model.action else { return } diff --git a/MVMCoreUI/Atoms/Views/RadioButton.swift b/MVMCoreUI/Atoms/Views/RadioButton.swift index 47eeb0ca..f6484326 100644 --- a/MVMCoreUI/Atoms/Views/RadioButton.swift +++ b/MVMCoreUI/Atoms/Views/RadioButton.swift @@ -8,13 +8,14 @@ import UIKit -@objcMembers public class RadioButton: Control, FormValidationFormFieldProtocol { +@objcMembers public class RadioButton: Control { var diameter: CGFloat = 30 { didSet { widthConstraint?.constant = diameter } } + var enabledColor = UIColor.black var disabledColor = UIColor.mfSilver() @@ -27,15 +28,18 @@ import UIKit var widthConstraint: NSLayoutConstraint? var heightConstraint: NSLayoutConstraint? + var radioModel: RadioButtonModel? { + return model as? RadioButtonModel + } + lazy var radioGroupName: String? = { - [unowned self] in - return json?.optionalStringForKey("radioGroupName") ?? json?.optionalStringForKey("fieldKey") + [unowned self] in return radioModel?.radioGroupName ?? radioModel?.fieldKey }() - lazy var radioButtonModel: RadioButtonSelectionHelper? = { + lazy var radioButtonSelectionHelper: RadioButtonSelectionHelper? = { [unowned self] in if let radioGroupName = radioGroupName, - let radioButtonModel = delegateObject?.formValidationProtocol?.formValidatorModel?()?.radioButtonsModelByGroup[radioGroupName] { + let radioButtonModel = delegateObject?.formHolderDelegate?.formValidator?.radioButtonsModelByGroup[radioGroupName] { return radioButtonModel } else { return nil @@ -58,12 +62,12 @@ import UIKit /// The action performed when tapped. func tapAction() { - if let radioButtonModel = radioButtonModel { + if let radioButtonModel = radioButtonSelectionHelper { radioButtonModel.selected(self) } else { isSelected = !isSelected } - FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol) + FormValidator.validate(delegate: delegateObject?.formHolderDelegate) setNeedsDisplay() } @@ -72,15 +76,15 @@ import UIKit } public func formFieldName() -> String? { - return json?.optionalStringForKey("fieldKey") + return radioModel?.fieldKey } public func formFieldGroupName() -> String? { - return json?.optionalStringForKey("groupName") + return radioModel?.radioGroupName } - public func formFieldValue() -> Any? { - return isSelected + public func formFieldValue() -> String? { + return radioModel?.fieldValue } // MARK: - MVMViewProtocol @@ -104,40 +108,14 @@ import UIKit guard let model = model as? RadioButtonModel else { return } - setWithJSON(model.toJSON(), delegateObject: delegateObject, additionalData: additionalData) - } -} - -// MARK: - MVMCoreUIViewConstrainingProtocol -extension RadioButton: MVMCoreUIViewConstrainingProtocol { - public func needsToBeConstrained() -> Bool { - return true - } -} - -// MARK: - MVMCoreUIMoleculeViewProtocol -extension RadioButton { - - @objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - - // Configure class properties with JSON values - guard let jsonDictionary = json else { - return - } - - fieldKey = jsonDictionary.optionalStringForKey("fieldKey") - isRequired = jsonDictionary.boolForKey("required") self.delegateObject = delegateObject - - let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(radioButton: self, - formValidator: delegateObject?.formValidationProtocol?.formValidatorModel?()) - FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formValidationProtocol) + let radioButtonModel = RadioButtonSelectionHelper.setupForRadioButtonGroup(model, + formValidator: delegateObject?.formHolderDelegate?.formValidator) + FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formHolderDelegate) } public override func reset() { - super.reset() - backgroundColor = .white + super.reset() + backgroundColor = .white } } diff --git a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift index c8443691..a058ada6 100644 --- a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift +++ b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift @@ -9,9 +9,20 @@ import Foundation -public class RadioButtonModel: MoleculeModelProtocol { +public class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { + public static var identifier: String = "radioButton" public var backgroundColor: Color? - public var state: Bool = false + public var state: Bool? = false + public var radioGroupName: String? public var fieldKey: String? + public var fieldValue: String + public func formFieldValue() -> Any? { + return fieldValue + } + + init(_ fieldKey: String, _ fieldValue: String) { + self.fieldKey = fieldKey + self.fieldValue = fieldValue + } } diff --git a/MVMCoreUI/Atoms/Views/Toggle.swift b/MVMCoreUI/Atoms/Views/Toggle.swift index ee888b3f..c53b4be6 100644 --- a/MVMCoreUI/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atoms/Views/Toggle.swift @@ -101,7 +101,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) self.constrainKnob() } - FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol) + FormValidator.validate(delegate: delegateObject?.formHolderDelegate) accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff") setNeedsLayout() layoutIfNeeded() @@ -379,7 +379,7 @@ extension Toggle { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) self.delegateObject = delegateObject - FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) +// FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) guard let dictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Views/ToggleModel.swift b/MVMCoreUI/Atoms/Views/ToggleModel.swift index aafacec8..54c86514 100644 --- a/MVMCoreUI/Atoms/Views/ToggleModel.swift +++ b/MVMCoreUI/Atoms/Views/ToggleModel.swift @@ -8,7 +8,8 @@ import UIKit -public class ToggleModel: MoleculeModelProtocol { +public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { + public static var identifier: String = "toggle" public var backgroundColor: Color? public var state: Bool = true @@ -27,6 +28,10 @@ public class ToggleModel: MoleculeModelProtocol { case alternateAction } + public func formFieldValue() -> Any? { + return state + } + public init(_ state: Bool) { self.state = state } diff --git a/MVMCoreUI/BaseControllers/MFViewController+Form.swift b/MVMCoreUI/BaseControllers/MFViewController+Form.swift new file mode 100644 index 00000000..2c3b14bf --- /dev/null +++ b/MVMCoreUI/BaseControllers/MFViewController+Form.swift @@ -0,0 +1,22 @@ +// +// MFViewController+Form.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 3/3/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +extension MFViewController: ObservingTextFieldDelegate { +} + +public extension MFViewController { + @objc func startValidation() { + (self as? FormHolderProtocol)?.formValidator?.validate() + } + + @objc func addFormParams(requestParameters: MVMCoreRequestParameters) { + (self as? FormHolderProtocol)?.formValidator?.addFormParams(requestParameters: requestParameters) + } +} diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index f663193f..1af64e34 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -52,19 +52,10 @@ // title view for navigation bar, used for custom navigation titles @property (weak, nonatomic) UILabel *titleLabel; -@property (strong, nonatomic) FormValidator *formValidator; - @end @implementation MFViewController -- (FormValidator *)formValidatorModel { - if (self.formValidator == nil) { - self.formValidator = [FormValidator new]; - } - return self.formValidator; -} - - (void)dismiss { [MVMCoreDispatchUtility performBlockOnMainThread:^{ if (self.presentingViewController) { @@ -487,12 +478,13 @@ if (!self.disableAnimations) { [self setupIntroAnimations]; } + + [self startValidation]; } - (void)newDataBuildAndUpdate { [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self newDataBuildScreen]; - [self.formValidator enableByValidation]; self.needToUpdateUI = YES; [self.view setNeedsLayout]; }]; @@ -690,9 +682,8 @@ [[MVMCoreUISession sharedGlobal].splitViewController.rightPanel willOpenWithActionInformation:actionInformation]; } - [self.formValidator addFormParamsWithRequestParameters:requestParameters]; + [self addFormParamsWithRequestParameters:requestParameters]; requestParameters.parentPageType = [self.loadObject.pageJSON stringForKey:@"parentPageType"]; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:[self delegateObject]]; } diff --git a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift b/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift index 4c4945a4..97668df4 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift @@ -8,21 +8,3 @@ import Foundation -@objc public extension FormValidator { - @objc func addFormParams(requestParameters: MVMCoreRequestParameters) { - requestParameters.add(self.getFormParams()) - } - - @objc func getFormParams() -> [String: Any] { - var extraParam: [String: Any] = [:] - MVMCoreDispatchUtility.performSyncBlock(onMainThread: { - for molecule in self.fieldMolecules { - if let formFieldName = molecule.formFieldName(), - let formFieldValue = molecule.formFieldValue() { - extraParam[formFieldName] = formFieldValue - } - } - }) - return extraParam - } -} diff --git a/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift b/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift index 21599abf..0455b689 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift @@ -8,63 +8,62 @@ import Foundation -@objc extension FormValidator: MFTextFieldDelegate { - - public func dismissFieldInput(_ sender: Any?) { - - if let delegate = delegate as? MFTextFieldDelegate { - delegate.dismissFieldInput?(sender) - } - } - - public func entryIsValid(_ textfield: MFTextField?) { - - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.enableByValidation() - if let delegate = self.delegate as? MFTextFieldDelegate { - delegate.entryIsValid?(textfield) - } - }) - } - - public func entryIsInvalid(_ textfield: MFTextField?) { - - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.enableByValidation() - if let delegate = self.delegate as? MFTextFieldDelegate { - delegate.entryIsInvalid?(textfield) - } - }) - } -} - +//@objc extension FormValidator: MFTextFieldDelegate { +// +// public func dismissFieldInput(_ sender: Any?) { +// +// if let delegate = delegate as? MFTextFieldDelegate { +// delegate.dismissFieldInput?(sender) +// } +// } +// +// public func entryIsValid(_ textfield: MFTextField?) { +// +// MVMCoreDispatchUtility.performBlock(onMainThread: { +// self.enableByValidation() +// if let delegate = self.delegate as? MFTextFieldDelegate { +// delegate.entryIsValid?(textfield) +// } +// }) +// } +// +// public func entryIsInvalid(_ textfield: MFTextField?) { +// +// MVMCoreDispatchUtility.performBlock(onMainThread: { +// self.enableByValidation() +// if let delegate = self.delegate as? MFTextFieldDelegate { +// delegate.entryIsInvalid?(textfield) +// } +// }) +// } +//} +// // Temporary: Looking to either combine or separate entirely with MFTextFieldDelegate. -extension FormValidator: ObservingTextFieldDelegate { - - public func dismissField(_ sender: Any?) { - - if let delegate = delegate as? MFTextFieldDelegate { - delegate.dismissFieldInput?(sender) - } - } - - @nonobjc public func isValid(_ textfield: MFTextField?) { - - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.enableByValidation() - if let delegate = self.delegate as? MFTextFieldDelegate { - delegate.entryIsValid?(textfield) - } - }) - } - - public func isInvalid(_ textfield: MFTextField?) { - - MVMCoreDispatchUtility.performBlock(onMainThread: { - self.enableByValidation() - if let delegate = self.delegate as? MFTextFieldDelegate { - delegate.entryIsInvalid?(textfield) - } - }) - } -} +//extension FormValidator: ObservingTextFieldDelegate { +// +// public func dismissField(_ sender: Any?) { +// if let delegate = delegate as? MFTextFieldDelegate { +// delegate.dismissFieldInput?(sender) +// } +// } +// +// @nonobjc public func isValid(_ textfield: MFTextField?) { +// +// MVMCoreDispatchUtility.performBlock(onMainThread: { +// self.enableByValidation() +// if let delegate = self.delegate as? MFTextFieldDelegate { +// delegate.entryIsValid?(textfield) +// } +// }) +// } +// +// public func isInvalid(_ textfield: MFTextField?) { +// +// MVMCoreDispatchUtility.performBlock(onMainThread: { +// self.enableByValidation() +// if let delegate = self.delegate as? MFTextFieldDelegate { +// delegate.entryIsInvalid?(textfield) +// } +// }) +// } +//} diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index cff26347..fd4dd6e8 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -13,73 +13,81 @@ import MVMCore var extraValidationBlock: (() -> Bool)? var dummyGroupName = "dummyGroupName" - weak var delegate: FormValidationProtocol? - var fieldMolecules: [FormValidationFormFieldProtocol] = [] - var enableDisableMolecules: [FormValidationEnableDisableProtocol] = [] + + var formRules: [FormGroupRule] + var delegate: FormHolderProtocol? + var fieldMolecules: [FormFieldProtocol] = [] + var formActionMolecules: [FormActionFieldProtocol] = [] var radioButtonsModelByGroup: [String: RadioButtonSelectionHelper] = [:] - - public func insertMolecule(_ molecule: FormValidationProtocol) { - if let molecule = molecule as? FormValidationFormFieldProtocol { - fieldMolecules.append(molecule) - } - if let moleculeT = molecule as? FormValidationEnableDisableProtocol, - moleculeT.isValidationRequired() { - enableDisableMolecules.append(moleculeT) - } + + public init(_ formRules: [FormGroupRule]) { + self.formRules = formRules } - public static func enableByValidationWith(delegate: FormValidationProtocol?) { - if let delegate = delegate { - let formValidator = FormValidator.getFormValidatorFor(delegate: delegate) - formValidator?.enableByValidation() + public func insertMolecule(_ molecule: FormItemProtocol) { + if let molecule = molecule as? FormFieldProtocol { + fieldMolecules.append(molecule) + } + if let molecule = molecule as? FormActionFieldProtocol { + formActionMolecules.append(molecule) } } - public static func getFormValidatorFor(delegate: FormValidationProtocol) -> FormValidator? { - return delegate.formValidatorModel?() - } - - public static func setupValidation(molecule: FormValidationProtocol, delegate: FormValidationProtocol?) { - if let validator = delegate?.formValidatorModel?() { + public static func setupValidation(molecule: FormItemProtocol, delegate: FormHolderProtocol?) { + if let validator = delegate?.formValidator { validator.delegate = delegate validator.insertMolecule(molecule) } } - public func enableByValidation() { - for molecule in enableDisableMolecules { - var requiredGroups = molecule.requiredGroups?() ?? [dummyGroupName] - if requiredGroups.count == 0 { - requiredGroups = [dummyGroupName] - } - enableWithGroups(requiredGroups, molecule) - } + public static func getFormValidatorFor(delegate: FormHolderProtocol?) -> FormValidator? { + return delegate?.formValidator } - - public func enableWithGroups(_ requiredGroupList: [String], _ enableDisableMolecule: FormValidationEnableDisableProtocol) { - let requiredGroupSet = Set(requiredGroupList) - var valid = true - for molecule in fieldMolecules { - let groupName = molecule.formFieldGroupName() ?? dummyGroupName - if requiredGroupSet.contains(groupName) { - valid = valid && molecule.isValidField() - if valid == false { - break - } + + public static func validate(delegate: FormHolderProtocol?) { + delegate?.formValidator?.validate() + } + + public func validate() { + formActionMolecules.forEach { (actionModel) in + if let groupName = actionModel.groupName, let formRule = formRules.first(where: { $0.groupName == groupName }) { + validate(groupName, actionModel, formRule.rules) } } - enableDisableMolecule.enableField?(valid) } - - public func enableIgnoreGroupName(_ enableDisableMolecules: FormValidationEnableDisableProtocol) { + + public func validate(_ groupName: String, _ actionModel: FormActionFieldProtocol, _ rules: [RulesProtocol]) { var valid = true - for molecule in fieldMolecules { - valid = valid && molecule.isValidField() - if (!valid) { + for rule in rules { + valid = valid && rule.isValid(self) + if !valid { break } } - let enableField = valid && (extraValidationBlock?() ?? true) - enableDisableMolecules.enableField?(enableField) + actionModel.updateEnable(valid) + } + + public func formField(for fieldKey: String) -> FormFieldProtocol? { + return fieldMolecules.first(where: { $0.fieldKey == fieldKey }) + } +} + +// mark Form params +@objc public extension FormValidator { + @objc func addFormParams(requestParameters: MVMCoreRequestParameters) { + requestParameters.add(self.getFormParams()) + } + + @objc func getFormParams() -> [String: Any] { + var extraParam: [String: Any] = [:] + MVMCoreDispatchUtility.performSyncBlock(onMainThread: { + for molecule in self.fieldMolecules { + if let formFieldName = molecule.fieldKey, + let formFieldValue = molecule.formFieldValue() { + extraParam[formFieldName] = formFieldValue + } + } + }) + return extraParam } } diff --git a/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift new file mode 100644 index 00000000..2f4b758d --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift @@ -0,0 +1,15 @@ +// +// FormActionFieldProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 1/31/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol FormActionFieldProtocol: EnableableModelProtocol, FormItemProtocol { + var groupName: String? { get set } + func updateEnable(_ enabled: Bool) + var updateUI: (() -> Void)? { get set } +} diff --git a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift new file mode 100644 index 00000000..d6073943 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift @@ -0,0 +1,15 @@ +// +// FormFieldProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 1/31/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public protocol FormFieldProtocol: FormItemProtocol { + var fieldKey: String? { get set } + func formFieldValue() -> Any? +} diff --git a/MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift new file mode 100644 index 00000000..57c41a21 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift @@ -0,0 +1,17 @@ +// +// FormHolderProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/26/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +//Protocol for Validation +public protocol FormHolderProtocol: NSObjectProtocol { + var formValidator: FormValidator? { get set } + /// Should call formValidator's validate method + func validate() +} diff --git a/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift new file mode 100644 index 00000000..47911f0c --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift @@ -0,0 +1,13 @@ +// +// FormItemProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/25/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol FormItemProtocol { + +} diff --git a/MVMCoreUI/FormUIHelpers/New/FormProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormProtocol.swift new file mode 100644 index 00000000..bef7f547 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/FormProtocol.swift @@ -0,0 +1,15 @@ +// +// Validatable.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/5/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +//Protocol for Validation +public protocol FormProtocol: class { + var formRules: [FormGroupRule]? { get set } + var formValidator: FormValidator? { get set } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift new file mode 100644 index 00000000..bc3bd023 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift @@ -0,0 +1,49 @@ +// +// FormRule.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +extension KeyedDecodingContainer where Key: CodingKey { + /// Decodes the list of molecule models with the given coding key based on moleculeName + public func decodeFormRules(codingKey: KeyedDecodingContainer.Key) throws -> [RulesProtocol] { + guard let models = try decodeModels(codingKey: codingKey, typeCodingKey: RulesCodingKey.ruleType) as? [RulesProtocol] else { + throw ModelRegistry.Error.decoderError + } + return models + } +} + + +open class FormGroupRule: Codable { +// public static var identifier: String = "formRule" + var groupName: String + var rules: [RulesProtocol] + + init(_ groupName: String, _ rules: [RulesProtocol]) { + self.groupName = groupName + self.rules = rules + } + + private enum CodingKeys: String, CodingKey { + case groupName + case rules + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + self.groupName = try typeContainer.decode(String.self, forKey: .groupName) + self.rules = try typeContainer.decodeFormRules(codingKey: .rules) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(groupName, forKey: .groupName) + try container.encodeModels(rules, forKey: .rules) + } +} + diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift new file mode 100644 index 00000000..3e10b7af --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift @@ -0,0 +1,20 @@ +// +// RuleAnyModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class RuleAnyModel: RulesProtocol { + + public static var identifier: String = "any" + public var ruleType: String = RuleAnyModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift new file mode 100644 index 00000000..7d1532d8 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift @@ -0,0 +1,20 @@ +// +// RuleEqualsModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public class RuleEqualsModel: RulesProtocol { + public static var identifier: String = "equals" + public var ruleType: String = RuleEqualsModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift new file mode 100644 index 00000000..9ef00426 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift @@ -0,0 +1,19 @@ +// +// RuleRegexModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class RuleRegexModel: RulesProtocol { + public static var identifier: String = "regex" + public var ruleType: String = RuleRegexModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift new file mode 100644 index 00000000..400c5b1b --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift @@ -0,0 +1,30 @@ +// +// FormFieldRuleRequiredModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public class RuleRequiredModel: RulesProtocol { + + public static var identifier: String = "required" + public var ruleType: String = RuleRequiredModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + guard let value = formField.formFieldValue() else { + return false + } + var valid = true + if let valueString = value as? String { + valid = valueString.count > 3 + } else if let valueBool = value as? Bool { + valid = valueBool + } + return valid + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift new file mode 100644 index 00000000..221c4b5d --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift @@ -0,0 +1,20 @@ +// +// RuleValueChangeModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class RuleValueChangeModel: RulesProtocol { + + public static var identifier: String = "valueChanged" + public var ruleType: String = RuleAnyModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return false + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift new file mode 100644 index 00000000..97485d66 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift @@ -0,0 +1,61 @@ +// +// FormBaseRulesProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 1/31/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + + +public enum RulesCodingKey: String, CodingKey { + case ruleType +} + +public protocol RulesProtocol: ModelProtocol { + var ruleType: String { get set } + var fields: [String] { get set } + func isValid(_ formValidator: FormValidator) -> Bool + func isValid(_ formField: FormFieldProtocol) -> Bool + func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) +} + +public extension RulesProtocol { + + var ruleType: String? { + get { return Self.identifier } + } + + static var categoryCodingKey: String { + return "ruleType" + } + + static var categoryName: String { + return "\(RulesProtocol.self)" + } + + func isValid(_ formValidator: FormValidator) -> Bool { + var valid = true + for formKey in fields { + guard let formField = formValidator.formField(for: formKey) else { + continue + } + valid = valid && isValid(formField) + if !valid { + setValid(formField, valid) + break + } else { + setValid(formField, valid) + } + } + return valid + } + + func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) { + guard let formFieldValid = formField as? ValidProtocol else { + return + } + formFieldValid.setValidity(isValid) + } +} diff --git a/MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift b/MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift new file mode 100644 index 00000000..20afd256 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift @@ -0,0 +1,15 @@ +// +// ValidProtocol.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 3/2/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol ValidProtocol { + var isValid: Bool? { get set } + func setValidity(_ isValid: Bool) + var updateUI: (() -> Void)? { get set } +} diff --git a/MVMCoreUI/Legacy/Views/MFTextField.m b/MVMCoreUI/Legacy/Views/MFTextField.m index fec796bf..691e6677 100644 --- a/MVMCoreUI/Legacy/Views/MFTextField.m +++ b/MVMCoreUI/Legacy/Views/MFTextField.m @@ -560,11 +560,11 @@ - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { - [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; - FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol]; +// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; +// FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol]; [self setWithMap:json]; - self.mfTextFieldDelegate = formValidator; +// self.mfTextFieldDelegate = formValidator; self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate; [MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate]; } diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m index 40fa987f..cfa1d20b 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m @@ -60,7 +60,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0; - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; +// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; self.delegateObject = delegateObject; self.fieldKey = [json stringForKey:KeyFieldKey]; @@ -350,7 +350,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0; [self.checkMark updateCheckSelected:NO animated:animated]; } - [FormValidator enableByValidationWithDelegate:self.delegateObject.formValidationProtocol]; +// [FormValidator enableByValidationWithDelegate:self.delegateObject.formValidationProtocol]; } - (void)setColor:(nullable UIColor *)color forState:(UIControlState)state { diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m index 1c40bc5a..c12e70a5 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m @@ -147,7 +147,7 @@ const CGFloat SwitchShakeIntensity = 2; self.json = json; self.delegate = delegateObject; - [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; +// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; NSString *color = [json string:@"onTintColor"]; if (color) { @@ -339,12 +339,11 @@ const CGFloat SwitchShakeIntensity = 2; [self setState:state withoutBlockAnimated:animated]; if (self.valueChangedBlock) { self.valueChangedBlock(); - } - - if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) { - FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)]; - [formValidator enableByValidation]; - } + } +// if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) { +// FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)]; +// [formValidator enableByValidation]; +// } } - (void)setState:(BOOL)state withoutBlockAnimated:(BOOL)animated { diff --git a/MVMCoreUI/Legacy/Views/PrimaryButton.m b/MVMCoreUI/Legacy/Views/PrimaryButton.m index 439d5479..f39edefc 100644 --- a/MVMCoreUI/Legacy/Views/PrimaryButton.m +++ b/MVMCoreUI/Legacy/Views/PrimaryButton.m @@ -671,7 +671,7 @@ self.validationRequired = [json boolForKey:@"required"]; self.requiredGroupsList = [json array:@"requiredGroups"]; - [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; +// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; self.primaryButtonType = PrimaryButtonTypeCustom; NSString *style = [json string:@"style"]; diff --git a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift index 3ed37d6b..a981ec64 100644 --- a/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Models/ModelProtocols/TemplateModelProtocol.swift @@ -9,7 +9,7 @@ import Foundation -public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol { +public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, FormProtocol { var template: String { get } } diff --git a/MVMCoreUI/Molecules/RadioButtonLabel.swift b/MVMCoreUI/Molecules/RadioButtonLabel.swift index e889b4f2..0db4e191 100644 --- a/MVMCoreUI/Molecules/RadioButtonLabel.swift +++ b/MVMCoreUI/Molecules/RadioButtonLabel.swift @@ -8,7 +8,7 @@ import UIKit -@objcMembers public class RadioButtonLabel: ViewConstrainingView { +@objcMembers public class RadioButtonLabel: View { public let radioButton = RadioButton() var delegateObject: MVMCoreUIDelegateObject? @@ -65,26 +65,12 @@ import UIKit let rightView = ViewConstrainingView(constrainingView: label) return rightView } -} - -// MARK: - MVMCoreUIMoleculeViewProtocol -extension RadioButtonLabel { - @objc open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - self.delegateObject = delegateObject - radioButton.setWithJSON(json?.optionalDictionaryForKey("radioButton"), delegateObject: delegateObject, additionalData: additionalData) - label.setWithJSON(json?.optionalDictionaryForKey(KeyLabel), - delegateObject: delegateObject, - additionalData: additionalData) - } - - public override func reset() { - super.reset() - radioButton.reset() - label.reset() - } - - public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { - return 45 - } + + open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let radioButtonLabelModel = model as? RadioButtonLabelModel else { return } + + radioButton.set(with: radioButtonLabelModel.radioButton, delegateObject, additionalData) + label.set(with: radioButtonLabelModel.label, delegateObject, additionalData) + } + } diff --git a/MVMCoreUI/Molecules/RadioButtonLabelModel.swift b/MVMCoreUI/Molecules/RadioButtonLabelModel.swift new file mode 100644 index 00000000..28a0f558 --- /dev/null +++ b/MVMCoreUI/Molecules/RadioButtonLabelModel.swift @@ -0,0 +1,17 @@ +// +// RadioButtonLabelModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 3/3/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers public class RadioButtonLabelModel: MoleculeModelProtocol { + public static var identifier: String = "radioButtonLabel" + public var backgroundColor: Color? + + public var radioButton: RadioButtonModel + public var label: LabelModel +} diff --git a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift index f20ac3b2..7505fca1 100644 --- a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift @@ -9,21 +9,25 @@ import Foundation import UIKit -@objcMembers public class RadioButtonSelectionHelper: NSObject { - +@objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol { + public var fieldKey: String? private var selectedRadioButton: RadioButton? private var fieldGroupName: String? + + init(_ fieldKey: String?) { + self.fieldKey = fieldKey + } - public static func setupForRadioButtonGroup(radioButton: RadioButton, formValidator: FormValidator?) -> RadioButtonSelectionHelper { - guard let groupName = radioButton.radioGroupName, + public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, formValidator: FormValidator?) -> RadioButtonSelectionHelper { + guard let groupName = radioButtonModel.radioGroupName ?? radioButtonModel.fieldKey, let formValidator = formValidator else { - return RadioButtonSelectionHelper() + return RadioButtonSelectionHelper(radioButtonModel.fieldKey) } - let radioButtonModel = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper() - radioButtonModel.fieldGroupName = radioButton.formFieldGroupName() - formValidator.radioButtonsModelByGroup[groupName] = radioButtonModel - return radioButtonModel + let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey) + radioButtonSelectionHelper.fieldGroupName = radioButtonModel.radioGroupName + formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper + return radioButtonSelectionHelper } public func selected(_ radioButton: RadioButton) { @@ -34,21 +38,12 @@ import UIKit } // MARK: - FormValidationFormFieldProtocol -extension RadioButtonSelectionHelper: FormValidationFormFieldProtocol { +extension RadioButtonSelectionHelper { public func formFieldGroupName() -> String? { return selectedRadioButton?.formFieldGroupName() ?? self.fieldGroupName } - // Used to check the validity of the field, to enable/disable the primary button. - @objc public func isValidField() -> Bool { - return selectedRadioButton != nil ? true : false - } - // Name of the field to send to server - @objc public func formFieldName() -> String? { - return selectedRadioButton?.fieldKey - } - // The field value key value pair for sending to server - @objc public func formFieldValue() -> Any? { - return selectedRadioButton != nil ? true : false + public func formFieldValue() -> Any? { + return selectedRadioButton?.formFieldValue() } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift index f64162db..54de3802 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift @@ -9,16 +9,18 @@ import UIKit open class MVMCoreUIDelegateObject: DelegateObject { - public weak var formValidationProtocol: FormValidationProtocol? + public weak var formHolderDelegate: FormHolderProtocol? public weak var buttonDelegate: ButtonDelegateProtocol? public weak var uiTextFieldDelegate: UITextFieldDelegate? + public weak var observingTextFieldDelegate: ObservingTextFieldDelegate? public var moleculeDelegate: MoleculeDelegateProtocol? open override func setAll(withDelegate delegate: Any) { super.setAll(withDelegate: delegate) - formValidationProtocol = delegate as? FormValidationProtocol + formHolderDelegate = delegate as? FormHolderProtocol buttonDelegate = delegate as? ButtonDelegateProtocol uiTextFieldDelegate = delegate as? UITextFieldDelegate + observingTextFieldDelegate = delegate as? ObservingTextFieldDelegate moleculeDelegate = delegate as? MoleculeDelegateProtocol } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 34da2080..ae8f19fe 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -51,8 +51,9 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Toggle.self, viewModelClass: ToggleModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Checkbox.self, viewModelClass: CheckboxModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: CheckboxLabel.self, viewModelClass: CheckboxLabelModel.self) - MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Arrow.self, viewModelClass: ArrowModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: RadioButton.self, viewModelClass: RadioButtonModel.self) + MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: RadioButtonLabel.self, viewModelClass: RadioButtonLabelModel.self) // Horizontal Combination Molecules MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: StringAndMoleculeView.self, viewModelClass: StringAndMoleculeModel.self) @@ -113,10 +114,16 @@ import Foundation MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(DateDropdownEntryField.self, forKey: "dateDropdownEntryField" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(Checkbox.self, forKey: "checkbox" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(CheckboxLabel.self, forKey: "checkboxLabel" as NSString) - MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(RadioButtonLabel.self, forKey: "radioButtonLabel" as NSString) MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping.setObject(MVMCoreUIPageControl.self, forKey: "barsPager" as NSString) // TODO: Need View try? ModelRegistry.register(TabsModel.self) + + // Helper models + try? ModelRegistry.register(RuleRequiredModel.self) + try? ModelRegistry.register(RuleAnyModel.self) + try? ModelRegistry.register(RuleValueChangeModel.self) + try? ModelRegistry.register(RuleEqualsModel.self) + try? ModelRegistry.register(RuleRegexModel.self) } } diff --git a/MVMCoreUI/Templates/ListPageTemplateModel.swift b/MVMCoreUI/Templates/ListPageTemplateModel.swift index 4ce4c6f5..5f8da7fc 100644 --- a/MVMCoreUI/Templates/ListPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ListPageTemplateModel.swift @@ -9,6 +9,10 @@ import Foundation @objcMembers public class ListPageTemplateModel: TemplateModelProtocol { + + public var formRules: [FormGroupRule]? + public var formValidator: FormValidator? + //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -47,6 +51,7 @@ import Foundation case footer case line case isAtomicTabs + case formRules } //-------------------------------------------------- @@ -62,6 +67,7 @@ import Foundation header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) + formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) } public func encode(to encoder: Encoder) throws { @@ -73,6 +79,7 @@ import Foundation try container.encodeModelIfPresent(header, forKey: .header) try container.encodeModelIfPresent(footer, forKey: .footer) try container.encode(line, forKey: .line) + try container.encodeIfPresent(formRules, forKey: .formRules) } } diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 33d6beb0..360fc86e 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -12,7 +12,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //-------------------------------------------------- // MARK: - Stored Properties //-------------------------------------------------- - + + public var formValidator: FormValidator? + public func validate() { + + } + public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? var observer: NSKeyValueObservation? diff --git a/MVMCoreUI/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Templates/MoleculeStackTemplate.swift index e05a067a..6a895120 100644 --- a/MVMCoreUI/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeStackTemplate.swift @@ -9,6 +9,11 @@ import UIKit open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol { + public func validate() { + + } + + public var formValidator: FormValidator? var observer: NSKeyValueObservation? public var templateModel: StackPageTemplateModel? diff --git a/MVMCoreUI/Templates/StackCenteredPageTemplateModel.swift b/MVMCoreUI/Templates/StackCenteredPageTemplateModel.swift index 86c09b6d..66cd0365 100644 --- a/MVMCoreUI/Templates/StackCenteredPageTemplateModel.swift +++ b/MVMCoreUI/Templates/StackCenteredPageTemplateModel.swift @@ -10,8 +10,35 @@ import Foundation @objcMembers public class StackCenteredPageTemplateModel: TemplateModelProtocol { + public var formRules: [FormGroupRule]? + public var formValidator: FormValidator? + public static var identifier: String = "stackCenterTemplate" public var pageType: String public var screenHeading: String? public var isAtomicTabs: Bool? + + public init(pageType: String) { + self.pageType = pageType + } + + private enum CodingKeys: String, CodingKey { + case pageType + case screenHeading + case isAtomicTabs + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + pageType = try typeContainer.decode(String.self, forKey: .pageType) + screenHeading = try typeContainer.decodeIfPresent(String.self, forKey: .screenHeading) + isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(pageType, forKey: .pageType) + try container.encodeIfPresent(screenHeading, forKey: .screenHeading) + try container.encodeIfPresent(isAtomicTabs, forKey: .isAtomicTabs) + } } diff --git a/MVMCoreUI/Templates/StackPageTemplateModel.swift b/MVMCoreUI/Templates/StackPageTemplateModel.swift index 10a2cf6f..1e5541eb 100644 --- a/MVMCoreUI/Templates/StackPageTemplateModel.swift +++ b/MVMCoreUI/Templates/StackPageTemplateModel.swift @@ -10,6 +10,9 @@ import Foundation @objcMembers public class StackPageTemplateModel: TemplateModelProtocol { + public var formRules: [FormGroupRule]? + public var formValidator: FormValidator? + public static var identifier: String = "stack" public var pageType: String @@ -32,6 +35,7 @@ import Foundation case footer case stack case isAtomicTabs + case formRules } required public init(from decoder: Decoder) throws { @@ -42,6 +46,7 @@ import Foundation isAtomicTabs = try typeContainer.decodeIfPresent(Bool.self, forKey: .isAtomicTabs) header = try typeContainer.decodeMoleculeIfPresent(codingKey: .header) footer = try typeContainer.decodeMoleculeIfPresent(codingKey: .footer) + formRules = try typeContainer.decodeIfPresent([FormGroupRule].self, forKey: .formRules) } public func encode(to encoder: Encoder) throws { @@ -52,5 +57,6 @@ import Foundation try container.encodeIfPresent(isAtomicTabs, forKey: .isAtomicTabs) try container.encodeModelIfPresent(header, forKey: .header) try container.encodeModelIfPresent(footer, forKey: .footer) + try container.encodeIfPresent(formRules, forKey: .formRules) } } diff --git a/MVMCoreUI/Templates/TemplateProtocol.swift b/MVMCoreUI/Templates/TemplateProtocol.swift index 63c66263..1e3dbdcc 100644 --- a/MVMCoreUI/Templates/TemplateProtocol.swift +++ b/MVMCoreUI/Templates/TemplateProtocol.swift @@ -8,18 +8,22 @@ import Foundation -public protocol TemplateProtocol: class { + +public protocol TemplateProtocol: FormHolderProtocol { associatedtype TemplateModel: TemplateModelProtocol var templateModel: TemplateModel? { get set } } public extension TemplateProtocol where Self: MFViewController { - func parseTemplateJSON() throws { guard let pageJSON = self.loadObject?.pageJSON else { return } let data = try JSONSerialization.data(withJSONObject: pageJSON) let decoder = JSONDecoder() let templateModel = try decoder.decode(TemplateModel.self, from: data) + + if self.formValidator == nil, let rules = templateModel.formRules { + self.formValidator = FormValidator(rules) + } self.templateModel = templateModel } } diff --git a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift index 689a7c62..d22b6675 100644 --- a/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift +++ b/MVMCoreUI/Templates/ThreeLayerPageTemplateModel.swift @@ -9,6 +9,10 @@ import Foundation @objcMembers public class ThreeLayerPageTemplateModel: TemplateModelProtocol { + + public var formRules: [FormGroupRule]? + public var formValidator: FormValidator? + public static var identifier: String = "threeLayer" public var pageType: String diff --git a/MVMCoreUI/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Templates/ThreeLayerTemplate.swift index eb822279..148d102d 100644 --- a/MVMCoreUI/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Templates/ThreeLayerTemplate.swift @@ -9,6 +9,11 @@ import UIKit @objcMembers open class ThreeLayerTemplate: ThreeLayerViewController, TemplateProtocol { + public func validate() { + + } + + public var formValidator: FormValidator? public var templateModel: ThreeLayerPageTemplateModel? From 9d8953d229304f08ee4437974dedb5f71096ceb8 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 4 Mar 2020 10:52:40 -0500 Subject: [PATCH 02/19] clean up --- MVMCoreUI.xcodeproj/project.pbxproj | 8 -- MVMCoreUI/Atoms/TextFields/EntryField.swift | 27 ----- MVMCoreUI/Atoms/Views/Toggle.swift | 110 +++++++----------- MVMCoreUI/BaseControllers/MFViewController.m | 2 +- .../FormValidationProtocol.swift | 41 ------- .../FormValidator+FormParams.swift | 10 -- MVMCoreUI/Legacy/Views/MFTextField.m | 27 +---- MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m | 19 +-- MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m | 20 +--- MVMCoreUI/Legacy/Views/PrimaryButton.m | 20 +--- 10 files changed, 50 insertions(+), 234 deletions(-) delete mode 100644 MVMCoreUI/FormUIHelpers/FormValidationProtocol.swift delete mode 100644 MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index d15c400c..3dd1fad9 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ 0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */; }; 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; }; 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; }; - 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; }; 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */; }; 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */; }; 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */; }; @@ -64,7 +63,6 @@ 017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */; }; 017BEB7B236763000024EF95 /* LineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7A236763000024EF95 /* LineModel.swift */; }; 017BEB7F23676E870024EF95 /* MoleculeObjectMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */; }; - 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; }; @@ -381,7 +379,6 @@ 0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyToggleModel.swift; sourceTree = ""; }; 0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = ""; }; 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = ""; }; - 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = ""; }; 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonSelectionHelper.swift; sourceTree = ""; }; 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModelProtocol.swift; sourceTree = ""; }; 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownListItemModel.swift; sourceTree = ""; }; @@ -434,7 +431,6 @@ 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeViewProtocol.swift; sourceTree = ""; }; 017BEB7A236763000024EF95 /* LineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineModel.swift; sourceTree = ""; }; 017BEB7E23676E870024EF95 /* MoleculeObjectMapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeObjectMapping.swift; sourceTree = ""; }; - 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; 01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = ""; }; @@ -827,9 +823,7 @@ isa = PBXGroup; children = ( 011D9583240422BF000E3791 /* New */, - 0198F79E225679870066C936 /* FormValidationProtocol.swift */, 0105618A224BBE7700E1557D /* FormValidator.swift */, - 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */, 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */, ); path = FormUIHelpers; @@ -1896,7 +1890,6 @@ 0A7EF85D23D8A95600B2AAD1 /* TextEntryFieldModel.swift in Sources */, D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */, 01EB368F23609801006832FA /* LabelModel.swift in Sources */, - 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */, 01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */, 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */, 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */, @@ -1966,7 +1959,6 @@ 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */, D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */, D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, - 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */, D243859923A16B1800332775 /* Container.swift in Sources */, D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */, D260105B23D0BB7100764D80 /* StackModelProtocol.swift in Sources */, diff --git a/MVMCoreUI/Atoms/TextFields/EntryField.swift b/MVMCoreUI/Atoms/TextFields/EntryField.swift index bbea1c62..43a15a3b 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryField.swift @@ -48,8 +48,6 @@ import UIKit //-------------------------------------------------- public var isValid: Bool = false - public var fieldKey: String? - public var errorMessage: String? public var standardMessage: String? { didSet { @@ -259,10 +257,6 @@ import UIKit } else if let isSelected = model.isSelected{ self.isSelected = isSelected } - - if let fieldKey = model.fieldKey { - self.fieldKey = fieldKey - } } } @@ -300,11 +294,6 @@ extension EntryField { if let isSelected = dictionary["isSelected"] as? Bool { self.isSelected = isSelected } - - // Key used to send text value to server - if let fieldKey = dictionary[KeyFieldKey] as? String { - self.fieldKey = fieldKey - } } @objc open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { @@ -312,22 +301,6 @@ extension EntryField { } } -// MARK: - Form Validation -extension EntryField: FormValidationProtocol { - - @objc public func isValidField() -> Bool { - return isValid - } - - @objc public func formFieldName() -> String? { - return fieldKey - } - - @objc public func formFieldValue() -> Any? { - return text - } -} - // MARK: - Accessibility extension EntryField { diff --git a/MVMCoreUI/Atoms/Views/Toggle.swift b/MVMCoreUI/Atoms/Views/Toggle.swift index c53b4be6..d6082292 100644 --- a/MVMCoreUI/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atoms/Views/Toggle.swift @@ -19,7 +19,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) Container: The background of the toggle control. Knob: The circular indicator that slides on the container. */ -@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol, FormValidationFormFieldProtocol { +@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -339,82 +339,60 @@ public typealias ActionBlockConfirmation = () -> (Bool) return } + self.delegateObject = delegateObject let toggleModelJSON = toggleModel.toJSON() + + FormValidator.setupValidation(molecule: toggleModel, delegate: delegateObject?.formHolderDelegate) setWithJSON(toggleModelJSON, delegateObject: delegateObject, additionalData: additionalData) } + + //TODO: change to setWith Model + public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + + guard let dictionary = json else { return } + + if let color = dictionary["onTintColor"] as? String { + containerTintColor?.on = UIColor.mfGet(forHex: color) + } + + if let color = dictionary["offTintColor"] as? String { + containerTintColor?.off = UIColor.mfGet(forHex: color) + } + + if let color = dictionary["onKnobTintColor"] as? String { + knobTintColor?.on = UIColor.mfGet(forHex: color) + } + + if let color = dictionary["offKnobTintColor"] as? String { + knobTintColor?.off = UIColor.mfGet(forHex: color) + } + + if let state = dictionary["state"] as? Bool { + changeStateNoAnimation(state) + } + + if let actionMap = dictionary.optionalDictionaryForKey("action") { + didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } + } + + if let isAnimated = dictionary["isAnimated"] as? Bool { + self.isAnimated = isAnimated + } + + if let isEnabled = dictionary["isEnabled"] as? Bool{ + self.isEnabled = isEnabled + } + } public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return Self.getContainerHeight() } } -// MARK: - Accessibility -extension Toggle { - - public func formFieldGroupName() -> String? { - return json?["groupName"] as? String - } -} - -// MARK: - FormValidationProtocol -extension Toggle { - - public func isValidField() -> Bool { - return isOn && json?["required"] as? Bool ?? false - } - - public func formFieldName() -> String? { - return json?[KeyFieldKey] as? String ?? "" - } - - public func formFieldValue() -> Any? { - return NSNumber(value: isOn) - } -} - // MARK: - MVMCoreUIMoleculeViewProtocol extension Toggle { - - public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - self.delegateObject = delegateObject - -// FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol) - - guard let dictionary = json else { return } - - if let color = dictionary["onTintColor"] as? String { - containerTintColor?.on = UIColor.mfGet(forHex: color) - } - - if let color = dictionary["offTintColor"] as? String { - containerTintColor?.off = UIColor.mfGet(forHex: color) - } - - if let color = dictionary["onKnobTintColor"] as? String { - knobTintColor?.on = UIColor.mfGet(forHex: color) - } - - if let color = dictionary["offKnobTintColor"] as? String { - knobTintColor?.off = UIColor.mfGet(forHex: color) - } - - if let state = dictionary["state"] as? Bool { - changeStateNoAnimation(state) - } - - if let actionMap = dictionary.optionalDictionaryForKey("action") { - didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } - } - - if let isAnimated = dictionary["isAnimated"] as? Bool { - self.isAnimated = isAnimated - } - - if let isEnabled = dictionary["isEnabled"] as? Bool{ - self.isEnabled = isEnabled - } - } + public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { return Self.getContainerHeight() diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index 1af64e34..d15a1b9e 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -38,7 +38,7 @@ #import @import MVMAnimationFramework; -@interface MFViewController() +@interface MFViewController() // A flag for if this view controller is observing for cache updates or not. @property (nonatomic) BOOL observingForResponseJSONUpdates; diff --git a/MVMCoreUI/FormUIHelpers/FormValidationProtocol.swift b/MVMCoreUI/FormUIHelpers/FormValidationProtocol.swift deleted file mode 100644 index 49cfacc9..00000000 --- a/MVMCoreUI/FormUIHelpers/FormValidationProtocol.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// FormValidationProtocol.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 3/26/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import Foundation - -@objc public protocol FormValidationProtocol: NSObjectProtocol { - - // Getter method to get the FormValidator from the delegate (Mostly from the parent View Controller) - @objc optional func formValidatorModel() -> FormValidator? -} - -@objc public protocol FormValidationFormFieldProtocol: FormValidationProtocol { - // Used to check the validity of the field. For example, to enable/disable the primary button. - @objc func isValidField() -> Bool - - // The Field name key value pair for sending to server - @objc func formFieldName() -> String? - - // Returns the group name for validation. The class should always return a value. - @objc func formFieldGroupName() -> String? - - // The Field value key value pair for sending to server - @objc func formFieldValue() -> Any? -} - -@objc public protocol FormValidationEnableDisableProtocol: FormValidationProtocol { - - // Returns true if the button needs to be enabled/disabled based on the validation - @objc func isValidationRequired() -> Bool - - // Based on the isValidField(), the fields which needs to be enabled can call this method - @objc optional func enableField(_ enable: Bool) - - // Returns the list of field keys required to enable/disable - @objc optional func requiredGroups() -> [String]? -} diff --git a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift b/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift deleted file mode 100644 index 97668df4..00000000 --- a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift +++ /dev/null @@ -1,10 +0,0 @@ -// -// MVMCoreUIFormValidator+FormParams.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 3/21/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import Foundation - diff --git a/MVMCoreUI/Legacy/Views/MFTextField.m b/MVMCoreUI/Legacy/Views/MFTextField.m index 691e6677..4ad018a4 100644 --- a/MVMCoreUI/Legacy/Views/MFTextField.m +++ b/MVMCoreUI/Legacy/Views/MFTextField.m @@ -18,7 +18,7 @@ @import MVMCore.NSDictionary_MFConvenience; @import MVMCore.MVMCoreJSONConstants; -@interface MFTextField() +@interface MFTextField() @property (strong, nonatomic) UIColor *customPlaceHolderColor; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *separatorHeightConstraint; @@ -560,11 +560,8 @@ - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { -// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; -// FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol]; - [self setWithMap:json]; -// self.mfTextFieldDelegate = formValidator; + self.mfTextFieldDelegate = delegateObject.uiTextFieldDelegate; self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate; [MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate]; } @@ -574,24 +571,4 @@ + (CGFloat)estimatedHeightForRow:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject { return 76; } - -#pragma mark - FormValidationProtocol - - -- (BOOL)isValidField { - return self.isValid; -} - -- (nullable NSString *)formFieldName { - return self.fieldKey; -} - -- (nullable id)formFieldValue { - return self.text; -} - -- (NSString * _Nullable)formFieldGroupName { - return self.groupName; -} - @end diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m index cfa1d20b..ab906bd7 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m @@ -21,7 +21,7 @@ static const CGFloat FaultTolerance = 20.f; static const CGFloat CheckBoxHeightWidth = 18.0; -@interface MVMCoreUICheckBox () +@interface MVMCoreUICheckBox () @property (nonatomic, readwrite) BOOL isSelected; @property (weak, nonatomic) UIView *checkedSquare; @@ -109,23 +109,6 @@ static const CGFloat CheckBoxHeightWidth = 18.0; return checkBox; } -#pragma mark - FormValidationProtocol - -- (BOOL)isValidField { - if (self.isRequired) { - return self.isSelected; - } - return true; -} - -- (nullable NSString *)formFieldName { - return self.fieldKey; -} - -- (nullable id)formFieldValue { - return @(self.isSelected); -} - #pragma mark - inits - (instancetype)init { diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m index c12e70a5..e4c3c38b 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m @@ -22,7 +22,7 @@ const CGFloat SwitchKnobWidth = 20; const CGFloat SwitchKnobHeight = 20; const CGFloat SwitchShakeIntensity = 2; -@interface MVMCoreUISwitch () +@interface MVMCoreUISwitch () @property (weak, nonatomic) UIView *baseView; @property (weak, nonatomic) UIView *knobView; @@ -426,22 +426,4 @@ const CGFloat SwitchShakeIntensity = 2; return [MVMCoreUIUtility hardcodedStringWithKey:@"AccToggleHint"]; } -#pragma mark FormValidationProtocol - -- (NSString * _Nullable)formFieldGroupName { - return [self.json string:@"groupName"]; -} - -- (BOOL)isValidField { - return self.isOn && [self.json boolForKey:@"required"]; -} - -- (NSString *)formFieldName { - return [self.json string:KeyFieldKey]; -} - -- (id)formFieldValue { - return @(self.isOn); -} - @end diff --git a/MVMCoreUI/Legacy/Views/PrimaryButton.m b/MVMCoreUI/Legacy/Views/PrimaryButton.m index f39edefc..4ced32ac 100644 --- a/MVMCoreUI/Legacy/Views/PrimaryButton.m +++ b/MVMCoreUI/Legacy/Views/PrimaryButton.m @@ -18,7 +18,7 @@ @import MVMCore.MVMCoreGetterUtility; @import MVMCore.NSDictionary_MFConvenience; -@interface PrimaryButton() +@interface PrimaryButton() @property (nonatomic) BOOL smallButton; @property (assign, nonatomic) BOOL tinyButton; @@ -781,22 +781,4 @@ } } -#pragma mark - FormValidationEnableDisableProtocol - -- (BOOL)isValidationRequired { - return self.validationRequired; -} - -- (NSArray *)requiredGroups { - return self.requiredGroupsList; -} - -- (void)enableField:(BOOL)enable { - if (!self.validationRequired) { - self.enabled = YES; - } else { - self.enabled = enable; - } -} - @end From 97cf39eaeedbad590b74eae48a0b9419787f8051 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 4 Mar 2020 15:17:45 -0500 Subject: [PATCH 03/19] textfield enhancement --- MVMCoreUI/Atoms/TextFields/TextEntryField.swift | 15 ++++++--------- MVMCoreUI/Atoms/Views/Toggle.swift | 4 +++- MVMCoreUI/BaseControllers/MFViewController.m | 4 ++-- .../FormUIHelpers/New/Rules/RulesProtocol.swift | 10 +++------- MVMCoreUI/Legacy/Views/MFTextField.m | 3 +-- 5 files changed, 15 insertions(+), 21 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 870d669a..49fb0953 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -45,7 +45,7 @@ import UIKit private var observingForChange: Bool = false /// Validate on each entry in the textField. Default: false - public var validateEachCharacter: Bool = false + public var validateEachCharacter: Bool = true /// Validate when user resigns editing. Default: true public var validateWhenDoneEditing: Bool = true @@ -233,18 +233,17 @@ import UIKit } @objc public func updateValidation(_ isValid: Bool) { + let previousValidity = self.isValid self.isValid = isValid - if isValid { - showError = false - observingTextFieldDelegate?.isValid?(textfield: self) - } else { + if previousValidity && !isValid { showError = true observingTextFieldDelegate?.isInvalid?(textfield: self) + } else if (!previousValidity && isValid) { + showError = false + observingTextFieldDelegate?.isValid?(textfield: self) } } - - /// Executes on UITextField.textDidBeginEditingNotification @objc func startEditing() { @@ -254,9 +253,7 @@ import UIKit /// Executes on UITextField.textDidChangeNotification (each character entry) @objc func valueChanged() { - guard validateEachCharacter else { return } - validateTextField() } diff --git a/MVMCoreUI/Atoms/Views/Toggle.swift b/MVMCoreUI/Atoms/Views/Toggle.swift index d6082292..7e45c567 100644 --- a/MVMCoreUI/Atoms/Views/Toggle.swift +++ b/MVMCoreUI/Atoms/Views/Toggle.swift @@ -100,7 +100,8 @@ public typealias ActionBlockConfirmation = () -> (Bool) knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off self.constrainKnob() } - + + (model as? ToggleModel)?.state = isOn FormValidator.validate(delegate: delegateObject?.formHolderDelegate) accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff") setNeedsLayout() @@ -339,6 +340,7 @@ public typealias ActionBlockConfirmation = () -> (Bool) return } + self.model = model self.delegateObject = delegateObject let toggleModelJSON = toggleModel.toJSON() diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index d15a1b9e..fef3b860 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -468,7 +468,7 @@ // Since we have new data, build stuff for the screen and update the ui once the screen is done laying out. [self newDataBuildAndUpdate]; - + self.needToupdateUIOnScreenSizeChanges = YES; if (UIAccessibilityIsVoiceOverRunning()) { @@ -479,12 +479,12 @@ [self setupIntroAnimations]; } - [self startValidation]; } - (void)newDataBuildAndUpdate { [MVMCoreDispatchUtility performBlockOnMainThread:^{ [self newDataBuildScreen]; + [self startValidation]; self.needToUpdateUI = YES; [self.view setNeedsLayout]; }]; diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift index 97485d66..536bf468 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift @@ -41,13 +41,9 @@ public extension RulesProtocol { guard let formField = formValidator.formField(for: formKey) else { continue } - valid = valid && isValid(formField) - if !valid { - setValid(formField, valid) - break - } else { - setValid(formField, valid) - } + let fieldValidity = isValid(formField) + setValid(formField, fieldValidity) + valid = valid && fieldValidity } return valid } diff --git a/MVMCoreUI/Legacy/Views/MFTextField.m b/MVMCoreUI/Legacy/Views/MFTextField.m index 4ad018a4..081f9fe8 100644 --- a/MVMCoreUI/Legacy/Views/MFTextField.m +++ b/MVMCoreUI/Legacy/Views/MFTextField.m @@ -560,8 +560,7 @@ - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { - [self setWithMap:json]; - self.mfTextFieldDelegate = delegateObject.uiTextFieldDelegate; + [self setWithMap:json]; self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate; [MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate]; } From 1bbfb0390a89ad52fd3e06cd9bd21de5a30f3371 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 6 Mar 2020 10:51:09 -0500 Subject: [PATCH 04/19] fixes --- MVMCoreUI.xcodeproj/project.pbxproj | 4 --- MVMCoreUI/Atoms/Buttons/ButtonModel.swift | 6 +++-- .../Atoms/TextFields/EntryFieldModel.swift | 8 +++++- .../Atoms/TextFields/TextEntryField.swift | 6 ++--- .../Atoms/TextFields/TextFieldModel.swift | 2 +- MVMCoreUI/Atoms/Views/CheckboxModel.swift | 6 +++++ MVMCoreUI/Atoms/Views/RadioButton.swift | 4 +-- MVMCoreUI/Atoms/Views/RadioButtonModel.swift | 2 +- MVMCoreUI/Atoms/Views/ToggleModel.swift | 9 ++++--- MVMCoreUI/FormUIHelpers/FormValidator.swift | 27 +++++++++++++++---- .../New/FormActionFieldProtocol.swift | 3 +-- .../FormUIHelpers/New/FormFieldProtocol.swift | 2 +- .../FormUIHelpers/New/FormItemProtocol.swift | 8 +++++- .../New/Rules/RuleRequiredModel.swift | 2 +- .../ModelProtocols/FormModelProtocol.swift | 16 ----------- .../RadioButtonSelectionHelper.swift | 5 ++-- 16 files changed, 64 insertions(+), 46 deletions(-) delete mode 100644 MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 3dd1fad9..113ebc13 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -57,7 +57,6 @@ 017BEB382360C6AC0024EF95 /* RadioButtonLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */; }; 017BEB3C2361EA1D0024EF95 /* MFViewController+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */; }; 017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB3F23620A230024EF95 /* TextFieldModel.swift */; }; - 017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB4123620AD20024EF95 /* FormModelProtocol.swift */; }; 017BEB442362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB432362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift */; }; 017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */; }; 017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */; }; @@ -425,7 +424,6 @@ 017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonLabel.swift; sourceTree = ""; }; 017BEB3B2361EA1D0024EF95 /* MFViewController+Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFViewController+Model.swift"; sourceTree = ""; }; 017BEB3F23620A230024EF95 /* TextFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldModel.swift; sourceTree = ""; }; - 017BEB4123620AD20024EF95 /* FormModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormModelProtocol.swift; sourceTree = ""; }; 017BEB432362192F0024EF95 /* MVMCoreUIMoleculeMappingObject+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUIMoleculeMappingObject+ModelExtension.swift"; sourceTree = ""; }; 017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeViewProtocol.swift; sourceTree = ""; }; 017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeViewProtocol.swift; sourceTree = ""; }; @@ -762,7 +760,6 @@ isa = PBXGroup; children = ( 014AA72323C501E2006F3E93 /* ContainerModelProtocol.swift */, - 017BEB4123620AD20024EF95 /* FormModelProtocol.swift */, 012A88C3238D86E600FE3DA1 /* CarouselItemModelProtocol.swift */, 012A88B0238C880100FE3DA1 /* CarouselPagingModelProtocol.swift */, 01EB3683236097C0006832FA /* MoleculeModelProtocol.swift */, @@ -1947,7 +1944,6 @@ D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */, C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */, 0AE98BB523FF18D2004C5109 /* Arrow.swift in Sources */, - 017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */, D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */, 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */, D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift index 77b7addc..2826ac03 100644 --- a/MVMCoreUI/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atoms/Buttons/ButtonModel.swift @@ -33,7 +33,7 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormAction public var disabledFillColor: Color? public var disabledTextColor: Color? public var disabledBorderColor: Color? - public var groupName: String? + public var groupName: String? = FormValidator.defaultGroupName public func updateEnable(_ enabled: Bool) { self.enabled = enabled @@ -82,7 +82,9 @@ public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormAction backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) - groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } if let style = try typeContainer.decodeIfPresent(ButtonStyle.self, forKey: .style) { self.style = style } diff --git a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift index e9ca5e65..5ccb67d7 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift @@ -27,7 +27,7 @@ import Foundation public var isLocked: Bool? public var isSelected: Bool? public var fieldKey: String? - public var isRequired: Bool? + public var groupName: String? = FormValidator.defaultGroupName public var text: String? public var isValid: Bool? { @@ -57,6 +57,7 @@ import Foundation case isValid case isRequired = "required" case text + case groupName } public func formFieldValue() -> Any? { @@ -79,6 +80,10 @@ import Foundation fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) isValid = try typeContainer.decodeIfPresent(Bool.self, forKey: .isValid) text = try typeContainer.decodeIfPresent(String.self, forKey: .text) + + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } } public func encode(to encoder: Encoder) throws { @@ -94,5 +99,6 @@ import Foundation try container.encodeIfPresent(fieldKey, forKey: .fieldKey) try container.encodeIfPresent(isValid, forKey: .isValid) try container.encodeIfPresent(text, forKey: .text) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 49fb0953..993aed59 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -197,9 +197,8 @@ import UIKit @objc deinit { setBothTextDelegates(to: nil) } - + @objc public func setBothTextDelegates(to delegate: (UITextFieldDelegate & ObservingTextFieldDelegate)?) { - observingTextFieldDelegate = delegate uiTextFieldDelegate = delegate } @@ -246,7 +245,6 @@ import UIKit } /// Executes on UITextField.textDidBeginEditingNotification @objc func startEditing() { - isSelected = true textField.becomeFirstResponder() } @@ -254,6 +252,7 @@ import UIKit /// Executes on UITextField.textDidChangeNotification (each character entry) @objc func valueChanged() { guard validateEachCharacter else { return } + isSelected = true validateTextField() } @@ -310,7 +309,6 @@ import UIKit defaultValidationBlock() } -// observingTextFieldDelegate = FormValidator.getFormValidatorFor(delegate: delegateObject?.formHolderDelegate) uiTextFieldDelegate = delegateObject?.uiTextFieldDelegate observingTextFieldDelegate = delegateObject?.observingTextFieldDelegate MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) diff --git a/MVMCoreUI/Atoms/TextFields/TextFieldModel.swift b/MVMCoreUI/Atoms/TextFields/TextFieldModel.swift index e26995d6..d901d13a 100644 --- a/MVMCoreUI/Atoms/TextFields/TextFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/TextFieldModel.swift @@ -8,7 +8,7 @@ import UIKit -@objcMembers public class TextFieldModel: MoleculeModelProtocol, FormModelProtocol { +@objcMembers public class TextFieldModel: MoleculeModelProtocol { public static var identifier: String = "textField" public var backgroundColor: Color? diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift index 60aade23..77fffecd 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxModel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -32,6 +32,7 @@ import Foundation public var disabledCheckColor: Color = Color(uiColor: .mvmCoolGray3) public var fieldKey: String? + public var groupName: String? = FormValidator.defaultGroupName //-------------------------------------------------- // MARK: - Keys @@ -53,6 +54,7 @@ import Foundation case isRound case isEnabled case action + case groupName } init(isChecked: Bool = false) {} @@ -81,6 +83,9 @@ import Foundation isRound = try typeContainer.decodeIfPresent(Bool.self, forKey: .isRound) ?? false isEnabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .isEnabled) ?? true action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } } public func encode(to encoder: Encoder) throws { @@ -100,5 +105,6 @@ import Foundation try container.encodeIfPresent(isRound, forKey: .isRound) try container.encodeIfPresent(isEnabled, forKey: .isEnabled) try container.encodeModelIfPresent(action, forKey: .action) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/Atoms/Views/RadioButton.swift b/MVMCoreUI/Atoms/Views/RadioButton.swift index f6484326..2883c4ec 100644 --- a/MVMCoreUI/Atoms/Views/RadioButton.swift +++ b/MVMCoreUI/Atoms/Views/RadioButton.swift @@ -33,7 +33,7 @@ import UIKit } lazy var radioGroupName: String? = { - [unowned self] in return radioModel?.radioGroupName ?? radioModel?.fieldKey + [unowned self] in return radioModel?.fieldKey }() lazy var radioButtonSelectionHelper: RadioButtonSelectionHelper? = { @@ -80,7 +80,7 @@ import UIKit } public func formFieldGroupName() -> String? { - return radioModel?.radioGroupName + return radioModel?.fieldKey } public func formFieldValue() -> String? { diff --git a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift index a058ada6..f185971d 100644 --- a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift +++ b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift @@ -14,8 +14,8 @@ public class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { public static var identifier: String = "radioButton" public var backgroundColor: Color? public var state: Bool? = false - public var radioGroupName: String? public var fieldKey: String? + public var groupName: String? = FormValidator.defaultGroupName public var fieldValue: String public func formFieldValue() -> Any? { return fieldValue diff --git a/MVMCoreUI/Atoms/Views/ToggleModel.swift b/MVMCoreUI/Atoms/Views/ToggleModel.swift index 54c86514..14f43d02 100644 --- a/MVMCoreUI/Atoms/Views/ToggleModel.swift +++ b/MVMCoreUI/Atoms/Views/ToggleModel.swift @@ -15,8 +15,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { public var state: Bool = true public var action: ActionModelProtocol? public var alternateAction: ActionModelProtocol? - public var required: Bool? public var fieldKey: String? + public var groupName: String? = FormValidator.defaultGroupName private enum CodingKeys: String, CodingKey { case moleculeName @@ -26,6 +26,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { case required case fieldKey case alternateAction + case groupName } public func formFieldValue() -> Any? { @@ -44,8 +45,10 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType) alternateAction = try typeContainer.decodeModelIfPresent(codingKey: .alternateAction, typeCodingKey: ActionCodingKey.actionType) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required) fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName + } } public func encode(to encoder: Encoder) throws { @@ -55,7 +58,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { try container.encodeModelIfPresent(alternateAction, forKey: .alternateAction) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(state, forKey: .state) - try container.encodeIfPresent(required, forKey: .required) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(groupName, forKey: .groupName) } } diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index fd4dd6e8..d3f238af 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -11,9 +11,8 @@ import MVMCore @objcMembers public class FormValidator: NSObject { + static var defaultGroupName: String = "default" var extraValidationBlock: (() -> Bool)? - var dummyGroupName = "dummyGroupName" - var formRules: [FormGroupRule] var delegate: FormHolderProtocol? var fieldMolecules: [FormFieldProtocol] = [] @@ -75,15 +74,19 @@ import MVMCore // mark Form params @objc public extension FormValidator { @objc func addFormParams(requestParameters: MVMCoreRequestParameters) { - requestParameters.add(self.getFormParams()) + let formButton = getFormButton(forPageType: requestParameters.pageType) + let groupName = formButton?.groupName ?? FormValidator.defaultGroupName + let formParams = self.getFormParams(forGroup: groupName) + requestParameters.add(formParams) } - @objc func getFormParams() -> [String: Any] { + @objc func getFormParams( forGroup groupName: String) -> [String: Any] { var extraParam: [String: Any] = [:] MVMCoreDispatchUtility.performSyncBlock(onMainThread: { for molecule in self.fieldMolecules { if let formFieldName = molecule.fieldKey, - let formFieldValue = molecule.formFieldValue() { + let formFieldValue = molecule.formFieldValue(), + groupName == molecule.groupName { extraParam[formFieldName] = formFieldValue } } @@ -91,3 +94,17 @@ import MVMCore return extraParam } } + +// Temporary +public extension FormValidator { + func getFormButton(forPageType pageType: String?) -> ButtonModel? { + for actionItem in formActionMolecules { + if let buttonModel = actionItem as? ButtonModel, + pageType == (buttonModel.action as? ActionOpenPageModel)?.pageType { + return buttonModel + } + } + return nil + } +} + diff --git a/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift index 2f4b758d..31208e95 100644 --- a/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift @@ -8,8 +8,7 @@ import Foundation -public protocol FormActionFieldProtocol: EnableableModelProtocol, FormItemProtocol { - var groupName: String? { get set } +public protocol FormActionFieldProtocol: EnableableModelProtocol, FormItemProtocol { func updateEnable(_ enabled: Bool) var updateUI: (() -> Void)? { get set } } diff --git a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift index d6073943..9ba8ad4d 100644 --- a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift @@ -10,6 +10,6 @@ import Foundation public protocol FormFieldProtocol: FormItemProtocol { - var fieldKey: String? { get set } + var fieldKey: String? { get set } func formFieldValue() -> Any? } diff --git a/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift index 47911f0c..9b671238 100644 --- a/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift @@ -9,5 +9,11 @@ import Foundation public protocol FormItemProtocol { - + static var defaultGroupName: String? { get } + var groupName: String? { get set } +} +extension FormItemProtocol{ + public static var defaultGroupName: String? { + return "default" + } } diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift index 400c5b1b..252808a0 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift @@ -21,7 +21,7 @@ public class RuleRequiredModel: RulesProtocol { } var valid = true if let valueString = value as? String { - valid = valueString.count > 3 + valid = valueString.count > 0 } else if let valueBool = value as? Bool { valid = valueBool } diff --git a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift b/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift deleted file mode 100644 index 28840f06..00000000 --- a/MVMCoreUI/Models/ModelProtocols/FormModelProtocol.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// FormModelProtocol.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 10/24/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import Foundation - - -public protocol FormModelProtocol: ModelProtocol { - var required: Bool? { get } - var fieldKey: String? { get } - var groupName: String? { get } -} diff --git a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift index 7505fca1..8297a2a3 100644 --- a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift @@ -11,6 +11,7 @@ import UIKit @objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol { public var fieldKey: String? + public var groupName: String? = FormValidator.defaultGroupName private var selectedRadioButton: RadioButton? private var fieldGroupName: String? @@ -19,13 +20,13 @@ import UIKit } public static func setupForRadioButtonGroup(_ radioButtonModel: RadioButtonModel, formValidator: FormValidator?) -> RadioButtonSelectionHelper { - guard let groupName = radioButtonModel.radioGroupName ?? radioButtonModel.fieldKey, + guard let groupName = radioButtonModel.fieldKey, let formValidator = formValidator else { return RadioButtonSelectionHelper(radioButtonModel.fieldKey) } let radioButtonSelectionHelper = formValidator.radioButtonsModelByGroup[groupName] ?? RadioButtonSelectionHelper(radioButtonModel.fieldKey) - radioButtonSelectionHelper.fieldGroupName = radioButtonModel.radioGroupName + radioButtonSelectionHelper.fieldGroupName = radioButtonModel.fieldKey formValidator.radioButtonsModelByGroup[groupName] = radioButtonSelectionHelper return radioButtonSelectionHelper } From 521ad8711df8868476d9b598d3adb2c0de284137 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 6 Mar 2020 17:26:42 -0500 Subject: [PATCH 05/19] value changed rules --- MVMCoreUI.xcodeproj/project.pbxproj | 16 +++++----- .../Atoms/TextFields/EntryFieldModel.swift | 9 ++++-- MVMCoreUI/Atoms/Views/CheckboxModel.swift | 6 ++-- MVMCoreUI/Atoms/Views/RadioButton.swift | 7 ++-- MVMCoreUI/Atoms/Views/RadioButtonModel.swift | 20 ++++++------ MVMCoreUI/Atoms/Views/ToggleModel.swift | 5 +-- MVMCoreUI/FormUIHelpers/FormValidator.swift | 3 +- .../FormUIHelpers/New/FormFieldProtocol.swift | 9 +++++- ...l.swift => RuleAllValueChangedModel.swift} | 8 ++--- .../New/Rules/RuleAnyModel.swift | 20 ------------ .../New/Rules/RuleAnyValueChangedModel.swift | 32 +++++++++++++++++++ .../RadioButtonSelectionHelper.swift | 5 ++- .../OtherHandlers/MoleculeObjectMapping.swift | 4 +-- 13 files changed, 88 insertions(+), 56 deletions(-) rename MVMCoreUI/FormUIHelpers/New/Rules/{RuleValueChangeModel.swift => RuleAllValueChangedModel.swift} (53%) delete mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 113ebc13..b29cdf75 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -18,8 +18,8 @@ 011D958724042492000E3791 /* FormFieldProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D958624042492000E3791 /* FormFieldProtocol.swift */; }; 011D95892404249B000E3791 /* FormProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95882404249B000E3791 /* FormProtocol.swift */; }; 011D959B240451E3000E3791 /* RuleRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959A240451E3000E3791 /* RuleRequiredModel.swift */; }; - 011D959D2404536F000E3791 /* RuleAnyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959C2404536F000E3791 /* RuleAnyModel.swift */; }; - 011D959F240453A1000E3791 /* RuleValueChangeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */; }; + 011D959D2404536F000E3791 /* RuleAnyValueChangedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */; }; + 011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */; }; 011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */; }; 011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A2240453F8000E3791 /* RuleRegexModel.swift */; }; 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011D95A4240455DC000E3791 /* FormGroupRule.swift */; }; @@ -385,8 +385,8 @@ 011D958624042492000E3791 /* FormFieldProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormFieldProtocol.swift; sourceTree = ""; }; 011D95882404249B000E3791 /* FormProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormProtocol.swift; sourceTree = ""; }; 011D959A240451E3000E3791 /* RuleRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRequiredModel.swift; sourceTree = ""; }; - 011D959C2404536F000E3791 /* RuleAnyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModel.swift; sourceTree = ""; }; - 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleValueChangeModel.swift; sourceTree = ""; }; + 011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyValueChangedModel.swift; sourceTree = ""; }; + 011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAllValueChangedModel.swift; sourceTree = ""; }; 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsModel.swift; sourceTree = ""; }; 011D95A2240453F8000E3791 /* RuleRegexModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleRegexModel.swift; sourceTree = ""; }; 011D95A4240455DC000E3791 /* FormGroupRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormGroupRule.swift; sourceTree = ""; }; @@ -790,8 +790,8 @@ children = ( 011D958424042432000E3791 /* RulesProtocol.swift */, 011D959A240451E3000E3791 /* RuleRequiredModel.swift */, - 011D959C2404536F000E3791 /* RuleAnyModel.swift */, - 011D959E240453A1000E3791 /* RuleValueChangeModel.swift */, + 011D959C2404536F000E3791 /* RuleAnyValueChangedModel.swift */, + 011D959E240453A1000E3791 /* RuleAllValueChangedModel.swift */, 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */, 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, 011D95A4240455DC000E3791 /* FormGroupRule.swift */, @@ -2010,7 +2010,7 @@ D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, 014AA72E23C5059B006F3E93 /* StackCenteredPageTemplateModel.swift in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, - 011D959D2404536F000E3791 /* RuleAnyModel.swift in Sources */, + 011D959D2404536F000E3791 /* RuleAnyValueChangedModel.swift in Sources */, D260105923D0A92900764D80 /* ContainerProtocol.swift in Sources */, C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, @@ -2028,7 +2028,7 @@ D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */, C695A69823C990C200BFB94E /* DoughnutChartView.swift in Sources */, D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */, - 011D959F240453A1000E3791 /* RuleValueChangeModel.swift in Sources */, + 011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */, 011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */, 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */, 01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */, diff --git a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift index 5ccb67d7..2b2ef27b 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift @@ -29,6 +29,7 @@ import Foundation public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName public var text: String? + public var baseValue: JSONValue? public var isValid: Bool? { didSet { @@ -60,8 +61,12 @@ import Foundation case groupName } - public func formFieldValue() -> Any? { - return text + public func formFieldValue() -> JSONValue? { + if let text = text { + return JSONValue(stringLiteral: text) + } else { + return nil + } } //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift index 77fffecd..cf7f7298 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxModel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -9,7 +9,6 @@ import Foundation @objcMembers public class CheckboxModel: MoleculeModelProtocol, FormFieldProtocol { - //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -33,6 +32,7 @@ import Foundation public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName + public var baseValue: JSONValue? //-------------------------------------------------- // MARK: - Keys @@ -59,8 +59,8 @@ import Foundation init(isChecked: Bool = false) {} - public func formFieldValue() -> Any? { - return isChecked + public func formFieldValue() -> JSONValue? { + return JSONValue(booleanLiteral: isChecked) } //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/RadioButton.swift b/MVMCoreUI/Atoms/Views/RadioButton.swift index 2883c4ec..49625eb2 100644 --- a/MVMCoreUI/Atoms/Views/RadioButton.swift +++ b/MVMCoreUI/Atoms/Views/RadioButton.swift @@ -83,8 +83,11 @@ import UIKit return radioModel?.fieldKey } - public func formFieldValue() -> String? { - return radioModel?.fieldValue + public func formFieldValue() -> JSONValue? { + if let fieldValue = radioModel?.fieldValue { + return JSONValue(stringLiteral: fieldValue) + } + return nil } // MARK: - MVMViewProtocol diff --git a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift index f185971d..a8a5de28 100644 --- a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift +++ b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift @@ -7,22 +7,22 @@ // import Foundation - +import MVMCore public class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { - public static var identifier: String = "radioButton" public var backgroundColor: Color? public var state: Bool? = false public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName - public var fieldValue: String - public func formFieldValue() -> Any? { - return fieldValue - } - - init(_ fieldKey: String, _ fieldValue: String) { - self.fieldKey = fieldKey - self.fieldValue = fieldValue + public var fieldValue: String? + public var baseValue: JSONValue? + + public func formFieldValue() -> JSONValue? { + if let fieldValue = fieldValue { + return JSONValue(stringLiteral: fieldValue) + } else { + return nil + } } } diff --git a/MVMCoreUI/Atoms/Views/ToggleModel.swift b/MVMCoreUI/Atoms/Views/ToggleModel.swift index 14f43d02..51f49828 100644 --- a/MVMCoreUI/Atoms/Views/ToggleModel.swift +++ b/MVMCoreUI/Atoms/Views/ToggleModel.swift @@ -17,6 +17,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { public var alternateAction: ActionModelProtocol? public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName + public var baseValue: JSONValue? private enum CodingKeys: String, CodingKey { case moleculeName @@ -29,8 +30,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { case groupName } - public func formFieldValue() -> Any? { - return state + public func formFieldValue() -> JSONValue? { + return JSONValue(booleanLiteral: state) } public init(_ state: Bool) { diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index d3f238af..ebc47f23 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -24,7 +24,8 @@ import MVMCore } public func insertMolecule(_ molecule: FormItemProtocol) { - if let molecule = molecule as? FormFieldProtocol { + if var molecule = molecule as? FormFieldProtocol { + molecule.baseValue = molecule.formFieldValue() fieldMolecules.append(molecule) } if let molecule = molecule as? FormActionFieldProtocol { diff --git a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift index 9ba8ad4d..0a099000 100644 --- a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift @@ -11,5 +11,12 @@ import Foundation public protocol FormFieldProtocol: FormItemProtocol { var fieldKey: String? { get set } - func formFieldValue() -> Any? + var baseValue: JSONValue? { get set } + func formFieldValue() -> JSONValue? +} + +extension FormFieldProtocol { + var baseValue: JSONValue? { + return nil + } } diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift similarity index 53% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift rename to MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift index 221c4b5d..a33cb64c 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleValueChangeModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift @@ -8,13 +8,13 @@ import Foundation -public class RuleValueChangeModel: RulesProtocol { +public class RuleAllValueChangedModel: RulesProtocol { - public static var identifier: String = "valueChanged" - public var ruleType: String = RuleAnyModel.identifier + public static var identifier: String = "allValueChanged" + public var ruleType: String = RuleAllValueChangedModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { - return false + return formField.baseValue != formField.formFieldValue() } } diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift deleted file mode 100644 index 3e10b7af..00000000 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyModel.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// RuleAnyModel.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 2/24/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import Foundation - -public class RuleAnyModel: RulesProtocol { - - public static var identifier: String = "any" - public var ruleType: String = RuleAnyModel.identifier - public var fields: [String] - - public func isValid(_ formField: FormFieldProtocol) -> Bool { - return false - } -} diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift new file mode 100644 index 00000000..80b95514 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift @@ -0,0 +1,32 @@ +// +// RuleAnyModel.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 2/24/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class RuleAnyValueChangedModel: RulesProtocol { + + public static var identifier: String = "anyValueChanged" + public var ruleType: String = RuleAnyValueChangedModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + return formField.baseValue != formField.formFieldValue() + } + + public func isValid(_ formValidator: FormValidator) -> Bool { + for formKey in fields { + guard let formField = formValidator.formField(for: formKey) else { + continue + } + if isValid(formField) { + return true + } + } + return false + } +} diff --git a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift index 8297a2a3..6674fe4d 100644 --- a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift @@ -10,10 +10,13 @@ import Foundation import UIKit @objcMembers public class RadioButtonSelectionHelper: FormFieldProtocol { + + public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName private var selectedRadioButton: RadioButton? private var fieldGroupName: String? + public var baseValue: JSONValue? init(_ fieldKey: String?) { self.fieldKey = fieldKey @@ -44,7 +47,7 @@ extension RadioButtonSelectionHelper { return selectedRadioButton?.formFieldGroupName() ?? self.fieldGroupName } - public func formFieldValue() -> Any? { + public func formFieldValue() -> JSONValue? { return selectedRadioButton?.formFieldValue() } } diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index ae8f19fe..8d150395 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -121,8 +121,8 @@ import Foundation // Helper models try? ModelRegistry.register(RuleRequiredModel.self) - try? ModelRegistry.register(RuleAnyModel.self) - try? ModelRegistry.register(RuleValueChangeModel.self) + try? ModelRegistry.register(RuleAnyValueChangedModel.self) + try? ModelRegistry.register(RuleAllValueChangedModel.self) try? ModelRegistry.register(RuleEqualsModel.self) try? ModelRegistry.register(RuleRegexModel.self) } From 8df94a2f56c1e1f51512a572c7049882fbbabea8 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Sun, 8 Mar 2020 19:14:51 -0400 Subject: [PATCH 06/19] moving back to any --- .../Atoms/TextFields/EntryFieldModel.swift | 10 ++-- MVMCoreUI/Atoms/Views/CheckboxModel.swift | 6 +-- MVMCoreUI/Atoms/Views/RadioButton.swift | 7 +-- MVMCoreUI/Atoms/Views/RadioButtonModel.swift | 46 ++++++++++++++++--- MVMCoreUI/Atoms/Views/ToggleModel.swift | 6 +-- .../FormUIHelpers/New/FormFieldProtocol.swift | 6 +-- .../New/Rules/FormGroupRule.swift | 1 - .../New/Rules/RuleAllValueChangedModel.swift | 2 +- .../New/Rules/RuleAnyValueChangedModel.swift | 2 +- .../New/Rules/RuleEqualsModel.swift | 2 +- .../New/Rules/RuleRegexModel.swift | 2 +- .../New/Rules/RuleRequiredModel.swift | 2 +- .../New/Rules/RulesProtocol.swift | 2 +- .../RadioButtonSelectionHelper.swift | 4 +- 14 files changed, 62 insertions(+), 36 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift index 2b2ef27b..54b441f7 100644 --- a/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atoms/TextFields/EntryFieldModel.swift @@ -29,7 +29,7 @@ import Foundation public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName public var text: String? - public var baseValue: JSONValue? + public var baseValue: AnyHashable? public var isValid: Bool? { didSet { @@ -61,12 +61,8 @@ import Foundation case groupName } - public func formFieldValue() -> JSONValue? { - if let text = text { - return JSONValue(stringLiteral: text) - } else { - return nil - } + public func formFieldValue() -> AnyHashable? { + return text } //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/CheckboxModel.swift b/MVMCoreUI/Atoms/Views/CheckboxModel.swift index 70224200..13b730a6 100644 --- a/MVMCoreUI/Atoms/Views/CheckboxModel.swift +++ b/MVMCoreUI/Atoms/Views/CheckboxModel.swift @@ -33,7 +33,7 @@ import Foundation public var fieldKey: String? public var fieldValue: JSONValue? public var groupName: String? = FormValidator.defaultGroupName - public var baseValue: JSONValue? + public var baseValue: AnyHashable? //-------------------------------------------------- // MARK: - Keys @@ -61,8 +61,8 @@ import Foundation init(isChecked: Bool = false) {} - public func formFieldValue() -> JSONValue? { - return JSONValue(booleanLiteral: isChecked) + public func formFieldValue() -> AnyHashable? { + return isChecked } //-------------------------------------------------- diff --git a/MVMCoreUI/Atoms/Views/RadioButton.swift b/MVMCoreUI/Atoms/Views/RadioButton.swift index 49625eb2..2c110b4e 100644 --- a/MVMCoreUI/Atoms/Views/RadioButton.swift +++ b/MVMCoreUI/Atoms/Views/RadioButton.swift @@ -83,11 +83,8 @@ import UIKit return radioModel?.fieldKey } - public func formFieldValue() -> JSONValue? { - if let fieldValue = radioModel?.fieldValue { - return JSONValue(stringLiteral: fieldValue) - } - return nil + public func formFieldValue() -> AnyHashable? { + return radioModel?.fieldValue } // MARK: - MVMViewProtocol diff --git a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift index a8a5de28..0927866c 100644 --- a/MVMCoreUI/Atoms/Views/RadioButtonModel.swift +++ b/MVMCoreUI/Atoms/Views/RadioButtonModel.swift @@ -10,19 +10,53 @@ import Foundation import MVMCore public class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { + public static var identifier: String = "radioButton" public var backgroundColor: Color? public var state: Bool? = false public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName public var fieldValue: String? - public var baseValue: JSONValue? + public var baseValue: AnyHashable? - public func formFieldValue() -> JSONValue? { - if let fieldValue = fieldValue { - return JSONValue(stringLiteral: fieldValue) - } else { - return nil + public func formFieldValue() -> AnyHashable? { + return fieldValue + } + + private enum CodingKeys: String, CodingKey { + case moleculeName + case state + case backgroundColor + case fieldKey + case groupName + case fieldValue + } + + public init(_ state: Bool) { + self.state = state + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { + self.state = state + } + + backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey) + fieldValue = try typeContainer.decodeIfPresent(String.self, forKey: .fieldValue) + if let groupName = try typeContainer.decodeIfPresent(String.self, forKey: .groupName) { + self.groupName = groupName } } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(state, forKey: .state) + try container.encodeIfPresent(fieldKey, forKey: .fieldKey) + try container.encodeIfPresent(fieldValue, forKey: .fieldValue) + try container.encodeIfPresent(groupName, forKey: .groupName) + } } diff --git a/MVMCoreUI/Atoms/Views/ToggleModel.swift b/MVMCoreUI/Atoms/Views/ToggleModel.swift index afe9ed41..18022833 100644 --- a/MVMCoreUI/Atoms/Views/ToggleModel.swift +++ b/MVMCoreUI/Atoms/Views/ToggleModel.swift @@ -17,7 +17,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { public var alternateAction: ActionModelProtocol? public var fieldKey: String? public var groupName: String? = FormValidator.defaultGroupName - public var baseValue: JSONValue? + public var baseValue: AnyHashable? private enum CodingKeys: String, CodingKey { case moleculeName @@ -30,8 +30,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { case groupName } - public func formFieldValue() -> JSONValue? { - return JSONValue(booleanLiteral: state) + public func formFieldValue() -> AnyHashable? { + return state } public init(_ state: Bool) { diff --git a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift index 0a099000..c59ccd08 100644 --- a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift @@ -11,12 +11,12 @@ import Foundation public protocol FormFieldProtocol: FormItemProtocol { var fieldKey: String? { get set } - var baseValue: JSONValue? { get set } - func formFieldValue() -> JSONValue? + var baseValue: AnyHashable? { get set } + func formFieldValue() -> AnyHashable? } extension FormFieldProtocol { - var baseValue: JSONValue? { + var baseValue: AnyHashable? { return nil } } diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift index 29872de7..d416ef3c 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift @@ -10,7 +10,6 @@ import Foundation open class FormGroupRule: Codable { -// public static var identifier: String = "formRule" var groupName: String var rules: [RulesProtocol] diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift index a33cb64c..7535c6dd 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift @@ -11,7 +11,7 @@ import Foundation public class RuleAllValueChangedModel: RulesProtocol { public static var identifier: String = "allValueChanged" - public var ruleType: String = RuleAllValueChangedModel.identifier + public var type: String = RuleAllValueChangedModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift index 80b95514..f52dd92d 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift @@ -11,7 +11,7 @@ import Foundation public class RuleAnyValueChangedModel: RulesProtocol { public static var identifier: String = "anyValueChanged" - public var ruleType: String = RuleAnyValueChangedModel.identifier + public var type: String = RuleAnyValueChangedModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift index 7d1532d8..fd7331f0 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift @@ -11,7 +11,7 @@ import Foundation public class RuleEqualsModel: RulesProtocol { public static var identifier: String = "equals" - public var ruleType: String = RuleEqualsModel.identifier + public var type: String = RuleEqualsModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift index 9ef00426..bc66fd1a 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift @@ -10,7 +10,7 @@ import Foundation public class RuleRegexModel: RulesProtocol { public static var identifier: String = "regex" - public var ruleType: String = RuleRegexModel.identifier + public var type: String = RuleRegexModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift index 252808a0..3900249a 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift @@ -12,7 +12,7 @@ import Foundation public class RuleRequiredModel: RulesProtocol { public static var identifier: String = "required" - public var ruleType: String = RuleRequiredModel.identifier + public var type: String = RuleRequiredModel.identifier public var fields: [String] public func isValid(_ formField: FormFieldProtocol) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift index 536bf468..24bedd01 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift @@ -14,7 +14,7 @@ public enum RulesCodingKey: String, CodingKey { } public protocol RulesProtocol: ModelProtocol { - var ruleType: String { get set } + var type: String { get set } var fields: [String] { get set } func isValid(_ formValidator: FormValidator) -> Bool func isValid(_ formField: FormFieldProtocol) -> Bool diff --git a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift index 6674fe4d..263a85a4 100644 --- a/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift +++ b/MVMCoreUI/Molecules/RadioButtonSelectionHelper.swift @@ -16,7 +16,7 @@ import UIKit public var groupName: String? = FormValidator.defaultGroupName private var selectedRadioButton: RadioButton? private var fieldGroupName: String? - public var baseValue: JSONValue? + public var baseValue: AnyHashable? init(_ fieldKey: String?) { self.fieldKey = fieldKey @@ -47,7 +47,7 @@ extension RadioButtonSelectionHelper { return selectedRadioButton?.formFieldGroupName() ?? self.fieldGroupName } - public func formFieldValue() -> JSONValue? { + public func formFieldValue() -> AnyHashable? { return selectedRadioButton?.formFieldValue() } } From c53c76d7f36fdb869d8ef62ddf1a5f5d7ad96241 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 9 Mar 2020 12:02:04 -0400 Subject: [PATCH 07/19] fixes --- MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift | 1 - MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift index d416ef3c..34dfb7b8 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift @@ -27,7 +27,6 @@ open class FormGroupRule: Codable { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) self.groupName = try typeContainer.decode(String.self, forKey: .groupName) self.rules = try typeContainer.decodeModels(codingKey: .rules) - //try typeContainer.decodeFormRules(codingKey: .rules) } public func encode(to encoder: Encoder) throws { diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift index 24bedd01..16fe77b3 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift @@ -28,7 +28,7 @@ public extension RulesProtocol { } static var categoryCodingKey: String { - return "ruleType" + return "type" } static var categoryName: String { From 2ce25e340c44c18eccd177aa09a83192d3c9da12 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 9 Mar 2020 22:04:41 -0400 Subject: [PATCH 08/19] optimise --- MVMCoreUI/FormUIHelpers/FormValidator.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index ebc47f23..daadf81f 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -15,7 +15,7 @@ import MVMCore var extraValidationBlock: (() -> Bool)? var formRules: [FormGroupRule] var delegate: FormHolderProtocol? - var fieldMolecules: [FormFieldProtocol] = [] + var fieldMolecules: [String: FormFieldProtocol] = [:] var formActionMolecules: [FormActionFieldProtocol] = [] var radioButtonsModelByGroup: [String: RadioButtonSelectionHelper] = [:] @@ -24,9 +24,10 @@ import MVMCore } public func insertMolecule(_ molecule: FormItemProtocol) { - if var molecule = molecule as? FormFieldProtocol { + if var molecule = molecule as? FormFieldProtocol, + let fieldKey = molecule.fieldKey { molecule.baseValue = molecule.formFieldValue() - fieldMolecules.append(molecule) + fieldMolecules[fieldKey] = molecule } if let molecule = molecule as? FormActionFieldProtocol { formActionMolecules.append(molecule) @@ -68,7 +69,7 @@ import MVMCore } public func formField(for fieldKey: String) -> FormFieldProtocol? { - return fieldMolecules.first(where: { $0.fieldKey == fieldKey }) + return fieldMolecules[fieldKey] } } @@ -84,11 +85,10 @@ import MVMCore @objc func getFormParams( forGroup groupName: String) -> [String: Any] { var extraParam: [String: Any] = [:] MVMCoreDispatchUtility.performSyncBlock(onMainThread: { - for molecule in self.fieldMolecules { - if let formFieldName = molecule.fieldKey, - let formFieldValue = molecule.formFieldValue(), + for (fieldKey, molecule) in self.fieldMolecules { + if let formFieldValue = molecule.formFieldValue(), groupName == molecule.groupName { - extraParam[formFieldName] = formFieldValue + extraParam[fieldKey] = formFieldValue } } }) From 21f38af0c372d8c648c0da42a78f6450c162fc3f Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Mon, 9 Mar 2020 22:26:01 -0400 Subject: [PATCH 09/19] equal rules --- .../New/Rules/RuleEqualsModel.swift | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift index fd7331f0..ac148a29 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift @@ -17,4 +17,24 @@ public class RuleEqualsModel: RulesProtocol { public func isValid(_ formField: FormFieldProtocol) -> Bool { return false } + + public func isValid(_ formValidator: FormValidator) -> Bool { + var valid = true + var compareValue: AnyHashable? + for formKey in fields { + guard let formField = formValidator.formField(for: formKey) else { + continue + } + + if compareValue == nil { + compareValue = formField.formFieldValue() + continue + } + if compareValue != formField.formFieldValue(){ + valid = false + break + } + } + return valid + } } From c1047d42b82d265b84ef06d30679dcd37dd10aa3 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 10 Mar 2020 11:37:08 -0400 Subject: [PATCH 10/19] regex --- MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift index bc66fd1a..db1c4859 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift @@ -12,8 +12,12 @@ public class RuleRegexModel: RulesProtocol { public static var identifier: String = "regex" public var type: String = RuleRegexModel.identifier public var fields: [String] + public var regex: String public func isValid(_ formField: FormFieldProtocol) -> Bool { + if let stringToValidate = formField.formFieldValue() as? String { + return MVMCoreUIUtility.validate(stringToValidate, withRegularExpression: regex) + } return false } } From 7965c4ac6a7c33d38b53bab3d0d9791b9f8318de Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 10 Mar 2020 15:25:49 -0400 Subject: [PATCH 11/19] clean up --- MVMCoreUI.xcodeproj/project.pbxproj | 10 --- ...maryButton+MoleculeProtocolExtension.swift | 5 -- .../MFTextField+ModelExtension.swift | 79 ------------------- .../Atoms/TextFields/MdnEntryField.swift | 42 +++++----- .../FormValidator+TextFields.swift | 69 ---------------- MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m | 4 +- MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m | 2 - MVMCoreUI/Legacy/Views/PrimaryButton.m | 1 - .../Templates/MoleculeListTemplate.swift | 2 +- 9 files changed, 23 insertions(+), 191 deletions(-) delete mode 100644 MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift delete mode 100644 MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 4066abcc..b5985e36 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 01004F3022721C3800991ECC /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01004F2F22721C3800991ECC /* RadioButton.swift */; }; 0103B84E23D7E33A009C315C /* HeadlineBodyToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */; }; 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; }; - 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; }; 0116A4E5228B19640094F3ED /* RadioButtonSelectionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */; }; 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */; }; 011B58F223A2AE2C0085F53C /* DropDownListItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */; }; @@ -40,7 +39,6 @@ 012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88AE238C626E00FE3DA1 /* CarouselModel.swift */; }; 012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88EB238F084D00FE3DA1 /* FooterModel.swift */; }; 012A88F123985E0100FE3DA1 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012A88F023985E0100FE3DA1 /* Color.swift */; }; - 012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */; }; 012CA99E2385A2D3003F810F /* MFView+ModelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */; }; 013F801923FB4A8E00AD8013 /* UIContentMode+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */; }; 014AA72423C501E2006F3E93 /* MoleculeContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */; }; @@ -383,7 +381,6 @@ 01004F2F22721C3800991ECC /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = ""; }; 0103B84D23D7E33A009C315C /* HeadlineBodyToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyToggleModel.swift; sourceTree = ""; }; 0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = ""; }; - 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = ""; }; 0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonSelectionHelper.swift; sourceTree = ""; }; 011B58EF23A2AA980085F53C /* ListItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListItemModelProtocol.swift; sourceTree = ""; }; 011B58F123A2AE2C0085F53C /* DropDownListItemModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DropDownListItemModel.swift; sourceTree = ""; }; @@ -413,7 +410,6 @@ 012A88C7238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModelMoleculeDelegateProtocol.swift; sourceTree = ""; }; 012A88EB238F084D00FE3DA1 /* FooterModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FooterModel.swift; sourceTree = ""; }; 012A88F023985E0100FE3DA1 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; - 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFTextField+ModelExtension.swift"; sourceTree = ""; }; 012CA99D2385A2D3003F810F /* MFView+ModelExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFView+ModelExtension.swift"; sourceTree = ""; }; 013F801823FB4A8E00AD8013 /* UIContentMode+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIContentMode+Extension.swift"; sourceTree = ""; }; 014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeContainerModel.swift; sourceTree = ""; }; @@ -832,7 +828,6 @@ children = ( 011D9583240422BF000E3791 /* New */, 0105618A224BBE7700E1557D /* FormValidator.swift */, - 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */, ); path = FormUIHelpers; sourceTree = ""; @@ -1457,7 +1452,6 @@ 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */, 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */, 017BEB3F23620A230024EF95 /* TextFieldModel.swift */, - 012CA9992384A687003F810F /* MFTextField+ModelExtension.swift */, ); path = TextFields; sourceTree = ""; @@ -1910,7 +1904,6 @@ D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */, 01EB368F23609801006832FA /* LabelModel.swift in Sources */, 942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */, - 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */, 01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */, 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */, 011B58F023A2AA980085F53C /* ListItemModelProtocol.swift in Sources */, @@ -1976,7 +1969,6 @@ D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */, 017BEB4A236235BA0024EF95 /* ModelMoleculeViewProtocol.swift in Sources */, C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */, - 012CA99A2384A687003F810F /* MFTextField+ModelExtension.swift in Sources */, 01EB3684236097C0006832FA /* MoleculeModelProtocol.swift in Sources */, D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */, D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, @@ -2028,7 +2020,6 @@ C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, - 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */, 0A7EF86323D8AFA000B2AAD1 /* BaseDropdownEntryFieldModel.swift in Sources */, 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */, D2B18B922361E65A00A9AEDC /* CoreUIObject.swift in Sources */, @@ -2056,7 +2047,6 @@ D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */, 011D959F240453A1000E3791 /* RuleAllValueChangedModel.swift in Sources */, 011D95AD2406BB57000E3791 /* FormHolderProtocol.swift in Sources */, - 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */, 01509D932327ECFB00EF99AA /* ProgressBar.swift in Sources */, D260106523D0CEA700764D80 /* StackModel.swift in Sources */, D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift index f354ac85..6cf0df21 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton+MoleculeProtocolExtension.swift @@ -16,11 +16,6 @@ extension PrimaryButton: ModelMoleculeViewProtocol { setTitle(model.title, for: .normal) backgroundColor = model.backgroundColor?.uiColor -// if self.validationRequired, -// let selfForm = self as? FormValidationEnableDisableProtocol { -// FormValidator.setupValidation(molecule: selfForm, delegate: delegateObject?.formValidationProtocol) -// } - if let style = model.style { switch style { case .primary: diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift b/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift deleted file mode 100644 index 63e01b3a..00000000 --- a/MVMCoreUI/Atoms/TextFields/MFTextField+ModelExtension.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// MFTextField+ModelExtension.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 11/19/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import UIKit - -enum TextType: String { - case dropDown = "dropDown" - case password = "password" - case number = "number" - case email = "email" -} -extension MFTextField: ModelMoleculeViewProtocol { - // - public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { -// //TODO: Need to create setWithModel in ViewConstraining View -// #warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.") -// //TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView. -// setUpDefaultWithModel(model, delegateObject, additionalData) -// -// guard let textFieldModel = model as? TextFieldModel, -// let delegateObject = delegateObject else { -// return -// } -// -// if let delegate = delegateObject.formValidationProtocol { -// let formValidator = FormValidator.getFormValidatorFor(delegate: delegate) -// mfTextFieldDelegate = formValidator -// uiTextFieldDelegate = delegateObject.uiTextFieldDelegate -// if let textField = textField { -// MVMCoreUICommonViewsUtility.addDismissToolbar(textField, delegate: uiTextFieldDelegate) -// } -// } -// -// formText = textFieldModel.label as NSString? -// text = textFieldModel.value as NSString? -// if let disabled = textFieldModel.disabled { -// enable(disabled) -// } -// errMessage = textFieldModel.errorMsg -// fieldKey = textFieldModel.fieldKey -// groupName = textFieldModel.groupName -// -// -// switch textFieldModel.type { -// case TextType.dropDown.rawValue: -// dropDownCarrotLabel?.isHidden = true -// hasDropDown = true -// break -// case TextType.password.rawValue: -// textField?.isSecureTextEntry = true -// break -// case TextType.number.rawValue: -// textField?.keyboardType = .numberPad -// break -// case TextType.email.rawValue: -// textField?.keyboardType = .emailAddress -// break -// default: -// print("default") -// } -// -// if let regex = textFieldModel.regex { -// validationBlock = {(enteredValue: String?) -> Bool in -// if let enteredValue = enteredValue { -// return MVMCoreUIUtility.validate(enteredValue, withRegularExpression: regex) -// } -// return true -// } -// } else { -// setDefaultValidationBlock() -// } - } -} - diff --git a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift index b42349c6..92a1e073 100644 --- a/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/MdnEntryField.swift @@ -97,25 +97,25 @@ import MVMCore return MVMCoreUIUtility.validateInternationalMDNString(MDN) } - @objc public override func validateTextField() { + @objc public func validateMDNTextField() -> Bool { -// guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else { -// isValid = true -// return true -// } -// -// let isValid = hasValidMDN() -// -// if isValid { -// showError = false -// -// } else { -// errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") -// showError = true -// UIAccessibility.post(notification: .layoutChanged, argument: textField) -// } -// -// return isValid + guard !shouldValidateMDN, let MDN = mdn, !MDN.isEmpty else { + isValid = true + return true + } + + let isValid = hasValidMDN() + + if isValid { + showError = false + + } else { + errorMessage = errorMessage ?? MVMCoreUIUtility.hardcodedString(withKey: "textfield_phone_format_error_message") + showError = true + UIAccessibility.post(notification: .layoutChanged, argument: textField) + } + + return isValid } @objc public func getContacts(_ sender: Any?) { @@ -186,9 +186,9 @@ import MVMCore proprietorTextDelegate?.textFieldDidEndEditing?(textField) -// if validateTextField() && isNationalMDN { -// textField.text = MVMCoreUIUtility.formatMdn(textField.text) -// } + if validateMDNTextField() && isNationalMDN { + textField.text = MVMCoreUIUtility.formatMdn(textField.text) + } } @objc public func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { diff --git a/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift b/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift deleted file mode 100644 index 0455b689..00000000 --- a/MVMCoreUI/FormUIHelpers/FormValidator+TextFields.swift +++ /dev/null @@ -1,69 +0,0 @@ -// -// MVMCoreUIFormValidator+TextFields.swift -// MVMCoreUI -// -// Created by Suresh, Kamlesh on 3/21/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import Foundation - -//@objc extension FormValidator: MFTextFieldDelegate { -// -// public func dismissFieldInput(_ sender: Any?) { -// -// if let delegate = delegate as? MFTextFieldDelegate { -// delegate.dismissFieldInput?(sender) -// } -// } -// -// public func entryIsValid(_ textfield: MFTextField?) { -// -// MVMCoreDispatchUtility.performBlock(onMainThread: { -// self.enableByValidation() -// if let delegate = self.delegate as? MFTextFieldDelegate { -// delegate.entryIsValid?(textfield) -// } -// }) -// } -// -// public func entryIsInvalid(_ textfield: MFTextField?) { -// -// MVMCoreDispatchUtility.performBlock(onMainThread: { -// self.enableByValidation() -// if let delegate = self.delegate as? MFTextFieldDelegate { -// delegate.entryIsInvalid?(textfield) -// } -// }) -// } -//} -// -// Temporary: Looking to either combine or separate entirely with MFTextFieldDelegate. -//extension FormValidator: ObservingTextFieldDelegate { -// -// public func dismissField(_ sender: Any?) { -// if let delegate = delegate as? MFTextFieldDelegate { -// delegate.dismissFieldInput?(sender) -// } -// } -// -// @nonobjc public func isValid(_ textfield: MFTextField?) { -// -// MVMCoreDispatchUtility.performBlock(onMainThread: { -// self.enableByValidation() -// if let delegate = self.delegate as? MFTextFieldDelegate { -// delegate.entryIsValid?(textfield) -// } -// }) -// } -// -// public func isInvalid(_ textfield: MFTextField?) { -// -// MVMCoreDispatchUtility.performBlock(onMainThread: { -// self.enableByValidation() -// if let delegate = self.delegate as? MFTextFieldDelegate { -// delegate.entryIsInvalid?(textfield) -// } -// }) -// } -//} diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m index ab906bd7..4c6bf8a5 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUICheckBox.m @@ -59,9 +59,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0; } - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { - -// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; - + self.delegateObject = delegateObject; self.fieldKey = [json stringForKey:KeyFieldKey]; self.isRequired = [json boolForKey:KeyRequired]; diff --git a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m index e4c3c38b..8cbb434d 100644 --- a/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m +++ b/MVMCoreUI/Legacy/Views/MVMCoreUISwitch.m @@ -147,8 +147,6 @@ const CGFloat SwitchShakeIntensity = 2; self.json = json; self.delegate = delegateObject; -// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; - NSString *color = [json string:@"onTintColor"]; if (color) { self.onTintColor = [UIColor mfGetColorForHex:color]; diff --git a/MVMCoreUI/Legacy/Views/PrimaryButton.m b/MVMCoreUI/Legacy/Views/PrimaryButton.m index 4ced32ac..0e16ce8e 100644 --- a/MVMCoreUI/Legacy/Views/PrimaryButton.m +++ b/MVMCoreUI/Legacy/Views/PrimaryButton.m @@ -671,7 +671,6 @@ self.validationRequired = [json boolForKey:@"required"]; self.requiredGroupsList = [json array:@"requiredGroups"]; -// [FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol]; self.primaryButtonType = PrimaryButtonTypeCustom; NSString *style = [json string:@"style"]; diff --git a/MVMCoreUI/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Templates/MoleculeListTemplate.swift index 360fc86e..1ea13b4c 100644 --- a/MVMCoreUI/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeListTemplate.swift @@ -15,7 +15,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol public var formValidator: FormValidator? public func validate() { - + // Can override } public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (ListItemModelProtocol & MoleculeModelProtocol))]? From c55a9f3faa4ba331f049e83bcbe27ab968ec6d36 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Tue, 10 Mar 2020 15:42:44 -0400 Subject: [PATCH 12/19] rules should be optional --- MVMCoreUI/FormUIHelpers/FormValidator.swift | 10 +++++++--- MVMCoreUI/Templates/TemplateProtocol.swift | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index daadf81f..b81804e8 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -13,13 +13,13 @@ import MVMCore static var defaultGroupName: String = "default" var extraValidationBlock: (() -> Bool)? - var formRules: [FormGroupRule] + var formRules: [FormGroupRule]? var delegate: FormHolderProtocol? var fieldMolecules: [String: FormFieldProtocol] = [:] var formActionMolecules: [FormActionFieldProtocol] = [] var radioButtonsModelByGroup: [String: RadioButtonSelectionHelper] = [:] - public init(_ formRules: [FormGroupRule]) { + public init(_ formRules: [FormGroupRule]?) { self.formRules = formRules } @@ -50,8 +50,12 @@ import MVMCore } public func validate() { + guard let formRules = formRules else { + return + } formActionMolecules.forEach { (actionModel) in - if let groupName = actionModel.groupName, let formRule = formRules.first(where: { $0.groupName == groupName }) { + if let groupName = actionModel.groupName, + let formRule = formRules.first(where: { $0.groupName == groupName }) { validate(groupName, actionModel, formRule.rules) } } diff --git a/MVMCoreUI/Templates/TemplateProtocol.swift b/MVMCoreUI/Templates/TemplateProtocol.swift index 1e3dbdcc..fcb6bde2 100644 --- a/MVMCoreUI/Templates/TemplateProtocol.swift +++ b/MVMCoreUI/Templates/TemplateProtocol.swift @@ -21,7 +21,8 @@ public extension TemplateProtocol where Self: MFViewController { let decoder = JSONDecoder() let templateModel = try decoder.decode(TemplateModel.self, from: data) - if self.formValidator == nil, let rules = templateModel.formRules { + if self.formValidator == nil { + let rules = templateModel.formRules self.formValidator = FormValidator(rules) } self.templateModel = templateModel From dfc9157c2650d7858a57ca2f7d9bdef290d2b81a Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 11 Mar 2020 10:45:17 -0400 Subject: [PATCH 13/19] nil check --- MVMCoreUI/FormUIHelpers/FormValidator.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index b81804e8..f2cdb8ea 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -26,7 +26,9 @@ import MVMCore public func insertMolecule(_ molecule: FormItemProtocol) { if var molecule = molecule as? FormFieldProtocol, let fieldKey = molecule.fieldKey { - molecule.baseValue = molecule.formFieldValue() + if molecule.baseValue == nil { + molecule.baseValue = molecule.formFieldValue() + } fieldMolecules[fieldKey] = molecule } if let molecule = molecule as? FormActionFieldProtocol { From 6d3946f0e7541b328130211fe37d942fc34da400 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 13 Mar 2020 11:52:09 -0400 Subject: [PATCH 14/19] anyrequiredmodel --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++++ .../New/Rules/RuleAnyRequiredModel.swift | 23 +++++++++++++++++++ .../OtherHandlers/MoleculeObjectMapping.swift | 1 + 3 files changed, 28 insertions(+) create mode 100644 MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8ece6dd9..aeaac929 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -91,6 +91,7 @@ 0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; }; 0A41BA7F23453A6400D4C0BC /* TextEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */; }; 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */; }; + 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */; }; 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; }; 0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; }; 0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; }; @@ -452,6 +453,7 @@ 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CATransaction+Extension.swift"; sourceTree = ""; }; 0A41BA7E23453A6400D4C0BC /* TextEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEntryField.swift; sourceTree = ""; }; 0A5D59C123AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleGuidelinesProtocol.swift; sourceTree = ""; }; + 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyRequiredModel.swift; sourceTree = ""; }; 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseDropdownEntryField.swift; sourceTree = ""; }; 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = ""; }; 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = ""; }; @@ -807,6 +809,7 @@ 011D95A0240453D0000E3791 /* RuleEqualsModel.swift */, 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, 011D95A4240455DC000E3791 /* FormGroupRule.swift */, + 0A69F610241BDEA700F7231B /* RuleAnyRequiredModel.swift */, ); path = Rules; sourceTree = ""; @@ -1781,6 +1784,7 @@ D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, + 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, D28A838923CCCFCB00DFE4FC /* LinkModel.swift in Sources */, diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift new file mode 100644 index 00000000..0eab62a7 --- /dev/null +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift @@ -0,0 +1,23 @@ +// +// RuleAnyRequiredModel.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 3/13/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + + +public class RuleAnyRequiredModel: RulesProtocol { + + public static var identifier: String = "anyRequired" + public var type: String = RuleRequiredModel.identifier + public var fields: [String] + + public func isValid(_ formField: FormFieldProtocol) -> Bool { + guard let value = formField.formFieldValue() else { return false } + + return true + } +} diff --git a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift index 17a9972c..640dbebe 100644 --- a/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift +++ b/MVMCoreUI/OtherHandlers/MoleculeObjectMapping.swift @@ -124,6 +124,7 @@ import Foundation // Helper models try? ModelRegistry.register(RuleRequiredModel.self) + try? ModelRegistry.register(RuleAnyRequiredModel.self) try? ModelRegistry.register(RuleAnyValueChangedModel.self) try? ModelRegistry.register(RuleAllValueChangedModel.self) try? ModelRegistry.register(RuleEqualsModel.self) From 62fd6c988eb3428163e6437af315e609cd941ad9 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 13 Mar 2020 12:13:32 -0400 Subject: [PATCH 15/19] merge --- MVMCoreUI.xcodeproj/project.pbxproj | 25 +++++++------------ .../{New => }/FormActionFieldProtocol.swift | 0 .../{New => }/FormFieldProtocol.swift | 0 .../{New => }/FormHolderProtocol.swift | 0 .../{New => }/FormItemProtocol.swift | 0 .../{New => }/FormProtocol.swift | 0 .../{New => Rules}/Rules/FormGroupRule.swift | 0 .../Rules/RuleAllValueChangedModel.swift | 0 .../Rules/RuleAnyValueChangedModel.swift | 0 .../Rules/RuleEqualsModel.swift | 0 .../{New => Rules}/Rules/RuleRegexModel.swift | 0 .../Rules/RuleRequiredModel.swift | 0 .../{New => Rules}/Rules/RulesProtocol.swift | 0 .../{New => }/ValidProtocol.swift | 0 14 files changed, 9 insertions(+), 16 deletions(-) rename MVMCoreUI/FormUIHelpers/{New => }/FormActionFieldProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => }/FormFieldProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => }/FormHolderProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => }/FormItemProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => }/FormProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/FormGroupRule.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RuleAllValueChangedModel.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RuleAnyValueChangedModel.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RuleEqualsModel.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RuleRegexModel.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RuleRequiredModel.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => Rules}/Rules/RulesProtocol.swift (100%) rename MVMCoreUI/FormUIHelpers/{New => }/ValidProtocol.swift (100%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b5985e36..e795475d 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -779,20 +779,6 @@ path = ModelProtocols; sourceTree = ""; }; - 011D9583240422BF000E3791 /* New */ = { - isa = PBXGroup; - children = ( - 011D958A24042794000E3791 /* Rules */, - 011D95882404249B000E3791 /* FormProtocol.swift */, - 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */, - 011D95AA2405C553000E3791 /* FormItemProtocol.swift */, - 011D958624042492000E3791 /* FormFieldProtocol.swift */, - 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */, - 011D9601240DA20A000E3791 /* ValidProtocol.swift */, - ); - path = New; - sourceTree = ""; - }; 011D958A24042794000E3791 /* Rules */ = { isa = PBXGroup; children = ( @@ -804,7 +790,8 @@ 011D95A2240453F8000E3791 /* RuleRegexModel.swift */, 011D95A4240455DC000E3791 /* FormGroupRule.swift */, ); - path = Rules; + name = Rules; + path = Rules/Rules; sourceTree = ""; }; 012A88EF23985E0100FE3DA1 /* CustomPrimitives */ = { @@ -826,8 +813,14 @@ 01C74D87224298E2009C25A3 /* FormUIHelpers */ = { isa = PBXGroup; children = ( - 011D9583240422BF000E3791 /* New */, + 011D95882404249B000E3791 /* FormProtocol.swift */, + 011D95AC2406BB57000E3791 /* FormHolderProtocol.swift */, + 011D95AA2405C553000E3791 /* FormItemProtocol.swift */, + 011D958624042492000E3791 /* FormFieldProtocol.swift */, + 011D95A824057AC7000E3791 /* FormActionFieldProtocol.swift */, + 011D9601240DA20A000E3791 /* ValidProtocol.swift */, 0105618A224BBE7700E1557D /* FormValidator.swift */, + 011D958A24042794000E3791 /* Rules */, ); path = FormUIHelpers; sourceTree = ""; diff --git a/MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/FormActionFieldProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/FormActionFieldProtocol.swift rename to MVMCoreUI/FormUIHelpers/FormActionFieldProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/FormFieldProtocol.swift rename to MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift b/MVMCoreUI/FormUIHelpers/FormHolderProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/FormHolderProtocol.swift rename to MVMCoreUI/FormUIHelpers/FormHolderProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift b/MVMCoreUI/FormUIHelpers/FormItemProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/FormItemProtocol.swift rename to MVMCoreUI/FormUIHelpers/FormItemProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/FormProtocol.swift b/MVMCoreUI/FormUIHelpers/FormProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/FormProtocol.swift rename to MVMCoreUI/FormUIHelpers/FormProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/FormGroupRule.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/FormGroupRule.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleAllValueChangedModel.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAllValueChangedModel.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyValueChangedModel.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleEqualsModel.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleRegexModel.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RuleRequiredModel.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRequiredModel.swift diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift rename to MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift diff --git a/MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift b/MVMCoreUI/FormUIHelpers/ValidProtocol.swift similarity index 100% rename from MVMCoreUI/FormUIHelpers/New/ValidProtocol.swift rename to MVMCoreUI/FormUIHelpers/ValidProtocol.swift From f888358336380e3628fcb37c547c1a9410784750 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Fri, 13 Mar 2020 12:31:32 -0400 Subject: [PATCH 16/19] refactor --- MVMCoreUI/Atoms/TextFields/TextEntryField.swift | 2 +- MVMCoreUI/FormUIHelpers/FormValidator.swift | 2 +- .../Rules/Rules/RuleAnyValueChangedModel.swift | 4 ++-- MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift | 4 ++-- MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift index 993aed59..5df115d9 100644 --- a/MVMCoreUI/Atoms/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atoms/TextFields/TextEntryField.swift @@ -44,7 +44,7 @@ import UIKit private var observingForChange: Bool = false - /// Validate on each entry in the textField. Default: false + /// Validate on each entry in the textField. Default: true public var validateEachCharacter: Bool = true /// Validate when user resigns editing. Default: true diff --git a/MVMCoreUI/FormUIHelpers/FormValidator.swift b/MVMCoreUI/FormUIHelpers/FormValidator.swift index f2cdb8ea..8977fad5 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator.swift @@ -66,7 +66,7 @@ import MVMCore public func validate(_ groupName: String, _ actionModel: FormActionFieldProtocol, _ rules: [RulesProtocol]) { var valid = true for rule in rules { - valid = valid && rule.isValid(self) + valid = valid && rule.isValid(fieldMolecules) if !valid { break } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift index f52dd92d..042243db 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleAnyValueChangedModel.swift @@ -18,9 +18,9 @@ public class RuleAnyValueChangedModel: RulesProtocol { return formField.baseValue != formField.formFieldValue() } - public func isValid(_ formValidator: FormValidator) -> Bool { + public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { for formKey in fields { - guard let formField = formValidator.formField(for: formKey) else { + guard let formField = fieldMolecules[formKey] else { continue } if isValid(formField) { diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift index ac148a29..e6b338a4 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleEqualsModel.swift @@ -18,11 +18,11 @@ public class RuleEqualsModel: RulesProtocol { return false } - public func isValid(_ formValidator: FormValidator) -> Bool { + public func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { var valid = true var compareValue: AnyHashable? for formKey in fields { - guard let formField = formValidator.formField(for: formKey) else { + guard let formField = fieldMolecules[formKey] else { continue } diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift index 16fe77b3..4c4a716d 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RulesProtocol.swift @@ -16,7 +16,7 @@ public enum RulesCodingKey: String, CodingKey { public protocol RulesProtocol: ModelProtocol { var type: String { get set } var fields: [String] { get set } - func isValid(_ formValidator: FormValidator) -> Bool + func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool func isValid(_ formField: FormFieldProtocol) -> Bool func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) } @@ -35,10 +35,10 @@ public extension RulesProtocol { return "\(RulesProtocol.self)" } - func isValid(_ formValidator: FormValidator) -> Bool { + func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool { var valid = true for formKey in fields { - guard let formField = formValidator.formField(for: formKey) else { + guard let formField = fieldMolecules[formKey] else { continue } let fieldValidity = isValid(formField) From 227248afe014fdaa738274260cbceb229a1d2c2f Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 13 Mar 2020 15:16:19 -0400 Subject: [PATCH 17/19] logic for anyRequired --- .../New/Rules/RuleAnyRequiredModel.swift | 30 +++++++++++++++++-- .../New/Rules/RulesProtocol.swift | 13 ++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift index 0eab62a7..af6f9095 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RuleAnyRequiredModel.swift @@ -10,14 +10,40 @@ import UIKit public class RuleAnyRequiredModel: RulesProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- public static var identifier: String = "anyRequired" public var type: String = RuleRequiredModel.identifier public var fields: [String] - + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public func isValid(_ formField: FormFieldProtocol) -> Bool { guard let value = formField.formFieldValue() else { return false } - return true + if let valueString = value as? String { + return valueString.count > 0 + + } else if let valueBool = value as? Bool { + return valueBool + } + + return false + } + + public func isValid(_ formValidator: FormValidator) -> Bool { + + for formKey in fields { + guard let formField = formValidator.formField(for: formKey) else { continue } + + if isValid(formField) { + return true + } + } + return false } } diff --git a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift index 16fe77b3..b666b895 100644 --- a/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/New/Rules/RulesProtocol.swift @@ -18,6 +18,7 @@ public protocol RulesProtocol: ModelProtocol { var fields: [String] { get set } func isValid(_ formValidator: FormValidator) -> Bool func isValid(_ formField: FormFieldProtocol) -> Bool +// func isValid(_ fieldMolecules: [String: FormFieldProtocol]) -> Bool func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) } @@ -36,22 +37,22 @@ public extension RulesProtocol { } func isValid(_ formValidator: FormValidator) -> Bool { + var valid = true + for formKey in fields { - guard let formField = formValidator.formField(for: formKey) else { - continue - } + guard let formField = formValidator.formField(for: formKey) else { continue } let fieldValidity = isValid(formField) setValid(formField, fieldValidity) valid = valid && fieldValidity } + return valid } func setValid(_ formField: FormFieldProtocol, _ isValid: Bool) { - guard let formFieldValid = formField as? ValidProtocol else { - return - } + guard let formFieldValid = formField as? ValidProtocol else { return } + formFieldValid.setValidity(isValid) } } From 86d2669beccee6fb32c84a4207c7eaca59a469c6 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 13 Mar 2020 18:05:01 -0400 Subject: [PATCH 18/19] changing so that page does not break if server doesn't send the value --- MVMCoreUI/Molecules/Items/DropDownListItemModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift b/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift index 99d493b8..0cd2f5ef 100644 --- a/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift +++ b/MVMCoreUI/Molecules/Items/DropDownListItemModel.swift @@ -51,7 +51,7 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - molecules = try typeContainer.decodeModels2D(codingKey: .molecules) + molecules = try typeContainer.decodeModels2DIfPresent(codingKey: .molecules) ?? [[]] dropDown = try typeContainer.decode(ItemDropdownEntryFieldModel.self, forKey: .dropDown) try super.init(from: decoder) } From dd19a51417bdf521533178be9a5e189a1a11b36b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Fri, 13 Mar 2020 19:03:12 -0400 Subject: [PATCH 19/19] additional change for empty --- MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift index f9b9d976..6b6f5a32 100644 --- a/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift +++ b/MVMCoreUI/Molecules/Items/DropDownFilterTableViewCell.swift @@ -30,7 +30,8 @@ import UIKit let self = self, let index = self.dropDown.pickerData.firstIndex(of: newValue), let dropListItemJSON = (self.listItemModel as? DropDownListItemModel).toJSON(), - let json2d = dropListItemJSON.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]] + let json2d = dropListItemJSON.optionalArrayForKey("molecules") as? [[[AnyHashable: Any]]], + !json2d.isEmpty && !(json2d.first?.isEmpty ?? false) else { return } if self.previousIndex != NSNotFound {