refactored to use VDS Dropdown Select

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2024-07-10 14:37:04 -05:00
parent 8bf4a28b0f
commit 981bdac292
2 changed files with 91 additions and 64 deletions

View File

@ -7,19 +7,41 @@
//
import UIKit
import VDS
open class ItemDropdownEntryField: VDS.DropdownSelect, VDSMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Properties
//------------------------------------------------------
open var viewModel: ItemDropdownEntryFieldModel!
open var delegateObject: MVMCoreUIDelegateObject?
open var additionalData: [AnyHashable : Any]?
// Form Validation
var fieldKey: String?
var fieldValue: JSONValue?
var groupName: String?
open var pickerData: [String] = [] {
didSet {
options = pickerData.compactMap({ DropdownOptionModel(text: $0) })
}
}
open class ItemDropdownEntryField: BaseItemPickerEntryField {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var isValid: Bool = false
/// Closure passed here will run as picker changes items.
public var observeDropdownChange: ((String?, String) -> ())?
open var pickerData: [String] = []
public var itemDropdownEntryFieldModel: ItemDropdownEntryFieldModel? {
model as? ItemDropdownEntryFieldModel
}
/// Closure passed here will run upon dismissing the selection picker.
public var observeDropdownSelection: ((String) -> ())?
/// When selecting for first responder, allow initial selected value to appear in empty text field.
public var setInitialValueInTextField = true
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
@ -28,7 +50,7 @@ open class ItemDropdownEntryField: BaseItemPickerEntryField {
super.init(frame: frame)
}
@objc public convenience init() {
@objc public convenience required init() {
self.init(frame: .zero)
}
@ -40,14 +62,36 @@ open class ItemDropdownEntryField: BaseItemPickerEntryField {
@objc required public init?(coder: NSCoder) {
fatalError("ItemDropdownEntryField init(coder:) has not been implemented")
}
required public init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.init(model: model, delegateObject, additionalData)
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
open override func setup() {
super.setup()
publisher(for: .valueChanged)
.sink { [weak self] control in
guard let self, let selectedItem else { return }
viewModel.selectedIndex = control.selectId
observeDropdownSelection?(selectedItem.text)
if let valid = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) {
isValid = valid
}
}.store(in: &subscribers)
dropdownField
.publisher(for: .editingDidBegin)
.sink { [weak self] textField in
guard let self else { return }
setInitialValueFromPicker()
}.store(in: &subscribers)
dropdownField
.publisher(for: .editingDidEnd)
.sink { [weak self] textField in
guard let self else { return }
performDropdownAction()
}.store(in: &subscribers)
}
/// Sets the textField with the first value of the available picker data.
@objc private func setInitialValueFromPicker() {
@ -55,61 +99,36 @@ open class ItemDropdownEntryField: BaseItemPickerEntryField {
guard !pickerData.isEmpty else { return }
if setInitialValueInTextField {
let pickerIndex = pickerView.selectedRow(inComponent: 0)
itemDropdownEntryFieldModel?.selectedIndex = pickerIndex
observeDropdownChange?(text, pickerData[pickerIndex])
text = pickerData[pickerIndex]
let pickerIndex = optionsPicker.selectedRow(inComponent: 0)
viewModel.selectedIndex = pickerIndex
selectId = pickerIndex
observeDropdownChange?(selectedItem?.text, pickerData[pickerIndex])
}
}
@objc override func startEditing() {
super.startEditing()
setInitialValueFromPicker()
public func viewModelDidUpdate() {
pickerData = viewModel.options
labelText = viewModel.title
helperText = viewModel.feedback
isEnabled = viewModel.enabled
isReadOnly = viewModel.readOnly
isRequired = viewModel.required
isSelected = viewModel.selected ?? false
tooltipModel = viewModel.tooltip?.toVDSTooltipModel()
if let index = viewModel.selectedIndex {
selectId = index
optionsPicker.selectRow(index, inComponent: 0, animated: false)
pickerView(optionsPicker, didSelectRow: index, inComponent: 0)
}
FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate)
}
@objc override func endInputing() {
super.endInputing()
guard !pickerData.isEmpty else { return }
observeDropdownSelection?(pickerData[pickerView.selectedRow(inComponent: 0)])
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ItemDropdownEntryFieldModel else { return }
pickerData = model.options
if let index = model.selectedIndex {
self.pickerView.selectRow(index, inComponent: 0, animated: false)
self.pickerView(pickerView, didSelectRow: index, inComponent: 0)
}
func performDropdownAction() {
guard let actionModel = viewModel.action,
!dropdownField.isFirstResponder
else { return }
MVMCoreUIActionHandler.performActionUnstructured(with: actionModel, sourceModel: viewModel, additionalData: additionalData, delegateObject: delegateObject)
}
//--------------------------------------------------
// MARK: - Picker Delegate
//--------------------------------------------------
@objc public override func numberOfComponents(in pickerView: UIPickerView) -> Int { 1 }
@objc public override func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
pickerData.count
}
@objc public func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
guard !pickerData.isEmpty else { return nil }
return pickerData[row]
}
@objc public func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
guard !pickerData.isEmpty else { return }
itemDropdownEntryFieldModel?.selectedIndex = row
observeDropdownChange?(text, pickerData[row])
text = pickerData[row]
}
public func updateView(_ size: CGFloat) { }
}

View File

@ -5,16 +5,18 @@
// Created by Kevin Christiano on 1/22/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import VDS
@objcMembers open class ItemDropdownEntryFieldModel: BaseItemPickerEntryFieldModel {
@objcMembers open class ItemDropdownEntryFieldModel: TextEntryFieldModel {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public override class var identifier: String { "dropDown" }
public var action: ActionModelProtocol?
public var options: [String] = []
public var selectedIndex: Int?
public var tooltip: TooltipModel?
public init(with options: [String], selectedIndex: Int? = nil) {
self.options = options
@ -42,6 +44,8 @@
private enum CodingKeys: String, CodingKey {
case options
case selectedIndex
case action
case tooltip
}
//--------------------------------------------------
@ -58,6 +62,8 @@
self.selectedIndex = selectedIndex
baseValue = options.indices.contains(selectedIndex) ? options[selectedIndex] : nil
}
action = try typeContainer.decodeModelIfPresent(codingKey: .action)
tooltip = try typeContainer.decodeIfPresent(TooltipModel.self, forKey: .tooltip)
}
public override func encode(to encoder: Encoder) throws {
@ -65,5 +71,7 @@
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(options, forKey: .options)
try container.encodeIfPresent(selectedIndex, forKey: .selectedIndex)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encodeIfPresent(tooltip, forKey: .tooltip)
}
}