Class: MotionPrime::FormSection

Inherits:
TableSection show all
Defined in:
motion-prime/sections/form.rb

Constant Summary

Constants inherited from Section

Section::DEFAULT_CONTENT_HEIGHT, Section::KEYBOARD_HEIGHT_LANDSCAPE, Section::KEYBOARD_HEIGHT_PORTRAIT

Instance Attribute Summary collapse

Attributes inherited from TableSection

#group_header_options, #group_header_sections

Attributes inherited from AbstractCollectionSection

#collection_element, #decelerating, #did_appear

Attributes inherited from Section

#elements, #model, #name, #options, #screen, #section_styles

Attributes included from DrawSectionMixin

#cached_draw_image, #container_element, #container_gesture_recognizers

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from TableSection

#add_cell_sections, #cell_sections_for_group, #delete_cell_sections, #delete_from_data, #flat_data?, group_header, #header_cell_in_group, #header_section_for_group, #height_for_header_in_group, #index_for_cell_section, pull_to_refresh, #reload_cell_sections, #reload_cells, #render_cell, #render_header, #resize_cell_sections, #table_element_options

Methods included from HasSearchBar

#add_search_bar, #create_search_bar, #dealloc, #searchBar, #searchBarSearchButtonClicked

Methods included from TableSectionRefreshMixin

#add_pull_to_refresh, #finish_pull_to_refresh

Methods inherited from AbstractCollectionSection

#cell_for_index, #cell_name, #cell_section_by_index, #cell_section_styles, #cell_sections_for_group, #collection_element_options, #collection_styles, #collection_view, #data, #dealloc, #fixed_collection_data, #height_for_index, #hide, #on_appear, #on_click, #on_input_change, #on_input_edit_begin, #on_input_edit_end, #on_input_return, #refresh_if_needed, #reload, #reload_collection_data, #render_cell, #reset_collection_data, #scroll_view_did_end_decelerating, #scroll_view_did_end_dragging, #scroll_view_did_end_scrolling_animation, #scroll_view_did_scroll, #scroll_view_will_begin_decelerating, #scroll_view_will_begin_dragging, #show, #update_pull_to_refresh_after_scroll

Methods included from HasStyleChainBuilder

#build_styles_chain

Methods inherited from Section

#add_element, after_element_render, #after_element_render, after_initialize, after_render, before_initialize, before_render, bind_keyboard_close, #bind_keyboard_events, #bring_to_front, container, #container_bounds, #container_height, #container_options, #create_elements, #current_input_view_height, #dealloc, #default_name, element, #elements_options, #elements_to_draw, #elements_to_render, #hard_reload_section, #has_container_bounds?, #hide, #hide_keyboard, #initialize, #on_keyboard_hide, #on_keyboard_show, #reload, #render, #render!, #render_container, #render_element?, #screen?, #show, #strong_references, #view

Methods included from DelegateMixin

#clear_delegated, #delegated_by

Methods included from DrawSectionMixin

#after_element_render, #before_element_render, #bind_gesture_on_container_for, #clear_gesture_for_receiver, #draw_in, #prerender_elements_for_state, #prerender_enabled?

Methods included from SectionWithContainerMixin

#container_view, #init_container_element, #load_container_with_elements

Methods included from FrameCalculatorMixin

#calculate_frame_for

Methods included from HasStyles

#prepare_gradient

Methods included from HasClassFactory

#camelize_factory, #class_factory, #low_camelize_factory, #underscore_factory

Methods included from HasNormalizer

#debug_info, #element?, #normalize_object, #normalize_options, #normalize_value

Methods included from HasAuthorization

#api_client, #current_user, #reset_current_user, #user_signed_in?

Constructor Details

This class inherits a constructor from MotionPrime::Section

Instance Attribute Details

#field_indexesObject

Returns the value of attribute field_indexes.



22
23
24
# File 'motion-prime/sections/form.rb', line 22

def field_indexes
  @field_indexes
end

#fieldsObject

Returns the value of attribute fields.



22
23
24
# File 'motion-prime/sections/form.rb', line 22

def fields
  @fields
end

#grouped_dataObject

Returns the value of attribute grouped_data.



22
23
24
# File 'motion-prime/sections/form.rb', line 22

def grouped_data
  @grouped_data
end

#keyboard_visibleObject

Returns the value of attribute keyboard_visible.



22
23
24
# File 'motion-prime/sections/form.rb', line 22

def keyboard_visible
  @keyboard_visible
end

#rendered_viewsObject

Returns the value of attribute rendered_views.



22
23
24
# File 'motion-prime/sections/form.rb', line 22

def rendered_views
  @rendered_views
end

Class Method Details

.after_field_render(field_name, method, options = {}) ⇒ Object



225
226
227
228
229
230
# File 'motion-prime/sections/form.rb', line 225

def after_field_render(field_name, method, options = {})
  options.merge!(method: method)
  self.fields_callbacks ||= {}
  self.fields_callbacks[field_name] ||= []
  self.fields_callbacks[field_name] << options
end

.async_collection_data(options = {}) ⇒ Object



211
212
213
214
# File 'motion-prime/sections/form.rb', line 211

def async_collection_data(options = {})
  super
  self.send :include, Prime::AsyncFormMixin
end

.field(name, options = {}, &block) ⇒ Object



216
217
218
219
220
221
222
223
# File 'motion-prime/sections/form.rb', line 216

def field(name, options = {}, &block)
  options[:name] = name
  options[:type] ||= :string
  options[:block] = block
  self.fields_options ||= {}
  self.fields_options[name] = options
  self.fields_options[name]
end

.inherited(subclass) ⇒ Object



203
204
205
206
207
208
209
# File 'motion-prime/sections/form.rb', line 203

def inherited(subclass)
  super
  subclass.fields_options = self.fields_options.try(:clone)
  subclass.fields_callbacks = self.fields_callbacks.try(:clone)
  subclass.text_field_limits = self.text_field_limits.try(:clone)
  subclass.text_view_limits = self.text_view_limits.try(:clone)
end

.limit_text_field_length(name, limit) ⇒ Object



232
233
234
235
# File 'motion-prime/sections/form.rb', line 232

def limit_text_field_length(name, limit)
  self.text_field_limits ||= {}
  self.text_field_limits[name] = limit
end

.limit_text_view_length(name, limit) ⇒ Object



236
237
238
239
# File 'motion-prime/sections/form.rb', line 236

def limit_text_view_length(name, limit)
  self.text_view_limits ||= {}
  self.text_view_limits[name] = limit
end

Instance Method Details

#allow_string_replacement?(target, limit, range, string) ⇒ Boolean

Returns:

  • (Boolean)


143
144
145
146
147
148
149
# File 'motion-prime/sections/form.rb', line 143

def allow_string_replacement?(target, limit, range, string)
  if string.length.zero? || (range.length + limit - target.text.length) >= string.length
    true
  else
    target.text.length < limit
  end
end

#collection_dataObject



24
25
26
27
28
29
30
# File 'motion-prime/sections/form.rb', line 24

def collection_data
  if has_many_sections?
    grouped_data.reject(&:nil?)
  else
    fields.values
  end
end

#collection_delegateObject



135
136
137
# File 'motion-prime/sections/form.rb', line 135

def collection_delegate
  @collection_delegate ||= FormDelegate.new(section: self)
end

#collection_styles_baseObject



139
140
141
# File 'motion-prime/sections/form.rb', line 139

def collection_styles_base
  :base_form
end

#element(name) ⇒ Object

Returns element based on field name and element name

Examples:

form.element("email:input")

Parameters:

  • String

    name with format “fieldname:elementname”

Returns:

  • MotionPrime::BaseElement element



55
56
57
58
59
60
61
62
# File 'motion-prime/sections/form.rb', line 55

def element(name)
  field_name, element_name = name.split(':')
  if element_name.present?
    field(field_name).element(element_name.to_sym)
  else
    super(field_name)
  end
end

#field(field_name) ⇒ Object

Returns field by name

Examples:

form.field(:email)

Parameters:

  • String

    field name

Returns:

  • MotionPrime::BaseFieldSection field



71
72
73
# File 'motion-prime/sections/form.rb', line 71

def field(field_name)
  self.fields[field_name.to_sym]
end

#field_valuesObject



79
80
81
82
83
84
85
# File 'motion-prime/sections/form.rb', line 79

def field_values
  values = {}
  fields.each do |field_name, field|
    values[field_name.to_sym] = field.value if field.input?
  end
  values
end

#fields_hashObject



75
76
77
# File 'motion-prime/sections/form.rb', line 75

def fields_hash
  fields.to_hash
end

#focus_on(field_name, animated = true) ⇒ Object

Set focus on field cell

Examples:

form.focus_on(:title)

Parameters:

  • String

    field name

Returns:

  • MotionPrime::BaseFieldSection field



101
102
103
104
105
106
107
108
# File 'motion-prime/sections/form.rb', line 101

def focus_on(field_name, animated = true)
  # unfocus other field
  data.flatten.each do |item|
    item.blur
  end
  # focus on field
  field(field_name).focus
end

#hard_reload_cell_section(section) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'motion-prime/sections/form.rb', line 32

def hard_reload_cell_section(section)
  field_name = section.name.to_sym
  path = field_indexes[field_name]
  deque_cell(section, at: path) # deque cached

  fields[field_name] = load_field(self.class.fields_options[field_name])
  fields[field_name].create_elements
  if flat_data?
    @data[path.row] = fields[field_name]
  else
    @data[path.section][path.row] = fields[field_name]
  end

  self.performSelectorOnMainThread(:reload_cells, withObject: path, waitUntilDone: false)
end

#has_many_sections?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'motion-prime/sections/form.rb', line 171

def has_many_sections?
  group_header_options.present? || grouped_data.count > 1
end

#keyboard_will_hideObject



129
130
131
132
133
# File 'motion-prime/sections/form.rb', line 129

def keyboard_will_hide
  current_inset = collection_view.contentInset
  current_inset.bottom = self.collection_element.computed_options[:bottom_content_inset] || 0
  collection_view.contentInset = current_inset
end

#keyboard_will_showObject



122
123
124
125
126
127
# File 'motion-prime/sections/form.rb', line 122

def keyboard_will_show
  current_inset = collection_view.contentInset
  return if collection_view.contentSize.height + collection_view.top + current_inset.top <= UIScreen.mainScreen.bounds.size.height - KEYBOARD_HEIGHT_PORTRAIT
  current_inset.bottom = KEYBOARD_HEIGHT_PORTRAIT + (self.collection_element.computed_options[:bottom_content_inset] || 0)
  collection_view.contentInset = current_inset
end

#load_field(field) ⇒ Object



151
152
153
154
# File 'motion-prime/sections/form.rb', line 151

def load_field(field)
  field_class = class_factory("#{field[:type]}_field_section", true)
  field_class.new(field.merge(screen: screen, collection_section: self.weak_ref))
end

#number_of_groupsObject

Table View Delegate




198
199
200
# File 'motion-prime/sections/form.rb', line 198

def number_of_groups
  has_many_sections? ? grouped_data.reject(&:nil?).count : 1
end

#on_cell_render(cell, index) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'motion-prime/sections/form.rb', line 180

def on_cell_render(cell, index)
  options = data[index.row].try(:options)
  if options && options[:after_render]
    self.send(options[:after_render])
  end

  section = cell_section_by_index(index)
  if callbacks = fields_callbacks.try(:[], section.name)
    callbacks.each do |options|
      options[:method].to_proc.call(options[:target] || self)
    end
  end
  super
end

#register_elements_from_section(section) ⇒ Object



87
88
89
90
91
92
# File 'motion-prime/sections/form.rb', line 87

def register_elements_from_section(section)
  self.rendered_views ||= {}
  section.elements.values.each do |element|
    self.rendered_views[element.view] = {element: element, section: section}
  end
end

#reload_dataObject



165
166
167
168
169
# File 'motion-prime/sections/form.rb', line 165

def reload_data
  init_form_fields # must be before resetting to reflect changes on @data
  reset_collection_data
  reload_collection_data
end

#render_collectionObject



175
176
177
178
# File 'motion-prime/sections/form.rb', line 175

def render_collection
  init_form_fields unless self.fields.present?
  super
end

#render_field?(name, options) ⇒ Boolean

Returns:

  • (Boolean)


156
157
158
159
160
161
162
163
# File 'motion-prime/sections/form.rb', line 156

def render_field?(name, options)
  return true unless condition = options[:if]
  if condition.is_a?(Proc)
    self.instance_eval(&condition)
  else
    condition.to_proc.call(self)
  end
end

#set_height_with_keyboardObject



110
111
112
113
114
# File 'motion-prime/sections/form.rb', line 110

def set_height_with_keyboard
  return if keyboard_visible
  self.collection_view.height -= KEYBOARD_HEIGHT_PORTRAIT
  self.keyboard_visible = true
end

#set_height_without_keyboardObject



116
117
118
119
120
# File 'motion-prime/sections/form.rb', line 116

def set_height_without_keyboard
  return unless keyboard_visible
  self.collection_view.height += KEYBOARD_HEIGHT_PORTRAIT
  self.keyboard_visible = false
end