Closed andrewhavens closed 9 years ago
This is not in XLForm, but I had to do this in an app. Here's how I managed it... I guess it could be done internally using something like multiple: true
... Could be cool
# MyFormScreen
{
title: 'Some title',
name: :multiple_cell,
type: :selector_push,
view_controller_class: MySubFormScreen,
value_transformer: MySubFormTransformer,
}
# MySubFormScreen
class MySubFormScreen < PM::TableScreen
attr_accessor :rowDescriptor # don't forget this one !
def table_data
SomeArray.map do |stuff|
{
title: stuff.name,
action: 'select:',
arguments: { stuff: stuff.name },
accessory_type: rowDescriptor.value && rowDescriptor.value.include?(stuff.name) ? :checkmark : :none
}
end
def select(arguments, index_path)
rowDescriptor.value ||= []
if rowDescriptor.value.include?(arguments[:skill])
rowDescriptor.value.delete(arguments[:skill])
else
rowDescriptor.value << arguments[:skill]
end
update_table_data([index_path])
end
end
# MySubFormTransformer < PM::ValueTransformer
def transformed_value(value)
return nil if value.nil?
value.join(', ')
end
end
and if you call values
after selecting multiple items, you will get something like
{
multiple_cell: [ 'one', 'two' ]
}
So, it was way easier than that... Simply use :multiple_selector or :multiple_selector_inline and you are done !
Ex: https://github.com/bmichotte/ProMotion-XLForm/blob/master/app/screens/test_form_screen.rb#L118
@bmichotte Nice! :+1: Unfortunately, that still would not work for me because I needed each option to be a custom table cell. Is there a way to specify a custom cell instead of a title? Something like...
rose = FlowerModel.new(name: 'rose', color: '#FF0000')
violet = FlowerModel.new(name: 'violet', color: '#0000FF')
{
title: 'Multiple',
name: :multiple,
type: :multiple_selector,
options: {
:roses => { cell_class: FlowerTableCell, properties: { flower: rose } },
:violets => { cell_class: FlowerTableCell, properties: { flower: violet } },
# etc...
}
},
The code that I ended up with looked something like this. It seemed like a lot of work to create a custom table cell class, but I was not able to subclass XLFormBaseCell. I also could not figure out how to pass the model instance to the cell.
# table data
cells: flowers.map do |flower|
{
type: :check,
cell_class: FlowerTableCell,
name: "flower_#{flower.id}",
title: flower.name,
}
end
# custom cell class
class FlowerTableCell < UITableViewCell
attr_accessor :flower, :rowDescriptor
def setRowDescriptor(rowDescriptor)
@rowDescriptor = rowDescriptor
update
end
def formDescriptorCellCanBecomeFirstResponder
false
end
def formViewController
return @formViewController if @formViewController
responder = self
while (responder)
if (responder.isKindOfClass(UIViewController))
@formViewController = responder
return @formViewController
end
responder = responder.nextResponder
end
return nil
end
# Update based on cell data
def update
rowDescriptor.value = false if rowDescriptor.value == 0
rowDescriptor.value = true if rowDescriptor.value == 1
# TODO: figure out how to fetch data from model instance
imageView.image = rmq.image.resource('icons/flower')
textLabel.text = rowDescriptor.title
display_checkmark
end
def layoutSubviews
super
imageView.bounds = [[0, 0], [35, 35]]
end
def formDescriptorCellDidSelectedWithFormController(controller)
toggle_checked_value
display_checkmark
formViewController.tableView.selectRowAtIndexPath(nil, animated: true, scrollPosition: UITableViewScrollPositionNone)
end
def toggle_checked_value
rowDescriptor.value = rowDescriptor.value == true ? false : true
end
def display_checkmark
if rowDescriptor.value == true
self.accessoryType = UITableViewCellAccessoryCheckmark
else
self.accessoryType = UITableViewCellAccessoryNone
end
end
end
if you use
gem "ProMotion-XLForm", path: '/Users/benjamin/workspace/ProMotion-XLForm'
you could simplify FlowerTableCell
by extending PM::XLFormCell
(which include PM::TableViewCellModule
) with something like
# table data
cells: flowers.map do |flower|
{
type: :check,
cell_class: FlowerTableCell,
name: "flower_#{flower.id}",
title: flower.name,
flower: flower
}
end
class FlowerTableCell < PM::XLFormCell
attr_accessor :flower
def setup(data_cell, screen)
super
self.flower = data_cell[:flower]
end
end
The rest of the cell is quite "specific" and should stay (you can remove setRowDescriptor
, formViewController
). I think you can also remove layoutSubviews
and move this on setup
Instead of using self.rowDescriptor.value
, you can use self.value
I want to create a section of options that allow multiple rows to be checked. For the resulting value, I would like an array of values:
However, the only way I can figure out how to get this to work looks like this:
...and returns the following hash:
Is there a way that I can display this list so that the selected values are returned as an array?