# -*- coding: utf-8 -*- module Formtastic module Helpers module ActionHelper ACTION_CLASS_DEPRECATION = 'configure Formtastic::FormBuilder.action_class_finder instead'.freeze private_constant(:ACTION_CLASS_DEPRECATION) # Renders an action for the form (such as a subit/reset button, or a cancel link). # # Each action is wrapped in an `
  • ` tag with other classes added based on the # type of action being rendered, and is intended to be rendered inside a {#buttons} # block which wraps the button in a `fieldset` and `ol`. # # The textual value of the label can be changed from the default through the `:label` # argument or through i18n. # # If using i18n, you'll need to provide the following translations: # # en: # formtastic: # actions: # create: "Create new %{model}" # update: "Save %{model}" # cancel: "Cancel" # reset: "Reset form" # submit: "Submit" # # For forms with an object present, the `update` key will be used if calling `persisted?` on # the object returns true (saving changes to a record), otherwise the `create` key will be # used. The `submit` key is used as a fallback when there is no object or we cannot determine # if `create` or `update` is appropriate. # # @example Basic usage # # form # <%= semantic_form_for @post do |f| %> # ... # <%= f.actions do %> # <%= f.action :submit %> # <%= f.action :reset %> # <%= f.action :cancel %> # <% end %> # <% end %> # # # output #
    # ... #
    #
      #
    1. # #
    2. #
    3. # #
    4. # #
    #
    #
    # # @example Set the value through the `:label` option # <%= f.action :submit, :label => "Go" %> # # @example Pass HTML attributes down to the tag inside the wrapper # <%= f.action :submit, :button_html => { :class => 'pretty', :accesskey => 'g', :disable_with => "Wait..." } %> # # @example Pass HTML attributes down to the `
  • ` wrapper # <%= f.action :submit, :wrapper_html => { :class => 'special', :id => 'whatever' } %> # # @option *args :label [String, Symbol] # Override the label text with a String or a symbold for an i18n translation key # # @option *args :button_html [Hash] # Override or add to the HTML attributes to be passed down to the `` tag # # @option *args :wrapper_html [Hash] # Override or add to the HTML attributes to be passed down to the wrapping `
  • ` tag # # @todo document i18n keys def action(method, options = {}) options = options.dup # Allow options to be shared without being tainted by Formtastic options[:as] ||= default_action_type(method, options) klass = action_class(options[:as]) klass.new(self, template, @object, @object_name, method, options).to_html end protected def default_action_type(method, options = {}) #:nodoc: case method when :submit then :input when :reset then :input when :cancel then :link else method end end # Takes the `:as` option and attempts to return the corresponding action # class. In the case of `:as => :awesome` it will first attempt to find a # top level `AwesomeAction` class (to allow the application to subclass # and modify to suit), falling back to `Formtastic::Actions::AwesomeAction`. # # Custom action namespaces to look into can be configured via the # .action_namespaces +FormBuilder+ configuration setting. # See +Formtastic::Helpers::InputHelper#namespaced_input_class+ for details. # def namespaced_action_class(as) @action_class_finder ||= action_class_finder.new(self) @action_class_finder.find(as) rescue Formtastic::ActionClassFinder::NotFoundError => e raise Formtastic::UnknownActionError, "Unable to find action #{e.message}" end # @api private # @deprecated Use {#namespaced_action_class} instead. def action_class(as) return namespaced_action_class(as) if action_class_finder action_class_deprecation_warning(__method__) @input_classes_cache ||= {} @input_classes_cache[as] ||= begin begin begin custom_action_class_name(as).constantize rescue NameError standard_action_class_name(as).constantize end rescue NameError raise Formtastic::UnknownActionError, "Unable to find action #{as}" end end end # @api private # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead. # :as => :button # => ButtonAction def custom_action_class_name(as) action_class_deprecation_warning(__method__) "#{as.to_s.camelize}Action" end # @api private # @deprecated Use {Formtastic::ActionClassFinder#class_name} instead. # :as => :button # => Formtastic::Actions::ButtonAction def standard_action_class_name(as) action_class_deprecation_warning(__method__) "Formtastic::Actions::#{as.to_s.camelize}Action" end private def action_class_deprecation_warning(method) @action_class_deprecation_warned ||= Formtastic.deprecation.deprecation_warning(method, ACTION_CLASS_DEPRECATION, caller(2)) end end end end