Module: ActiveForm::Mixins::ContainerMethods::ElementMethods

Defined in:
lib/active_form/mixins/container_methods.rb

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object (private)



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/active_form/mixins/container_methods.rb', line 356

def method_missing(method, *args, &block) 
  if (match = /^html_for_(.*)$/.match(method.to_s))
    get_and_render_to_html(match.captures[0], *args)
  elsif (match = /^label_for_(.*)$/.match(method.to_s))
    get_and_render_label(match.captures[0], *args)
  elsif (match = /^(.*)_element$/.match(method.to_s)) && ActiveForm::Element::exists?(match.captures[0])
    define_element(match.captures[0], *args, &block)
  elsif (match = /^(.*)_widget$/.match(method.to_s)) && ActiveForm::Widget::exists?(match.captures[0])
    define_widget(match.captures[0], *args, &block)
  elsif (match = /^validates_(with_|as_|within_)?(.*)$/.match(method.to_s)) && ActiveForm::Validator::exists?(match.captures[1])
    define_validator(match.captures[1], *args, &block)
  elsif (match = /^select_from_(.*)$/.match(method.to_s))
    options = args.last.is_a?(Hash) ? args.pop : {} 
    args.push(options.merge(:model => match.captures[0], :to_dropdown => true))
    define_element(:select_from_model, *args, &block)
  else
    super
  end
end

Instance Method Details

#append_sections(*defnames) ⇒ Object Also known as: append_section



125
126
127
128
129
130
131
132
133
134
# File 'lib/active_form/mixins/container_methods.rb', line 125

def append_sections(*defnames)
  index = defnames.last.kind_of?(Integer) ? defnames.pop : -1
  sections = defnames.inject([]) do |ary, name|
    args = name.kind_of?(Array) ? name : [name]
    section = ActiveForm::Element::Section::build(*args)
    ary << section unless section.nil?
    ary
  end
  insert_elements(sections, index)
end

#default_valueObject



342
343
344
# File 'lib/active_form/mixins/container_methods.rb', line 342

def default_value
  ActiveForm::Values.new
end

#define_builder(*args, &block) ⇒ Object Also known as: builder, html



148
149
150
# File 'lib/active_form/mixins/container_methods.rb', line 148

def define_builder(*args, &block)
  define_element(:builder, *args, &block)
end

#define_element(type, *args, &block) ⇒ Object Also known as: define_element_at_bottom



161
162
163
164
165
166
# File 'lib/active_form/mixins/container_methods.rb', line 161

def define_element(type, *args, &block)
  args.unshift(self)
  element = ActiveForm::Element::build(type, *args, &block)
  insert_element(element, false) && element unless element.nil?
  element
end

#define_element_at(index, type, *args, &block) ⇒ Object



169
170
171
172
173
174
# File 'lib/active_form/mixins/container_methods.rb', line 169

def define_element_at(index, type, *args, &block)
  args.unshift(self)
  element = ActiveForm::Element::build(type, *args, &block)
  insert_element(element, index, false) && element unless element.nil?
  element
end

#define_element_at_top(type, *args, &block) ⇒ Object



176
177
178
179
180
181
# File 'lib/active_form/mixins/container_methods.rb', line 176

def define_element_at_top(type, *args, &block)
  args.unshift(self)
  element = ActiveForm::Element::build(type, *args, &block)
  insert_element(element, 0, false) && element unless element.nil?
  element
end

#define_form(*args, &block) ⇒ Object



137
138
139
140
141
# File 'lib/active_form/mixins/container_methods.rb', line 137

def define_form(*args, &block)
  args.unshift(self)
  form = ActiveForm::compose(*args, &block)
  insert_element(form, false) && form
end

#define_section(*args, &block) ⇒ Object Also known as: section



143
144
145
# File 'lib/active_form/mixins/container_methods.rb', line 143

def define_section(*args, &block)
  define_element(:section, *args, &block)
end

#define_widget(type, *args, &block) ⇒ Object



154
155
156
157
158
159
# File 'lib/active_form/mixins/container_methods.rb', line 154

def define_widget(type, *args, &block)
  args.unshift(self)
  element = ActiveForm::Widget::build(type, *args, &block)
  insert_element(element, false) && element unless element.nil?
  element
end

#each(&block) ⇒ Object



114
115
116
# File 'lib/active_form/mixins/container_methods.rb', line 114

def each(&block)
  elements.each(&block)
end

#element_exists?(name) ⇒ Boolean

Returns:

  • (Boolean)


302
303
304
305
# File 'lib/active_form/mixins/container_methods.rb', line 302

def element_exists?(name)
  name = ActiveForm::symbolize_name(name)
  name_to_index_lookup.include?(name)
end

#element_namesObject



323
324
325
# File 'lib/active_form/mixins/container_methods.rb', line 323

def element_names
  elements.collect(&:name)
end

#element_names_from_indices(*indices) ⇒ Object



319
320
321
# File 'lib/active_form/mixins/container_methods.rb', line 319

def element_names_from_indices(*indices)
  indices.flatten.collect { |idx| get_element_by_index(idx) }.compact.collect(&:name)
end

#elementsObject



233
234
235
236
# File 'lib/active_form/mixins/container_methods.rb', line 233

def elements
  @elements ||= []
  @elements
end

#elements=(*elems) ⇒ Object



238
239
240
241
# File 'lib/active_form/mixins/container_methods.rb', line 238

def elements=(*elems)
  reset_elements!
  insert_elements(*elems)
end

#elements?Boolean

Returns:

  • (Boolean)


243
244
245
# File 'lib/active_form/mixins/container_methods.rb', line 243

def elements?
  !elements.empty?
end

#get_and_render_label(name, builder = create_builder) ⇒ Object



252
253
254
255
# File 'lib/active_form/mixins/container_methods.rb', line 252

def get_and_render_label(name, builder = create_builder)
  elem = get_element(name)
  elem ? elem.render_label(builder) : nil
end

#get_and_render_to_html(name, builder = create_builder) ⇒ Object



247
248
249
250
# File 'lib/active_form/mixins/container_methods.rb', line 247

def get_and_render_to_html(name, builder = create_builder)
  elem = get_element(name)
  elem ? elem.to_html(builder) : nil
end

#get_element(name) ⇒ Object Also known as: []



257
258
259
260
261
262
263
# File 'lib/active_form/mixins/container_methods.rb', line 257

def get_element(name)
  name = ActiveForm::symbolize_name(name)
  if index = index_of_element(name)      
    return elements[index]
  end
  return nil
end

#get_element_by_index(index) ⇒ Object Also known as: element_at



314
315
316
# File 'lib/active_form/mixins/container_methods.rb', line 314

def get_element_by_index(index)
  self.elements[index]
end

#get_elements_of_type(*types) ⇒ Object



266
267
268
269
270
271
# File 'lib/active_form/mixins/container_methods.rb', line 266

def get_elements_of_type(*types)
  types.flatten.inject([]) do |elems, type|
    self.recurse { |e| elems << e if type == e.element_type }
    elems
  end
end

#index_of_element(name) ⇒ Object Also known as: index_of



307
308
309
310
311
# File 'lib/active_form/mixins/container_methods.rb', line 307

def index_of_element(name)
  name = ActiveForm::symbolize_name(name)
  return nil unless element_exists?(name)
  name_to_index_lookup[name]
end

#insert_element(*elem) ⇒ Object



183
184
185
# File 'lib/active_form/mixins/container_methods.rb', line 183

def insert_element(*elem)
  insert_elements(*elem).last
end

#insert_element_at_top(*elems) ⇒ Object



210
211
212
# File 'lib/active_form/mixins/container_methods.rb', line 210

def insert_element_at_top(*elems)
  insert_elements(*(elems << 0)).last
end

#insert_elements(*elems) ⇒ Object Also known as: append_form, <<



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/active_form/mixins/container_methods.rb', line 187

def insert_elements(*elems)
  elems.flatten!
  do_registration = elems.last === false ? elems.pop : true
  index = elems.last.kind_of?(Integer) ? elems.pop : -1
  first_index = index < 0 ? elements.length + 1 + index : index
  first_index = 0 if first_index < 0
  elems.each_with_index do |elem, i|
    if elem.kind_of?(Symbol)
      elem = ActiveForm::Element::Section::build(elem)
    elsif elem.kind_of?(String)
      elem = ActiveForm::Element::build(:builder, :html => elem)
    end
    if ActiveForm::Element::element?(elem)
      elem.register_container(self) if do_registration
      elements.insert(first_index + i, elem)
    end
  end
  reindex_name_to_index_lookup!
  elements  
end

#insert_elements_at_top(*elems) ⇒ Object



214
215
216
# File 'lib/active_form/mixins/container_methods.rb', line 214

def insert_elements_at_top(*elems)
  insert_elements(*(elems << 0))
end

#name_to_index_lookupObject



337
338
339
340
# File 'lib/active_form/mixins/container_methods.rb', line 337

def name_to_index_lookup
  @name_to_index_lookup ||= {}
  @name_to_index_lookup 
end

#rebuild!Object



332
333
334
335
# File 'lib/active_form/mixins/container_methods.rb', line 332

def rebuild!
  reset_elements!
  after_initialize
end

#recurse(&block) ⇒ Object



118
119
120
121
122
123
# File 'lib/active_form/mixins/container_methods.rb', line 118

def recurse(&block)
  elements.each do |elem| 
    block.call(elem)     
    elem.recurse(&block) if elem.container? && elem.elements?
  end
end

#remove_elements(*names) ⇒ Object Also known as: remove_element



286
287
288
# File 'lib/active_form/mixins/container_methods.rb', line 286

def remove_elements(*names)
  names.flatten.each { |name| elements.delete_at(index_of_element(name)); reindex_name_to_index_lookup! }
end

#remove_elements_at(*indices) ⇒ Object Also known as: remove_element_at



291
292
293
# File 'lib/active_form/mixins/container_methods.rb', line 291

def remove_elements_at(*indices)
  remove_elements(element_names_from_indices(indices))
end

#remove_elements_of_type(*types) ⇒ Object



296
297
298
299
300
# File 'lib/active_form/mixins/container_methods.rb', line 296

def remove_elements_of_type(*types)
  types.flatten.each do |type|
    self.recurse { |e| e.container.remove_element(e.name) if e.contained? && type == e.element_type }
  end
end

#reset_elements!Object



327
328
329
330
# File 'lib/active_form/mixins/container_methods.rb', line 327

def reset_elements!
  elements.clear
  reindex_name_to_index_lookup!
end

#set_element(name, elem) ⇒ Object Also known as: []=, replace



273
274
275
276
277
278
279
280
281
282
# File 'lib/active_form/mixins/container_methods.rb', line 273

def set_element(name, elem)
  name = ActiveForm::symbolize_name(name)
  raise ActiveForm::Element::MismatchException unless name == elem.name
  raise ActiveForm::Element::NoElemException unless is_element?(elem)      
  if index = index_of_element(name) 
    elem.register_container(self)     
    return elements[index] = elem
  end
  return nil
end

#update_elements(*args) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/active_form/mixins/container_methods.rb', line 218

def update_elements(*args)
  attrs = args.last.kind_of?(Hash) ? args.pop : {}
  elem_names = args.length > 0 ? args.flatten : self.element_names
  elem_names.each do |elem_name| 
    name = ActiveForm::symbolize_name(elem_name)
    if element_exists?(name)
      if self[name].respond_to?(:update_elements)
        self[name].update_elements(attrs.dup) 
      else
        self[name].update(attrs.dup) 
      end
    end
  end
end