Class: MotionPrime::BaseFieldSection

Inherits:
Section
  • Object
show all
Includes:
BW::KVO, CellSectionMixin
Defined in:
motion-prime/sections/form/base_field_section.rb

Constant Summary

Constants inherited from Section

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

Instance Attribute Summary collapse

Attributes included from CellSectionMixin

#pending_display, #table

Attributes inherited from Section

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

Attributes included from DrawSectionMixin

#cached_draw_image, #container_element, #container_gesture_recognizers

Instance Method Summary collapse

Methods included from CellSectionMixin

#cell_section_name, #cell_type, #container_bounds, #display, #init_container_element, #pending_display!, #render_container, #section_styles

Methods included from SectionWithContainerMixin

#container_view, #init_container_element, #load_container_with_elements

Methods inherited from Section

#add_element, after_initialize, after_render, before_initialize, before_render, bind_keyboard_close, #bind_keyboard_events, #cell, container, #container_bounds, #container_options, #create_elements, #current_input_view_height, #default_name, element, #element, #elements_options, #elements_to_draw, #elements_to_render, #has_container_bounds?, #hide, #hide_keyboard, inherited, #initialize, #keyboard_will_hide, #keyboard_will_show, #on_keyboard_hide, #on_keyboard_show, #reload, #render, #render!, #render_container, #screen?, #show, #strong_references, #view

Methods included from DelegateMixin

#clear_delegated, #delegated_by

Methods included from DrawSectionMixin

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

Methods included from FrameCalculatorMixin

#calculate_frome_for

Methods included from HasStyles

#prepare_gradient

Methods included from HasClassFactory

#camelize_factory, #class_factory, #low_camelize_factory

Methods included from HasNormalizer

#normalize_object, #normalize_options

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

#formObject (readonly)

Returns the value of attribute form.



6
7
8
# File 'motion-prime/sections/form/base_field_section.rb', line 6

def form
  @form
end

Instance Method Details

#all_errorsObject



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

def all_errors
  return [] unless observing_errors?

  observing_errors_for.errors.info.slice(*errors_observer_fields).values.flatten
end

#bind_text_inputObject



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

def bind_text_input
  view(:input).on :change do |view|
    focus if options[:auto_focus]
    form.on_input_change(view(:input))
  end
end

#blurObject



110
111
112
113
114
115
116
117
118
119
# File 'motion-prime/sections/form/base_field_section.rb', line 110

def blur
  elements.values.each do |element|
    if element.view.is_a?(UITextField)
      element.view.resignFirstResponder && return
    end
  end
  self
rescue
  NSLog("can't blur on element #{self.class_name_without_kvo}")
end

#clear_observersObject



177
178
179
180
181
182
# File 'motion-prime/sections/form/base_field_section.rb', line 177

def clear_observers
  return unless observing_errors?
  # unobserve_all cause double dealloc, following code is a replacement
  unobserve observing_errors_for.errors, :info
  # TODO: clear 'on' events
end

#container_heightObject



184
185
186
187
188
189
# File 'motion-prime/sections/form/base_field_section.rb', line 184

def container_height
  return 0 if container_options[:hidden]
  element = element(:error_message)
  error_height = element ? element.cached_content_height + 5 : 0
  super + error_height
end

#deallocObject



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

def dealloc
  clear_observers
  super
end

#default_label_optionsObject



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

def default_label_options
  label_options = options[:label] || {}
  if label_options.has_key?(:text)
    label_options
  else
    {text: options[:name].to_s.titleize}.merge(label_options)
  end
end

#errors_observer_fieldsObject



154
155
156
157
158
159
160
# File 'motion-prime/sections/form/base_field_section.rb', line 154

def errors_observer_fields
  @errors_observer_fields ||= begin
    fields = Array.wrap(@errors_observer_options[:fields])
    fields << name if fields.empty?
    fields.uniq
  end
end

#focus(begin_editing = false) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'motion-prime/sections/form/base_field_section.rb', line 79

def focus(begin_editing = false)
  # focus on text field
  elements.values.detect do |element|
    if element.view.is_a?(UITextField) || element.view.is_a?(UITextView)
      element.view.becomeFirstResponder
    end
  end if begin_editing

  # scroll to cell
  # path = form.table_view.indexPathForCell(cell)
  # form.table_view.scrollToRowAtIndexPath path,
  #   atScrollPosition: UITableViewScrollPositionTop, animated: true
  return self unless input_view = element(:input).try(:view)
  origin = input_view.frame.origin
  point = container_view.convertPoint(origin, toView: form.table_view)

  nav_bar_height = screen.navigationController ? screen.navigationController.navigationBar.frame.size.height : 0
  nav_bar_height += 20 # status bar height

  offset = form.table_view.contentOffset
  new_top_offset = point.y - nav_bar_height
  unless new_top_offset == offset.y
    offset.y = new_top_offset
    form.table_view.setContentOffset(offset, animated: true)
  end

  self
rescue
  NSLog("can't focus on element #{self.class_name_without_kvo}")
end

#form_nameObject



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

def form_name
  form.name
end

#has_errors?Boolean

Returns:

  • (Boolean)


149
150
151
152
# File 'motion-prime/sections/form/base_field_section.rb', line 149

def has_errors?
  return false unless observing_errors?
  observing_errors_for.errors.info.slice(*errors_observer_fields).values.any?(&:present?)
end

#input?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'motion-prime/sections/form/base_field_section.rb', line 141

def input?
  false
end

#observe_model_errorsObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'motion-prime/sections/form/base_field_section.rb', line 52

def observe_model_errors
  return unless observing_errors?
  on_error_change = proc { |old_value, new_value|
    changes = observing_errors_for.errors.changes
    errors_observer_fields.each do |field|
      next unless changes.has_key?(field)
      if @status_for_updated == :rendered
        reload_section
      else
        create_elements!
        form.reload_table_data
      end
    end
  }.weak!

  observe observing_errors_for.errors, :info, &on_error_change
end

#observing_errors?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'motion-prime/sections/form/base_field_section.rb', line 145

def observing_errors?
  @errors_observer_options.present?
end

#observing_errors_forObject



162
163
164
# File 'motion-prime/sections/form/base_field_section.rb', line 162

def observing_errors_for
  @errors_observer_options[:resource]
end

#on_section_renderObject



47
48
49
50
# File 'motion-prime/sections/form/base_field_section.rb', line 47

def on_section_render
  @status_for_updated = :rendered
  form.register_elements_from_section(self)
end

#prepare_table_dataObject



12
13
14
15
16
17
18
# File 'motion-prime/sections/form/base_field_section.rb', line 12

def prepare_table_data
  @form = @options[:table]
  if options[:observe_errors]
    # Do not remove clone() after delete()
    @errors_observer_options = normalize_options(options.delete(:observe_errors).clone, self)
  end
end

#reload_sectionObject



172
173
174
175
# File 'motion-prime/sections/form/base_field_section.rb', line 172

def reload_section
  clear_observers
  form.reload_cell_section(self)
end

#render_element?(element_name) ⇒ Boolean

Returns true if we should render element in current state

Parameters:

  • element_name (Symbol)

    name of element in field

Returns:

  • (Boolean)


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

def render_element?(element_name)
  case element_name.to_sym
  when :error_message
    has_errors?
  when :label
    not @options[:label] === false
  else true
  end
end

#update_height(height) ⇒ MotionPrime::BaseFieldSection

Changes height of the field (the cell in table) with animation.

Parameters:

  • height (Integet)

    new height of field

Returns:



38
39
40
41
42
43
44
45
# File 'motion-prime/sections/form/base_field_section.rb', line 38

def update_height(height)
  return if container_options[:height] == height
  container_options[:height] = height
  index = form.field_indexes[name]
  form.send :set_data_stamp, self.object_id
  form.table_view.reloadRowsAtIndexPaths([index], withRowAnimation: UITableViewRowAnimationFade)
  self
end

#valueObject



137
138
139
# File 'motion-prime/sections/form/base_field_section.rb', line 137

def value
  raise "should be defined"
end