Permalink
Browse files

Support mapping `items` names to values

Ex
row.items = [["name", value], ["name2", value2]]
  • Loading branch information...
clayallsopp committed Nov 5, 2012
1 parent 0fcfd03 commit bec0b4098e3a10b4d8af3767c5408b92d716f982
@@ -0,0 +1,43 @@
+module Formotion
+ module RowType
+ module ItemsMapper
+ def items
+ if !row.items
+ []
+ elsif row.items[0].is_a?(Enumerable)
+ row.items
+ else
+ row.items.map {|i| [i, i]}
+ end
+ end
+
+ def item_names
+ self.items.map { |name, value| name }
+ end
+
+ def item_names_hash
+ hash = {}
+ self.items.each do |name, value|
+ hash[name] = value
+ end
+ hash
+ end
+
+ def name_index_of_value(value)
+ item_names.index(item_names_hash.invert[value])
+ end
+
+ def value_for_name_index(index)
+ item_names_hash[item_names[index]]
+ end
+
+ def value_for_name(name)
+ item_names_hash[name]
+ end
+
+ def name_for_value(value)
+ item_names_hash.invert[value].to_s
+ end
+ end
+ end
+end
@@ -2,23 +2,25 @@ module Formotion
module RowType
class OptionsRow < Base
include BW::KVO
+ include RowType::ItemsMapper
def build_cell(cell)
cell.selectionStyle = UITableViewCellSelectionStyleNone
- segmentedControl = UISegmentedControl.alloc.initWithItems(row.items || [])
- segmentedControl.selectedSegmentIndex = row.items.index(row.value) if row.value
+
+ segmentedControl = UISegmentedControl.alloc.initWithItems(item_names || [])
+ segmentedControl.selectedSegmentIndex = name_index_of_value(row.value) if row.value
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar
cell.accessoryView = cell.editingAccessoryView = segmentedControl
segmentedControl.when(UIControlEventValueChanged) do
break_with_semaphore do
- row.value = row.items[segmentedControl.selectedSegmentIndex]
+ row.value = value_for_name_index(segmentedControl.selectedSegmentIndex)
end
end
observe(self.row, "value") do |old_value, new_value|
break_with_semaphore do
if row.value
- segmentedControl.selectedSegmentIndex = row.items.index(row.value)
+ segmentedControl.selectedSegmentIndex = name_index_of_value(row.value)
else
segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment
end
@@ -27,8 +29,6 @@ def build_cell(cell)
nil
end
-
-
end
end
end
@@ -3,9 +3,11 @@
module Formotion
module RowType
class PickerRow < StringRow
+ include RowType::ItemsMapper
def after_build(cell)
self.row.text_field.inputView = self.picker
+ self.row.text_field.text = name_for_value(row.value).to_s
end
def picker
@@ -17,8 +19,8 @@ def picker
picker.delegate = self
if self.row.value
- picker_row = self.row.items.index(row.value)
- if picker_row
+ picker_row = name_index_of_value(row.value)
+ if picker_row != nil
picker.selectRow(picker_row, inComponent:0, animated:false)
else
warn "Picker item '#{row.value}' not found in #{row.items.inspect} for '#{row.key}'"
@@ -34,21 +36,30 @@ def numberOfComponentsInPickerView(pickerView)
end
def pickerView(pickerView, numberOfRowsInComponent:component)
- self.row.items.size
+ self.items.size
end
def pickerView(pickerView, titleForRow:index, forComponent:component)
- self.row.items[index]
+ self.item_names[index]
end
def pickerView(pickerView, didSelectRow:index, inComponent:component)
- update_row(self.row.items[index])
+ update_text_field(value_for_name_index(index))
end
- def update_row(value)
- self.row.text_field && self.row.text_field.text = value
+ def on_change(text_field)
+ break_with_semaphore do
+ row.value = value_for_name(text_field.text)
+ end
+ end
+
+ def update_text_field(new_value)
+ self.row.text_field.text = name_for_value(new_value)
end
+ def row_value
+ name_for_value(row.value)
+ end
end
end
end
@@ -69,12 +69,17 @@ def setText(text)
end
field.placeholder = row.placeholder
- field.text = row.value.to_s
+ field.text = row_value
cell.addSubview(field)
field
end
+ # overriden in subclasses
+ def row_value
+ row.value.to_s
+ end
+
def add_callbacks(field)
if row.on_enter_callback
field.should_return? do |text_field|
@@ -42,4 +42,16 @@
@row.value = nil
cell.accessoryView.selectedSegmentIndex.should == UISegmentedControlNoSegment
end
+
+ it "should work with name-value items" do
+ @row = Formotion::Row.new(title: "Options", key: :options, type: :options,
+ items: [["First", 1], ["Second", 2]], value: 1)
+ @row.reuse_identifier = 'test'
+ cell = @row.make_cell
+
+ cell.accessoryView.selectedSegmentIndex.should == 0
+
+ @row.value = 2
+ cell.accessoryView.selectedSegmentIndex.should == 1
+ end
end
@@ -23,4 +23,16 @@
@row.text_field.text.should == "Motion"
end
+
+ it "should work with name-value items" do
+ @row = Formotion::Row.new(title: "Picker", key: :picker, type: :picker,
+ items: [["Ruby", 1], ["Motion", 2]], value: 1)
+ @row.reuse_identifier = 'test'
+ cell = @row.make_cell
+
+ @row.text_field.text.should == "Ruby"
+
+ @row.value = 2
+ @row.text_field.text.should == "Motion"
+ end
end

0 comments on commit bec0b40

Please sign in to comment.