Skip to content

Commit

Permalink
Support mapping items names to values
Browse files Browse the repository at this point in the history
Ex
row.items = [["name", value], ["name2", value2]]
  • Loading branch information
clayallsopp committed Nov 5, 2012
1 parent 0fcfd03 commit bec0b40
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 14 deletions.
43 changes: 43 additions & 0 deletions lib/formotion/row_type/items_mapper.rb
@@ -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
12 changes: 6 additions & 6 deletions lib/formotion/row_type/options_row.rb
Expand Up @@ -2,23 +2,25 @@ module Formotion
module RowType module RowType
class OptionsRow < Base class OptionsRow < Base
include BW::KVO include BW::KVO
include RowType::ItemsMapper


def build_cell(cell) def build_cell(cell)
cell.selectionStyle = UITableViewCellSelectionStyleNone 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 segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar
cell.accessoryView = cell.editingAccessoryView = segmentedControl cell.accessoryView = cell.editingAccessoryView = segmentedControl


segmentedControl.when(UIControlEventValueChanged) do segmentedControl.when(UIControlEventValueChanged) do
break_with_semaphore do break_with_semaphore do
row.value = row.items[segmentedControl.selectedSegmentIndex] row.value = value_for_name_index(segmentedControl.selectedSegmentIndex)
end end
end end
observe(self.row, "value") do |old_value, new_value| observe(self.row, "value") do |old_value, new_value|
break_with_semaphore do break_with_semaphore do
if row.value if row.value
segmentedControl.selectedSegmentIndex = row.items.index(row.value) segmentedControl.selectedSegmentIndex = name_index_of_value(row.value)
else else
segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment
end end
Expand All @@ -27,8 +29,6 @@ def build_cell(cell)


nil nil
end end


end end
end end
end end
25 changes: 18 additions & 7 deletions lib/formotion/row_type/picker_row.rb
Expand Up @@ -3,9 +3,11 @@
module Formotion module Formotion
module RowType module RowType
class PickerRow < StringRow class PickerRow < StringRow
include RowType::ItemsMapper


def after_build(cell) def after_build(cell)
self.row.text_field.inputView = self.picker self.row.text_field.inputView = self.picker
self.row.text_field.text = name_for_value(row.value).to_s
end end


def picker def picker
Expand All @@ -17,8 +19,8 @@ def picker
picker.delegate = self picker.delegate = self


if self.row.value if self.row.value
picker_row = self.row.items.index(row.value) picker_row = name_index_of_value(row.value)
if picker_row if picker_row != nil
picker.selectRow(picker_row, inComponent:0, animated:false) picker.selectRow(picker_row, inComponent:0, animated:false)
else else
warn "Picker item '#{row.value}' not found in #{row.items.inspect} for '#{row.key}'" warn "Picker item '#{row.value}' not found in #{row.items.inspect} for '#{row.key}'"
Expand All @@ -34,21 +36,30 @@ def numberOfComponentsInPickerView(pickerView)
end end


def pickerView(pickerView, numberOfRowsInComponent:component) def pickerView(pickerView, numberOfRowsInComponent:component)
self.row.items.size self.items.size
end end


def pickerView(pickerView, titleForRow:index, forComponent:component) def pickerView(pickerView, titleForRow:index, forComponent:component)
self.row.items[index] self.item_names[index]
end end


def pickerView(pickerView, didSelectRow:index, inComponent:component) def pickerView(pickerView, didSelectRow:index, inComponent:component)
update_row(self.row.items[index]) update_text_field(value_for_name_index(index))
end end


def update_row(value) def on_change(text_field)
self.row.text_field && self.row.text_field.text = value 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 end


def row_value
name_for_value(row.value)
end
end end
end end
end end
7 changes: 6 additions & 1 deletion lib/formotion/row_type/string_row.rb
Expand Up @@ -69,12 +69,17 @@ def setText(text)
end end


field.placeholder = row.placeholder field.placeholder = row.placeholder
field.text = row.value.to_s field.text = row_value
cell.addSubview(field) cell.addSubview(field)
field field


end end


# overriden in subclasses
def row_value
row.value.to_s
end

def add_callbacks(field) def add_callbacks(field)
if row.on_enter_callback if row.on_enter_callback
field.should_return? do |text_field| field.should_return? do |text_field|
Expand Down
12 changes: 12 additions & 0 deletions spec/row_type/options_spec.rb
Expand Up @@ -42,4 +42,16 @@
@row.value = nil @row.value = nil
cell.accessoryView.selectedSegmentIndex.should == UISegmentedControlNoSegment cell.accessoryView.selectedSegmentIndex.should == UISegmentedControlNoSegment
end 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 end
12 changes: 12 additions & 0 deletions spec/row_type/picker_spec.rb
Expand Up @@ -23,4 +23,16 @@


@row.text_field.text.should == "Motion" @row.text_field.text.should == "Motion"
end 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 end

0 comments on commit bec0b40

Please sign in to comment.