Class: Wedge::Plugins::Form

Inherits:
Component show all
Extended by:
Forwardable, Delegates
Includes:
Enumerable, Methods, Validations, Render
Defined in:
lib/wedge/plugins/form.rb,
lib/wedge/plugins/form_backup.rb,
lib/wedge/plugins/form/validations.rb

Direct Known Subclasses

AbilityList, CurrentUser, Factory

Defined Under Namespace

Modules: Delegates, InstanceMethods, Validations Classes: Attributes, Atts

Class Attribute Summary collapse

Attributes inherited from Component

#wedge_method_called

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Delegates

_delegates

Methods included from Validations

#_errors, #_model_errors, #error, #errors, #model_errors, #valid, #valid?, #validate

Methods included from Methods

#client?, included, #server?

Methods inherited from Component

config, dom, html, html!, method_missing, plugin, set_dom, store, tmpl, #to_js, #wedge, #wedge_class_store, wedge_config, wedge_dom, #wedge_dom, #wedge_from_client?, #wedge_from_server?, #wedge_function, wedge_html, #wedge_html, #wedge_javascript, #wedge_method_url, wedge_name, wedge_new, wedge_on, wedge_on_server, #wedge_plugin, #wedge_scope, #wedge_store, #wedge_tmpl, wedge_tmpl, #wedge_trigger

Constructor Details

#initialize(atts = {}, options = {}) ⇒ Form

Initialize with a hash of attributes and values. If extra attributes are sent, a NoMethodError exception will be raised.

Examples:


class EditPost < Scrivener
  attr_accessor :title
  attr_accessor :body

  def validate
    assert_present :title
    assert_present :body
  end
end

edit = EditPost.new(title: "Software Tools")

edit.valid? #=> false

edit.errors[:title] #=> []
edit.errors[:body]  #=> [:not_present]

edit.body = "Recommended reading..."

edit.valid? #=> true

# Now it's safe to initialize the model.
post = Post.new(edit.attributes)
post.save


265
266
267
268
269
270
271
272
# File 'lib/wedge/plugins/form.rb', line 265

def initialize(atts = {}, options = {})
  atts      = atts.deep_dup
  @_options = options.indifferent
  @_atts    = Atts.new atts, _accessors, _aliases, _accessor_options
  @_atts    = @_atts.set_defaults self

  _set_atts atts
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

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



136
137
138
139
140
141
142
143
144
145
# File 'lib/wedge/plugins/form_backup.rb', line 136

def method_missing method, *args, &block
  # respond_to?(symbol, include_all=false)
  if _data.respond_to? method, true
    _data.send method, *args, &block
  else
    return if method[/\=\z/]

    super
  end
end

Class Attribute Details

._accessor_optionsObject

Returns the value of attribute _accessor_options.



158
159
160
# File 'lib/wedge/plugins/form.rb', line 158

def _accessor_options
  @_accessor_options
end

._accessorsObject

Returns the value of attribute _accessors.



158
159
160
# File 'lib/wedge/plugins/form.rb', line 158

def _accessors
  @_accessors
end

._aliasesObject

Returns the value of attribute _aliases.



158
159
160
# File 'lib/wedge/plugins/form.rb', line 158

def _aliases
  @_aliases
end

Class Method Details

.attr_accessor(*vars) ⇒ Object



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/wedge/plugins/form.rb', line 181

def attr_accessor(*attrs, &block)
  attrs.each_with_index do |att, i|
    if att.is_a? Hash
      # remove the hash from the attrs, use them as options
      options = attrs.delete_at i
      # set the type class to aa string so it's not turned into an
      # anonymous class
      if type = options.delete(:type)
        options[:type] = type.to_s
      end
      # merge and att them to the accessor options
      attrs.each do |a|
        ((@_accessor_options ||= IndifferentHash.new)[a] ||= {}).merge! options
      end
    else
      # issue: OPAL is not using the alias method original_attr_reader
      # correctly.  It's still somehow getting in here when called below.
      next if %w'_atts _options _atts_keys'.include? att.to_s
      ###################################################################

      # set empty options if need be
      (@_accessor_options ||= IndifferentHash.new)[att] ||= {}
      # store the accessors
      ((@_accessors ||= []) << att).uniq!
      define_method(att) { _atts.send att }
    end
  end

  _delegates(*attrs)
end

.attr_reader(*attrs, &block) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/wedge/plugins/form.rb', line 161

def attr_reader(*attrs, &block)
  default_opts = { read_only: true }
  opts = attrs.pop

  if opts.is_a? Hash
    default_opts.merge! opts
    attrs << default_opts.merge!(opts)
  else
    attrs << opts
    attrs << default_opts
  end

  attr_accessor(*attrs, &block)
end

.form_accessor(name, options = {}) ⇒ Object



176
177
178
# File 'lib/wedge/plugins/form.rb', line 176

def form_accessor name, options = {}
  attr_accessor *[name, { form: name }.merge(options)]
end

.inherited(subclass) ⇒ Object

We need to set instance variables on the inherited class



213
214
215
216
217
218
219
# File 'lib/wedge/plugins/form.rb', line 213

def inherited(subclass)
  return if name == 'Wedge::Plugins::Form'

  subclass.instance_variable_set :@_accessors, @_accessors.deep_dup
  subclass.instance_variable_set :@_accessor_options, @_accessor_options.deep_dup
  subclass.instance_variable_set :@_aliases, @_aliases.deep_dup
end

.model_alias(alias_name, original_name) ⇒ Object Also known as: alias_model



221
222
223
224
225
226
227
228
229
# File 'lib/wedge/plugins/form.rb', line 221

def model_alias alias_name, original_name
  @_aliases ||= IndifferentHash.new
  @_aliases[original_name] = alias_name
  # discuss: should we also alias_method. right now I'm think no, reason
  # being it's just a model alias and shouldn't allow people to call
  # that method on the form to avoid some people using one name and some
  # another.
  # alias_method alias_name, original_name
end

.original_attr_accessorObject



180
# File 'lib/wedge/plugins/form.rb', line 180

alias_method :original_attr_accessor, :attr_accessor

.original_attr_readerObject



160
# File 'lib/wedge/plugins/form.rb', line 160

alias_method :original_attr_reader, :attr_reader

Instance Method Details

#_accessor_optionsObject



313
314
315
# File 'lib/wedge/plugins/form.rb', line 313

def _accessor_options
  @_accessor_options ||= (self.class._accessor_options || IndifferentHash.new).deep_dup
end

#_accessorsObject



309
310
311
# File 'lib/wedge/plugins/form.rb', line 309

def _accessors
  @_accessors ||= (self.class._accessors || IndifferentHash.new).deep_dup
end

#_aliasesObject



317
318
319
# File 'lib/wedge/plugins/form.rb', line 317

def _aliases
  @_aliases || (self.class._aliases || IndifferentHash.new).deep_dup
end

#_attributesObject



288
289
290
# File 'lib/wedge/plugins/form_backup.rb', line 288

def _attributes
  @_attributes ||= {}
end

#_atts_keysObject



293
294
295
# File 'lib/wedge/plugins/form.rb', line 293

def _atts_keys
  @_atts_keys ||= []
end

#_keysObject



305
306
307
# File 'lib/wedge/plugins/form.rb', line 305

def _keys
  ((_options[:atts] || _accessors) + _with_atts).reject { |k| _without_atts.include? k }
end

#_set_atts(atts) ⇒ Object



274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/wedge/plugins/form.rb', line 274

def _set_atts atts
  return unless atts

  atts.each do |key, val|
    # grab the original key if alias is given
    _atts_keys << (key = _aliases.invert[key] || key)

    if (_accessor_options[key] || {})[:form]
      send(key)._set_atts val
    else
      accessor = "#{key}="

      if respond_to?(accessor)
        send(accessor, val)
      end
    end
  end
end

#_with_attsObject



297
298
299
# File 'lib/wedge/plugins/form.rb', line 297

def _with_atts
  _accessor_options[:with_atts] || []
end

#_without_attsObject



301
302
303
# File 'lib/wedge/plugins/form.rb', line 301

def _without_atts
  _accessor_options[:without_atts] || []
end

#attributesObject

Return hash of attributes and values.



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/wedge/plugins/form.rb', line 334

def attributes for_model = false
  IndifferentHash.new.tap do |atts|
    _options[:_attributes]       = true
    _options[:_model_attributes] = for_model

    _keys.each do |att|
      opts = _accessor_options[att].indifferent
      if ((for_model && !opts[:read_only]) || !for_model) && _atts.can_read?(att) && (!opts[:hidden] || opts[:hidden].is_a?(Proc) && !self.instance_exec(&opts[:hidden]))
        is_form   = opts[:form]
        key       = for_model ? _aliases[att] || att : att
        key       = (for_model && is_form)? "#{key}_attributes" : key
        atts[key] = is_form ? send(att).send(for_model ? 'model_attributes' : 'attributes') : (for_model ? _atts.send(att) : send(att))
      end
    end
  end
end

#attributes?Boolean

Returns:

  • (Boolean)


325
326
327
# File 'lib/wedge/plugins/form.rb', line 325

def attributes?
  @_options[:_attributes] ? true : false
end

#display_errors(options = {}, &block) ⇒ Object Also known as: render_errors



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/wedge/plugins/form_backup.rb', line 196

def display_errors options = {}, &block
  dom = options.delete(:dom) || _dom
  d_errors = errors

  if override_errors = options[:override_errors]
    d_errors = override_errors
  end

  keys = options.delete(:keys) || (_options[:key] ? [_options[:key]] : [])

  if extra_errors = options.delete(:errors)
    extra_errors.each do |key, value|
      d_errors[key] = value
    end
  end

  d_errors.each do |key, error|
    d_keys = (keys.dup << key)

    error = error.first

    if error.is_a?(Hash)
      d_options = options.dup
      d_options[:keys] = d_keys
      d_options[:override_errors] = d_errors[key].first

      display_errors d_options, &block
    elsif !block_given? || block.call(d_keys, error) == false
      name = d_keys.each_with_index.map do |field, i|
        i != 0 ? "[#{field}]" : field
      end.join

      if tmpl = options[:tmpl]
        if client?
          field_error_dom = DOM.new(`#{tmpl.dom}[0].outerHTML`)
        else
          field_error_dom = DOM.new(tmpl.dom.to_html)
        end
      else
        field_error_dom = DOM.new('<span class="field-error"><span>')
      end

      field_error_dom.html _error_name(key, error)

      field = dom.find("[name='#{name}']")
      field.before field_error_dom.dom
    end
  end
end

#model_attributes(data = attributes) ⇒ Object



351
352
353
# File 'lib/wedge/plugins/form.rb', line 351

def model_attributes
  attributes true
end

#model_attributes?Boolean

Returns:

  • (Boolean)


329
330
331
# File 'lib/wedge/plugins/form.rb', line 329

def model_attributes?
  @_options[:_model_attributes] ? true : false
end

#nested?Boolean

Returns:

  • (Boolean)


321
322
323
# File 'lib/wedge/plugins/form.rb', line 321

def nested?
  @_options[:_nested] ? true : false
end

#optionsObject



356
# File 'lib/wedge/plugins/form.rb', line 356

alias options _options

#render_values(dom = false, key = false, data = false) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/wedge/plugins/form_backup.rb', line 247

def render_values dom = false, key = false, data = false
  dom = _options[:dom] unless dom
  key = _options[:key] if !key && _options.key?(:key)

  dom.find('input, select, textarea') do |element|
    name  = element['name']
    next if name.nil?
    name  = name.gsub(/\A#{key}/, '') if key
    keys  = name.gsub(/\A\[/, '').gsub(/[^a-z0-9_]/, '|').gsub(/\|\|/, '|').gsub(/\|$/, '').split('|')
    value = false

    keys.each do |k|
      begin
        value = value != false ? value.send(k) : send(k)
      rescue
        value = ''
      end
    end

    case element.name
    when 'select'
      element.find('option') do |x|
        x['selected'] = true if x['value'] == value.to_s
      end
    when 'input'
      if %w(radio checkbox).include? element['type']
        if element['value'] == value.to_s
          element['checked'] = true
        else
          element.delete 'checked'
        end
      else
        value = sprintf('%.2f', value) if value.is_a? BigDecimal
        element['value'] = value.to_s
      end
    when 'textarea'
      element.val value.to_s
    end
  end
end

#slice(*keys) ⇒ Object



358
359
360
361
362
363
364
# File 'lib/wedge/plugins/form.rb', line 358

def slice(*keys)
  IndifferentHash.new.tap do |atts|
    keys.each do |att|
      atts[att] = send(att)
    end
  end
end

#validate_msg(error, column) ⇒ Object



292
293
294
# File 'lib/wedge/plugins/form_backup.rb', line 292

def validate_msg error, column
  false
end