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_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, #build_element, #cell, container, #container_bounds, #container_options, #create_elements, #default_name, #element, element, #elements_options, #elements_to_draw, #elements_to_render, #hide, #hide_keyboard, inherited, #initialize, #keyboard_will_hide, #keyboard_will_show, #load_section, #load_section!, #on_keyboard_hide, #on_keyboard_show, #render, #render!, #render_container, #show, #view

Methods included from DelegateMixin

#clear_delegated, #delegated_by

Methods included from DrawSectionMixin

#bind_gesture_on_container_for, #draw_in, #prerender_elements_for_state, #prerender_enabled?, #strong_references

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



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

def all_errors
  return [] unless observing_errors?

  errors_observer_fields.map do |field|
    observing_errors_for.errors[field]
  end
end

#bind_text_inputObject



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

def bind_text_input
  view(:input).on :change do |view|
    focus
    form.on_input_change(view(:input))
  end
end

#blurObject



95
96
97
98
99
100
101
102
103
104
# File 'motion-prime/sections/form/base_field_section.rb', line 95

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



158
159
160
161
162
163
164
165
166
# File 'motion-prime/sections/form/base_field_section.rb', line 158

def clear_observers
  return unless observing_errors?
  # unobserve_all cause double dealloc, following code is a replacement
  block = proc { |field|
    unobserve observing_errors_for.errors, observing_errors_for.errors.unique_key(field)
  }.weak!
  errors_observer_fields.each(&block)
  # TODO: clear 'on' events
end

#container_heightObject



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

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



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

def dealloc
  clear_observers
  super
end

#default_label_optionsObject



106
107
108
109
110
111
112
113
# File 'motion-prime/sections/form/base_field_section.rb', line 106

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



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

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 = true) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'motion-prime/sections/form/base_field_section.rb', line 78

def focus(begin_editing = true)
  # scroll to cell
  path = form.table_view.indexPathForCell(cell)
  form.table_view.scrollToRowAtIndexPath path,
    atScrollPosition: UITableViewScrollPositionTop, animated: true
  # focus on text field
  return unless begin_editing
  elements.values.each do |element|
    if element.view.is_a?(UITextField) || element.view.is_a?(UITextView)
      element.view.becomeFirstResponder and return
    end
  end
  self
rescue
  NSLog("can't focus on element #{self.class_name_without_kvo}")
end

#form_nameObject



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

def form_name
  form.name
end

#has_errors?Boolean

Returns:

  • (Boolean)


126
127
128
129
130
131
# File 'motion-prime/sections/form/base_field_section.rb', line 126

def has_errors?
  return false unless observing_errors?
  errors_observer_fields.any? do |field|
    observing_errors_for.errors[field].present?
  end
end

#observe_model_errorsObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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|
    next if old_value == new_value
    if @status_for_updated == :rendered
      reload_section
    else
      load_section!
      form.reload_table_data
    end
  }.weak!

  errors_observer_fields.each do |field|
    observe observing_errors_for.errors, observing_errors_for.errors.unique_key(field), &on_error_change
  end
end

#observing_errors?Boolean

Returns:

  • (Boolean)


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

def observing_errors?
  @errors_observer_options.present?
end

#observing_errors_forObject



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

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



153
154
155
156
# File 'motion-prime/sections/form/base_field_section.rb', line 153

def reload_section
  clear_observers
  form.reload_cell(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)
  container_options[:height] = height
  field_index = form.field_indexes[name]
  index = field_index.split('_').map(&:to_i)
  path = NSIndexPath.indexPathForRow(index.last, inSection: index.first)
  form.table_view.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimationFade)
  self
end