move titles into behavior. changed selectable protocol name.

This commit is contained in:
Kevin G Christiano 2021-06-21 15:27:22 -04:00
parent 98be36c711
commit cf8d0f967e
3 changed files with 83 additions and 20 deletions

View File

@ -7,7 +7,7 @@
// //
@objcMembers public class CheckboxModel: MoleculeModelProtocol, SelectableModel, FormFieldProtocol { @objcMembers public class CheckboxModel: MoleculeModelProtocol, SelectableMoleculeModel, FormFieldProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------

View File

@ -7,7 +7,7 @@
// //
public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol { public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableModelProtocol, SelectableMoleculeModel {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -53,11 +53,23 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol, EnableableMo
} }
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Methods // MARK: - Form Valdiation
//-------------------------------------------------- //--------------------------------------------------
public func formFieldValue() -> AnyHashable? { state } public func formFieldValue() -> AnyHashable? { state }
//--------------------------------------------------
// MARK: - Selectable Protocol
//--------------------------------------------------
public func select(as isSelected: Bool) {
state = isSelected
}
public var selectedValue: Bool {
state
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Initializer // MARK: - Initializer
//-------------------------------------------------- //--------------------------------------------------

View File

@ -6,7 +6,10 @@
// Copyright © 2021 Verizon Wireless. All rights reserved. // Copyright © 2021 Verizon Wireless. All rights reserved.
// //
public protocol SelectableModel { /// Protocol to apply to any model of a UI Control with a binary on/off nature.
///
/// Example classes: Checkbox or Switch.
public protocol SelectableMoleculeModel {
var selectedValue: Bool { get } var selectedValue: Bool { get }
func select(as isSelected: Bool) func select(as isSelected: Bool)
} }
@ -14,16 +17,48 @@ public protocol SelectableModel {
public class SelectAllBoxesBehaviorModel: PageBehaviorModelProtocol { public class SelectAllBoxesBehaviorModel: PageBehaviorModelProtocol {
public class var identifier: String { "pageSelectAllBoxesBehavior" } public class var identifier: String { "pageSelectAllBoxesBehavior" }
public var shouldAllowMultipleInstances: Bool { false } public var shouldAllowMultipleInstances: Bool { false }
public var selectAllTitle: String = "Select All"
public var deselectAllTitle: String = "Deselect All"
public init() { } public init() { }
//--------------------------------------------------
// MARK: - Codable
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case selectAllTitle
case deselectAllTitle
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let selectAllTitle = try typeContainer.decodeIfPresent(String.self, forKey: .selectAllTitle) {
self.selectAllTitle = selectAllTitle
}
if let deselectAllTitle = try typeContainer.decodeIfPresent(String.self, forKey: .deselectAllTitle) {
self.deselectAllTitle = deselectAllTitle
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(selectAllTitle, forKey: .selectAllTitle)
try container.encode(deselectAllTitle, forKey: .deselectAllTitle)
}
} }
/// Selects all the control models presented on a page.
public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior { public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
var didSelectAll = false /// Status of the select all behavior. Initially false as the action has not been enaged.
var selectAllState = false
var model: PageBehaviorModelProtocol
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Delegate // MARK: - Delegate
@ -35,7 +70,8 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior {
// MARK: - Init // MARK: - Init
//-------------------------------------------------- //--------------------------------------------------
public required init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) { required public init(model: PageBehaviorModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
self.model = model
self.delegate = delegateObject self.delegate = delegateObject
} }
@ -43,31 +79,40 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior {
// MARK: - Custom Action // MARK: - Custom Action
//-------------------------------------------------- //--------------------------------------------------
// To select or deselect all controls adhereing to /// To select or deselect all controls adhereing to `SelectableMoleculeModel`
///
/// - Parameters:
/// - actionType: The action type of the passed action model.
/// - information: information of the passed action model.
/// - additionalData: Additional information of the
/// - Returns: Boolean determines if the action has been handled.
public func handleAction(type actionType: String?, information: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) -> Bool { public func handleAction(type actionType: String?, information: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?) -> Bool {
// Verify we have the correct action type and necessary values.
guard actionType == "selectAllBoxes", guard actionType == "selectAllBoxes",
let selectableModels: [SelectableModel] = delegate?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(), let selectableModels: [SelectableMoleculeModel] = delegate?.moleculeDelegate?.getRootMolecules().allMoleculesOfType(),
!selectableModels.isEmpty !selectableModels.isEmpty,
let model = model as? SelectAllBoxesBehaviorModel
else { return false } else { return false }
didSelectAll.toggle() // Flip the selected state of the behavior.
selectAllState.toggle()
let navButtonTitle: String? = (didSelectAll ? information!["deSelectAllTitle"] : information!["selectAllTitle"]) as? String
// Iterate through selectable molecules.
for selectableModel in selectableModels { for selectableModel in selectableModels {
if toSelect(model: selectableModel) || toDeselect(model: selectableModel) { if toSelect(model: selectableModel) || toDeselect(model: selectableModel) {
selectableModel.select(as: didSelectAll) selectableModel.select(as: selectAllState)
} }
} }
// Get title to update the nav button title.
let navButtonTitle: String? = selectAllState ? model.deselectAllTitle : model.selectAllTitle
MVMCoreDispatchUtility.performBlock(onMainThread: { MVMCoreDispatchUtility.performBlock(onMainThread: {
// TODO: move to protocol function instead
guard let controller = self.delegate?.moleculeDelegate as? ViewController else { return } guard let controller = self.delegate?.moleculeDelegate as? ViewController else { return }
controller.handleNewDataAndUpdateUI() controller.handleNewDataAndUpdateUI()
if MVMCoreUIUtility.getCurrentVisibleController() == controller { if MVMCoreUIUtility.getCurrentVisibleController() == controller {
// Update navigation bar if showing.
controller.navigationItem.rightBarButtonItem?.title = navButtonTitle controller.navigationItem.rightBarButtonItem?.title = navButtonTitle
controller.manager?.refreshNavigationUI() controller.manager?.refreshNavigationUI()
} }
@ -76,11 +121,17 @@ public class SelectAllBoxesBehavior: PageCustomActionHandlerBehavior {
return true return true
} }
func toSelect(model: SelectableModel) -> Bool { /// Convenience function making it easier to read if a current selectable model should be acted on.
didSelectAll && !model.selectedValue /// - Parameter model: A model object assined to the SelectableModel protocol
/// - Returns: Boolean determining if the passed model should be selected.
func toSelect(model: SelectableMoleculeModel) -> Bool {
selectAllState && !model.selectedValue
} }
func toDeselect(model: SelectableModel) -> Bool { /// Convenience function making it easier to read if a current selectable model should be acted on.
!didSelectAll && model.selectedValue /// - Parameter model: A model object assined to the SelectableModel protocol
/// - Returns: Boolean determining if the passed model should be deselected.
func toDeselect(model: SelectableMoleculeModel) -> Bool {
!selectAllState && model.selectedValue
} }
} }