new Checkboxes/RadioButtons

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-08-20 08:45:04 -05:00
parent ffd5242cde
commit 13f9776a4f
5 changed files with 282 additions and 0 deletions

View File

@ -594,6 +594,10 @@
EA6642932BCDA97D00D81DC4 /* TileContainerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */; };
EA6E8B952B504A43000139B4 /* ButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B942B504A43000139B4 /* ButtonGroup.swift */; };
EA6E8B972B504A4D000139B4 /* ButtonGroupModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */; };
EA7AE5472C73C01A00107C74 /* CheckboxesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */; };
EA7AE5492C7403DC00107C74 /* Checkboxes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE5482C7403DC00107C74 /* Checkboxes.swift */; };
EA7AE54B2C74CACA00107C74 /* RadioButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */; };
EA7AE54D2C74CAD700107C74 /* RadioButtonsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */; };
EA7D81602B2B6E6800D29F9E /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D815F2B2B6E6800D29F9E /* Icon.swift */; };
EA7D81622B2B6E7F00D29F9E /* IconModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D81612B2B6E7F00D29F9E /* IconModel.swift */; };
EA7D81642B2BABCB00D29F9E /* TooltipModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7D81632B2BABCB00D29F9E /* TooltipModel.swift */; };
@ -1223,6 +1227,10 @@
EA6642922BCDA97D00D81DC4 /* TileContainerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileContainerModel.swift; sourceTree = "<group>"; };
EA6E8B942B504A43000139B4 /* ButtonGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroup.swift; sourceTree = "<group>"; };
EA6E8B962B504A4D000139B4 /* ButtonGroupModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupModel.swift; sourceTree = "<group>"; };
EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxesModel.swift; sourceTree = "<group>"; };
EA7AE5482C7403DC00107C74 /* Checkboxes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkboxes.swift; sourceTree = "<group>"; };
EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtons.swift; sourceTree = "<group>"; };
EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButtonsModel.swift; sourceTree = "<group>"; };
EA7D815F2B2B6E6800D29F9E /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; };
EA7D81612B2B6E7F00D29F9E /* IconModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconModel.swift; sourceTree = "<group>"; };
EA7D81632B2BABCB00D29F9E /* TooltipModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TooltipModel.swift; sourceTree = "<group>"; };
@ -2031,8 +2039,12 @@
BBAA4F00243D8E3B005AAD5F /* RadioBoxModel.swift */,
D264FAA6243FE13B00D98315 /* RadioBox.swift */,
0116A4E4228B19640094F3ED /* RadioButtonSelectionHelper.swift */,
EA7AE54C2C74CAD700107C74 /* RadioButtonsModel.swift */,
EA7AE54A2C74CACA00107C74 /* RadioButtons.swift */,
011D95AE2407266E000E3791 /* RadioButtonModel.swift */,
01004F2F22721C3800991ECC /* RadioButton.swift */,
EA7AE5462C73C01A00107C74 /* CheckboxesModel.swift */,
EA7AE5482C7403DC00107C74 /* Checkboxes.swift */,
31BE15CA23D8924C00452370 /* CheckboxModel.swift */,
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
AAC6F166243332E400F295C1 /* RadioSwatchesModel.swift */,
@ -2848,6 +2860,7 @@
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */,
EAA482CE2B45F2F300978105 /* MFLoadingSpinner+VDS.swift in Sources */,
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */,
EA7AE54D2C74CAD700107C74 /* RadioButtonsModel.swift in Sources */,
D2D2FCF3252B72CF0033EAAA /* MoleculeSectionFooter.swift in Sources */,
0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */,
D2E2A99423D8CCBC000B42E6 /* HeadlineBodyLinkModel.swift in Sources */,
@ -3108,6 +3121,7 @@
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */,
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */,
58A9DD7D2AC2103300F5E0B0 /* ReplaceableMoleculeBehaviorModel.swift in Sources */,
EA7AE54B2C74CACA00107C74 /* RadioButtons.swift in Sources */,
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
27F9736A246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift in Sources */,
@ -3265,6 +3279,7 @@
01F2C20327C81F9700DC3D36 /* SubNavManagerNavigationController.swift in Sources */,
EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */,
AA997252247530B100FC7472 /* ListLeftVariableIconAllTextLinks.swift in Sources */,
EA7AE5492C7403DC00107C74 /* Checkboxes.swift in Sources */,
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */,
D2E2A9A323E096B1000B42E6 /* DisableableModelProtocol.swift in Sources */,
@ -3315,6 +3330,7 @@
D2D3957D252FDBCD00047B11 /* ModalSectionListTemplateModel.swift in Sources */,
D2B9D0E4265EEE9D0084735C /* MoleculeListProtocol.swift in Sources */,
D29C559625C099630082E7D6 /* VideoDataManager.swift in Sources */,
EA7AE5472C73C01A00107C74 /* CheckboxesModel.swift in Sources */,
8D4687E2242E2DE400802879 /* ListFourColumnDataUsageListItemModel.swift in Sources */,
D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */,
EA6642912BCDA97300D81DC4 /* TileContainer.swift in Sources */,

View File

@ -0,0 +1,55 @@
//
// Checkboxes.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/19/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class Checkboxes: VDS.CheckboxGroup, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: CheckboxesModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
/// The models for the molecules.
public var checkboxes: [CheckboxLabelModel]?
// MARK: - MoleculeViewProtocol
public func viewModelDidUpdate() {
surface = viewModel.surface
showError = viewModel.showError
isEnabled = viewModel.enabled && !viewModel.readOnly
checkboxes = viewModel.checkboxes
checkboxes?.forEach {
FormValidator.setupValidation(for: $0.checkbox, delegate: delegateObject?.formHolderDelegate)
}
selectorModels = viewModel.checkboxes.toVDSCheckboxItemModel(surface: surface,
delegateObject: delegateObject,
additionalData: additionalData)
}
open func updateView(_ size: CGFloat) {}
open override func didSelect(_ selectedControl: CheckboxItem) {
super.didSelect(selectedControl)
// since the boxes has the state being tracked, we need to update the values here.
if let index = items.firstIndex(where: {$0 === selectedControl}), let selectedBox = checkboxes?[index] {
selectedBox.checkbox.selected = true
}
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}
}

View File

@ -0,0 +1,85 @@
//
// CheckboxesModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/19/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
import VDS
@objcMembers public class CheckboxesModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String { "checkboxes" }
public var id: String = UUID().uuidString
public var backgroundColor: Color?
public var accessibilityIdentifier: String?
public var enabled: Bool = true
public var required: Bool = true
public var readOnly: Bool = false
public var showError: Bool = false
public var inverted: Bool = false
public var surface: Surface { inverted ? .dark : .light }
public var checkboxes: [CheckboxLabelModel]
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case id
case moleculeName
case accessibilityIdentifier
case inverted
case enabled
case readOnly
case showError
case checkboxes
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(with checkboxes: [CheckboxLabelModel]){
self.checkboxes = checkboxes
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier)
showError = try typeContainer.decodeIfPresent(Bool.self, forKey: .showError) ?? false
enabled = try typeContainer.decodeIfPresent(Bool.self, forKey: .enabled) ?? true
readOnly = try typeContainer.decodeIfPresent(Bool.self, forKey: .readOnly) ?? false
if let inverted = try typeContainer.decodeIfPresent(Bool.self, forKey: .inverted) {
self.inverted = inverted
}
checkboxes = try typeContainer.decode([CheckboxLabelModel].self, forKey: .checkboxes)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encodeIfPresent(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier)
try container.encode(readOnly, forKey: .readOnly)
try container.encode(enabled, forKey: .enabled)
try container.encode(inverted, forKey: .inverted)
try container.encode(checkboxes, forKey: .checkboxes)
}
}

View File

@ -0,0 +1,54 @@
//
// RadioButtons.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import VDS
open class RadioButtons: VDS.RadioButtonGroup, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: RadioButtonsModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
/// The models for the molecules.
public var radioButtons: [RadioButtonLabelModel]?
// MARK: - MoleculeViewProtocol
public func viewModelDidUpdate() {
showError = viewModel.showError
isEnabled = viewModel.enabled && !viewModel.readOnly
surface = viewModel.surface
radioButtons = viewModel.radioButtons
selectorModels = viewModel.radioButtons.toVDSRadioButtonItemModel(surface: surface,
delegateObject: delegateObject,
additionalData: additionalData)
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
}
open func updateView(_ size: CGFloat) {}
open override func didSelect(_ selectedControl: RadioButtonItem) {
super.didSelect(selectedControl)
// since the boxes has the state being tracked, we need to update the values here.
if let index = items.firstIndex(where: {$0 === selectedControl}), let selectedBox = radioButtons?[index] {
radioButtons?.forEach { $0.radioButton.state = false }
selectedBox.radioButton.state = true
}
_ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate)
}
}

View File

@ -0,0 +1,72 @@
//
// RadioButtonsModel.swift
// MVMCoreUI
//
// Created by Matt Bruce on 8/20/24.
// Copyright © 2024 Verizon Wireless. All rights reserved.
//
import Foundation
import MVMCore
import VDS
@objcMembers public class RadioButtonsModel: FormFieldModel {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public override static var identifier: String { "radioButtons" }
public var radioButtons: [RadioButtonLabelModel]
//--------------------------------------------------
// MARK: - Form Validation
//--------------------------------------------------
/// Returns the fieldValue of the selected box, otherwise the text of the selected box.
public override func formFieldValue() -> AnyHashable? {
guard enabled else { return nil }
let selectedBox = radioButtons.first { $0.radioButton.state }
return selectedBox?.radioButton.formFieldValue()
}
//--------------------------------------------------
// MARK: - Server Value
//--------------------------------------------------
open override func formFieldServerValue() -> AnyHashable? {
return formFieldValue()
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case radioButtons
}
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(with radioButtons: [RadioButtonLabelModel]){
self.radioButtons = radioButtons
super.init()
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
radioButtons = try typeContainer.decode([RadioButtonLabelModel].self, forKey: .radioButtons)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(radioButtons, forKey: .radioButtons)
}
}