formotion 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +1 -0
- data/Formotion.gemspec +1 -1
- data/LIST_OF_ROW_TYPES.md +115 -3
- data/README.md +1 -0
- data/examples/KitchenSink/app/app_delegate.rb +16 -2
- data/lib/formotion.rb +9 -1
- data/lib/formotion/form/form.rb +7 -0
- data/lib/formotion/form/form_delegate.rb +2 -2
- data/lib/formotion/patch/ui_image.rb +45 -0
- data/lib/formotion/patch/ui_text_view_placeholder.rb +4 -1
- data/lib/formotion/row/row.rb +13 -1
- data/lib/formotion/row_type/base.rb +13 -4
- data/lib/formotion/row_type/button.rb +1 -0
- data/lib/formotion/row_type/check_row.rb +2 -1
- data/lib/formotion/row_type/date_row.rb +3 -0
- data/lib/formotion/row_type/image_row.rb +6 -1
- data/lib/formotion/row_type/map_row.rb +79 -0
- data/lib/formotion/row_type/multi_choice_row.rb +25 -0
- data/lib/formotion/row_type/object_row.rb +30 -0
- data/lib/formotion/row_type/options_row.rb +2 -2
- data/lib/formotion/row_type/paged_image_row.rb +257 -0
- data/lib/formotion/row_type/picker_row.rb +2 -0
- data/lib/formotion/row_type/slider_row.rb +2 -2
- data/lib/formotion/row_type/static_row.rb +1 -1
- data/lib/formotion/row_type/string_row.rb +3 -7
- data/lib/formotion/row_type/subform_row.rb +3 -1
- data/lib/formotion/row_type/switch_row.rb +2 -2
- data/lib/formotion/row_type/tags_row.rb +172 -0
- data/lib/formotion/row_type/template_row.rb +3 -3
- data/lib/formotion/row_type/text_row.rb +5 -1
- data/lib/formotion/row_type/web_view_row.rb +44 -0
- data/lib/formotion/version.rb +1 -1
- data/resources/tags_row-selected.png +0 -0
- data/resources/tags_row-selected@2x.png +0 -0
- data/resources/tags_row.png +0 -0
- data/resources/tags_row@2x.png +0 -0
- data/spec/form_spec.rb +26 -0
- data/spec/functional/date_row_spec.rb +6 -0
- data/spec/functional/picker_row_spec.rb +5 -0
- data/spec/row_type/back_spec.rb +1 -1
- data/spec/row_type/base_spec.rb +3 -3
- data/spec/row_type/string_spec.rb +14 -3
- data/spec/row_type/subform_spec.rb +1 -1
- data/spec/row_type/submit_spec.rb +1 -1
- data/spec/row_type/text_spec.rb +7 -0
- metadata +17 -6
@@ -8,7 +8,7 @@ module Formotion
|
|
8
8
|
SLIDER_VIEW_TAG = 1200
|
9
9
|
|
10
10
|
def build_cell(cell)
|
11
|
-
cell.selectionStyle = UITableViewCellSelectionStyleNone
|
11
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleNone
|
12
12
|
slideView = UISlider.alloc.initWithFrame(CGRectZero)
|
13
13
|
cell.accessoryView = cell.editingAccessoryView = slideView
|
14
14
|
row.range ||= (1..10)
|
@@ -52,4 +52,4 @@ module Formotion
|
|
52
52
|
|
53
53
|
end
|
54
54
|
end
|
55
|
-
end
|
55
|
+
end
|
@@ -21,6 +21,7 @@ module Formotion
|
|
21
21
|
# Also does the layoutSubviews swizzle trick
|
22
22
|
# to size the UITextField so it won't bump into the titleLabel.
|
23
23
|
def build_cell(cell)
|
24
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
24
25
|
field = UITextField.alloc.initWithFrame(CGRectZero)
|
25
26
|
field.tag = TEXT_FIELD_TAG
|
26
27
|
|
@@ -72,6 +73,7 @@ module Formotion
|
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
76
|
+
field.font = BW::Font.new(row.font) if row.font
|
75
77
|
field.placeholder = row.placeholder
|
76
78
|
field.text = row_value
|
77
79
|
cell.addSubview(field)
|
@@ -131,13 +133,7 @@ module Formotion
|
|
131
133
|
end
|
132
134
|
|
133
135
|
def on_select(tableView, tableViewDelegate)
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
def _on_select(tableView, tableViewDelegate)
|
138
|
-
if !row.editable?
|
139
|
-
return
|
140
|
-
else
|
136
|
+
if row.editable?
|
141
137
|
row.text_field.becomeFirstResponder
|
142
138
|
end
|
143
139
|
end
|
@@ -7,6 +7,7 @@ module Formotion
|
|
7
7
|
LABEL_TAG=1001
|
8
8
|
|
9
9
|
def build_cell(cell)
|
10
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
10
11
|
cell.accessoryType = cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator
|
11
12
|
|
12
13
|
cell.contentView.addSubview(self.display_key_label)
|
@@ -27,6 +28,7 @@ module Formotion
|
|
27
28
|
end
|
28
29
|
|
29
30
|
display_key_label.highlightedTextColor = cell.textLabel.highlightedTextColor
|
31
|
+
nil
|
30
32
|
end
|
31
33
|
|
32
34
|
def update_cell(cell)
|
@@ -52,4 +54,4 @@ module Formotion
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
55
|
-
end
|
57
|
+
end
|
@@ -6,7 +6,7 @@ module Formotion
|
|
6
6
|
include BW::KVO
|
7
7
|
|
8
8
|
def build_cell(cell)
|
9
|
-
cell.selectionStyle = UITableViewCellSelectionStyleNone
|
9
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleNone
|
10
10
|
switchView = UISwitch.alloc.initWithFrame(CGRectZero)
|
11
11
|
switchView.accessibilityLabel = (row.title || "") + " Switch"
|
12
12
|
cell.accessoryView = cell.editingAccessoryView = switchView
|
@@ -27,4 +27,4 @@ module Formotion
|
|
27
27
|
|
28
28
|
end
|
29
29
|
end
|
30
|
-
end
|
30
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
motion_require 'base'
|
2
|
+
|
3
|
+
# ideas and images taken from:
|
4
|
+
# https://github.com/davbeck/TURecipientBar
|
5
|
+
# License: https://github.com/davbeck/TURecipientBar/blob/master/LICENSE.md
|
6
|
+
|
7
|
+
module Formotion
|
8
|
+
module RowType
|
9
|
+
class TagsRow < Base
|
10
|
+
include BW::KVO
|
11
|
+
|
12
|
+
TAGS_VIEW_TAG=1110
|
13
|
+
TAGS_EDIT_VIEW_TAG=1111
|
14
|
+
|
15
|
+
def build_cell(cell)
|
16
|
+
# only show the "plus" when editable
|
17
|
+
add_plus_accessory(cell) if row.editable?
|
18
|
+
|
19
|
+
self.row.value = [] unless self.row.value.is_a?(Array)
|
20
|
+
|
21
|
+
@scroll_view = UIScrollView.alloc.init
|
22
|
+
@scroll_view.tag = row.editable? ? TAGS_EDIT_VIEW_TAG : TAGS_VIEW_TAG
|
23
|
+
@scroll_view.delegate = self
|
24
|
+
@scroll_view.pagingEnabled = false
|
25
|
+
@scroll_view.delaysContentTouches = true
|
26
|
+
@scroll_view.showsHorizontalScrollIndicator = false
|
27
|
+
@scroll_view.showsVerticalScrollIndicator = false
|
28
|
+
@btns = {}
|
29
|
+
cell.addSubview(@scroll_view)
|
30
|
+
|
31
|
+
row.value.each do |t|
|
32
|
+
add_tag(t)
|
33
|
+
end
|
34
|
+
|
35
|
+
cell.swizzle(:layoutSubviews) do
|
36
|
+
def layoutSubviews
|
37
|
+
old_layoutSubviews
|
38
|
+
|
39
|
+
# viewWithTag is terrible, but I think it's ok to use here...
|
40
|
+
edittable = false
|
41
|
+
formotion_field = self.viewWithTag(TAGS_VIEW_TAG)
|
42
|
+
# is an editable row
|
43
|
+
if formotion_field.nil?
|
44
|
+
edittable = true
|
45
|
+
formotion_field = self.viewWithTag(TAGS_EDIT_VIEW_TAG)
|
46
|
+
end
|
47
|
+
field_frame = formotion_field.frame
|
48
|
+
|
49
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
50
|
+
edit_buffer = edittable ? 20.0 : 0.0
|
51
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer - edit_buffer
|
52
|
+
|
53
|
+
# rearrange the tags
|
54
|
+
last = CGRectMake(0.0, 0.0, 0.0, 0.0)
|
55
|
+
formotion_field.subviews.each do |sv|
|
56
|
+
now = sv.frame
|
57
|
+
now.origin.x = (last.origin.x+last.size.width)+5.0
|
58
|
+
now.origin.y = last.origin.y
|
59
|
+
if (now.origin.x+now.size.width)+3.0 > field_frame.size.width
|
60
|
+
now.origin.x = 5.0
|
61
|
+
now.origin.y += last.size.height + 5.0
|
62
|
+
end
|
63
|
+
sv.frame = now
|
64
|
+
last = now
|
65
|
+
end
|
66
|
+
|
67
|
+
# set the height of the scroll box
|
68
|
+
max_height = self.frame.size.height - 3.0
|
69
|
+
field_frame.size.height = last.origin.y + last.size.height + 5.0
|
70
|
+
field_frame.size.height = max_height if field_frame.size.height > max_height
|
71
|
+
field_frame.origin.y = (self.frame.size.height - field_frame.size.height) / 2.0
|
72
|
+
|
73
|
+
formotion_field.frame = field_frame
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def _on_select(tableView, tableViewDelegate)
|
80
|
+
end
|
81
|
+
|
82
|
+
def add_plus_accessory(cell)
|
83
|
+
@add_button ||= begin
|
84
|
+
button = UIButton.buttonWithType(UIButtonTypeContactAdd)
|
85
|
+
button.when(UIControlEventTouchUpInside) do
|
86
|
+
if row.on_tap_callback
|
87
|
+
row.on_tap_callback.call(self.row)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
button
|
91
|
+
end
|
92
|
+
cell.accessoryView = cell.editingAccessoryView = @add_button
|
93
|
+
end
|
94
|
+
|
95
|
+
def image_for_state(state)
|
96
|
+
case state
|
97
|
+
when UIControlStateNormal
|
98
|
+
return UIImage.imageNamed("tags_row.png").stretchableImageWithLeftCapWidth(14, topCapHeight:0)
|
99
|
+
|
100
|
+
when UIControlStateHighlighted, UIControlStateSelected
|
101
|
+
return UIImage.imageNamed("tags_row-selected.png").stretchableImageWithLeftCapWidth(14, topCapHeight:0)
|
102
|
+
|
103
|
+
end
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
def attrib_for_state(state)
|
108
|
+
case state
|
109
|
+
when UIControlStateNormal
|
110
|
+
return { NSFontAttributeName => UIFont.systemFontOfSize(14.0),
|
111
|
+
NSForegroundColorAttributeName => UIColor.blackColor }
|
112
|
+
|
113
|
+
when UIControlStateHighlighted, UIControlStateSelected
|
114
|
+
return { NSFontAttributeName => UIFont.systemFontOfSize(14.0),
|
115
|
+
NSForegroundColorAttributeName => UIColor.whiteColor }
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def add_tag(text)
|
121
|
+
return if @btns.has_key?(text)
|
122
|
+
btn = UIButton.buttonWithType(UIButtonTypeCustom)
|
123
|
+
btn.adjustsImageWhenHighlighted = false
|
124
|
+
btn.contentEdgeInsets = UIEdgeInsetsMake(0.0, 5.0, 0.0, 5.0)
|
125
|
+
textsize = text.sizeWithFont(UIFont.systemFontOfSize(14.0))
|
126
|
+
width = textsize.width+14.0
|
127
|
+
btn.frame = CGRectMake(0.0, 0.0, width, 24.0)
|
128
|
+
[UIControlStateNormal, UIControlStateHighlighted, UIControlStateSelected].each do |state|
|
129
|
+
btn.setBackgroundImage(image_for_state(state), forState:state)
|
130
|
+
attr_text = NSAttributedString.alloc.initWithString(text, attributes:attrib_for_state(state))
|
131
|
+
btn.setAttributedTitle(attr_text, forState:state)
|
132
|
+
end
|
133
|
+
|
134
|
+
if row.editable?
|
135
|
+
btn.addTarget(self, action:'button_click:', forControlEvents:UIControlEventTouchUpInside)
|
136
|
+
end
|
137
|
+
|
138
|
+
btn.translatesAutoresizingMaskIntoConstraints = false
|
139
|
+
@scroll_view.addSubview(btn)
|
140
|
+
unless row.value.include?(text)
|
141
|
+
row.value << text
|
142
|
+
end
|
143
|
+
@btns[text] = btn
|
144
|
+
end
|
145
|
+
|
146
|
+
def button_click(btn)
|
147
|
+
@del_btn = btn
|
148
|
+
App.alert(BW.localized_string("Remove Tag?"), cancel_button_title: NO) do |alert|
|
149
|
+
alert.addButtonWithTitle(YES)
|
150
|
+
alert.delegate = self
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
YES = BW.localized_string("Yes", nil)
|
155
|
+
NO = BW.localized_string("No", nil)
|
156
|
+
|
157
|
+
def alertView(alert_view, clickedButtonAtIndex:button_index)
|
158
|
+
if alert_view.buttonTitleAtIndex(button_index)==NO
|
159
|
+
@del_btn = nil
|
160
|
+
return
|
161
|
+
end
|
162
|
+
@del_btn.removeFromSuperview
|
163
|
+
@btns.delete(@del_btn)
|
164
|
+
row.value.delete(@del_btn.currentAttributedTitle.string)
|
165
|
+
end
|
166
|
+
|
167
|
+
def scrollViewDidScroll(_scroll_view)
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -27,11 +27,11 @@ module Formotion
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def build_cell(cell)
|
30
|
-
cell.selectionStyle = UITableViewCellSelectionStyleBlue
|
30
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
31
31
|
@add_button ||= begin
|
32
32
|
button = UIButton.buttonWithType(UIButtonTypeContactAdd)
|
33
33
|
button.when(UIControlEventTouchUpInside) do
|
34
|
-
self.
|
34
|
+
self._on_select(nil, nil)
|
35
35
|
end
|
36
36
|
button
|
37
37
|
end
|
@@ -125,4 +125,4 @@ module Formotion
|
|
125
125
|
|
126
126
|
end
|
127
127
|
end
|
128
|
-
end
|
128
|
+
end
|
@@ -10,6 +10,7 @@ module Formotion
|
|
10
10
|
attr_accessor :field
|
11
11
|
|
12
12
|
def build_cell(cell)
|
13
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
13
14
|
|
14
15
|
@field = UITextView.alloc.initWithFrame(CGRectZero)
|
15
16
|
field.backgroundColor = UIColor.clearColor
|
@@ -21,6 +22,9 @@ module Formotion
|
|
21
22
|
field.returnKeyType = row.return_key || UIReturnKeyDefault
|
22
23
|
field.autocapitalizationType = row.auto_capitalization if row.auto_capitalization
|
23
24
|
field.autocorrectionType = row.auto_correction if row.auto_correction
|
25
|
+
|
26
|
+
# must be set prior to placeholder!
|
27
|
+
field.font = BW::Font.new(row.font) if row.font
|
24
28
|
field.placeholder = row.placeholder
|
25
29
|
field.enabled = row.editable?
|
26
30
|
|
@@ -87,4 +91,4 @@ module Formotion
|
|
87
91
|
|
88
92
|
end
|
89
93
|
end
|
90
|
-
end
|
94
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
motion_require 'base'
|
2
|
+
|
3
|
+
module Formotion
|
4
|
+
module RowType
|
5
|
+
class WebViewRow < Base
|
6
|
+
|
7
|
+
WEB_VIEW_TAG=1100
|
8
|
+
|
9
|
+
def build_cell(cell)
|
10
|
+
cell.selectionStyle = self.row.selection_style || UITableViewCellSelectionStyleBlue
|
11
|
+
|
12
|
+
@web_view = UIWebView.alloc.init
|
13
|
+
@web_view.loadHTMLString(row.value, baseURL:nil) if row.value
|
14
|
+
@web_view.tag = WEB_VIEW_TAG
|
15
|
+
@web_view.contentMode = UIViewContentModeScaleAspectFit
|
16
|
+
@web_view.backgroundColor = UIColor.clearColor
|
17
|
+
cell.addSubview(@web_view)
|
18
|
+
|
19
|
+
cell.swizzle(:layoutSubviews) do
|
20
|
+
def layoutSubviews
|
21
|
+
old_layoutSubviews
|
22
|
+
|
23
|
+
# viewWithTag is terrible, but I think it's ok to use here...
|
24
|
+
formotion_field = self.viewWithTag(WEB_VIEW_TAG)
|
25
|
+
|
26
|
+
field_frame = formotion_field.frame
|
27
|
+
field_frame.origin.y = 10
|
28
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
29
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer
|
30
|
+
field_frame.size.height = self.frame.size.height - Formotion::RowType::Base.field_buffer
|
31
|
+
formotion_field.frame = field_frame
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def on_select(tableView, tableViewDelegate)
|
37
|
+
if !row.editable?
|
38
|
+
return
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/formotion/version.rb
CHANGED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/form_spec.rb
CHANGED
@@ -52,6 +52,32 @@ describe "Forms" do
|
|
52
52
|
row.title.should == "Label"
|
53
53
|
row.subtitle.should == "Placeholder"
|
54
54
|
end
|
55
|
+
|
56
|
+
it "should return row by key" do
|
57
|
+
@form = Formotion::Form.new(sections: [{
|
58
|
+
rows: [{
|
59
|
+
key: :email,
|
60
|
+
type: :email,
|
61
|
+
editable: true,
|
62
|
+
title: 'Email'
|
63
|
+
}]
|
64
|
+
}])
|
65
|
+
|
66
|
+
expected = @form.sections[0].rows[0]
|
67
|
+
@form.row(:email).should == expected
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return nil for row by key if key does not exist" do
|
71
|
+
@form = Formotion::Form.new(sections: [{
|
72
|
+
rows: [{
|
73
|
+
key: :email,
|
74
|
+
type: :email,
|
75
|
+
editable: true,
|
76
|
+
title: 'Email'
|
77
|
+
}]
|
78
|
+
}])
|
79
|
+
@form.row(:foobar).should.be.nil
|
80
|
+
end
|
55
81
|
|
56
82
|
it "render works correctly" do
|
57
83
|
@form = Formotion::Form.new(sections: [{
|
data/spec/row_type/back_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe "Back Row" do
|
|
8
8
|
it "should pop subform on select" do
|
9
9
|
form = FakeForm.new
|
10
10
|
@row.instance_variable_set("@section", form)
|
11
|
-
@row.object.
|
11
|
+
@row.object._on_select(nil, nil)
|
12
12
|
form.controller.pop_subform_called.should == true
|
13
13
|
end
|
14
14
|
end
|
data/spec/row_type/base_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe "Base Row Type" do
|
|
11
11
|
tests_row :dummy
|
12
12
|
|
13
13
|
it "should return false if callback is not defined" do
|
14
|
-
@row.object.
|
14
|
+
@row.object._on_select(nil, nil).should == false
|
15
15
|
end
|
16
16
|
|
17
17
|
describe 'when on_tap_callback is set' do
|
@@ -24,11 +24,11 @@ describe "Base Row Type" do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should return true" do
|
27
|
-
@row.object.
|
27
|
+
@row.object._on_select(nil, nil).should == true
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should call the callback" do
|
31
|
-
@row.object.
|
31
|
+
@row.object._on_select(nil, nil)
|
32
32
|
@called.should == true
|
33
33
|
end
|
34
34
|
|