Module: Decidim::DecidimFormHelper

Included in:
ScopesHelper
Defined in:
app/helpers/decidim/decidim_form_helper.rb

Overview

A heper to expose an easy way to add authorization forms in a view.

Instance Method Summary collapse

Instance Method Details

#areas_for_select(organization) ⇒ Object

Handle which collection to pass to Decidim::FilterFormBuilder.areas_select



198
199
200
201
202
203
# File 'app/helpers/decidim/decidim_form_helper.rb', line 198

def areas_for_select(organization)
  return organization.areas if organization.area_types.blank?
  return organization.areas if organization.area_types.all? { |at| at.area_ids.empty? }

  organization.area_types
end

#base_error_messages(record) ⇒ Object



186
187
188
189
190
191
# File 'app/helpers/decidim/decidim_form_helper.rb', line 186

def base_error_messages(record)
  return unless record.respond_to?(:errors)
  return unless record.errors[:base].any?

  alert_box(record.errors.full_messages_for(:base).join(","), "alert", false)
end

#decidim_form_for(record, options = {}, &block) ⇒ Object

A custom form for that injects client side validations with Abide.

record - The object to build the form for. options - A Hash of options to pass to the form builder. &block - The block to execute as content of the form.

Returns a String.



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/helpers/decidim/decidim_form_helper.rb', line 13

def decidim_form_for(record, options = {}, &block)
  options[:data] ||= {}
  options[:data].update(abide: true, "live-validate" => true, "validate-on-blur" => true)

  options[:html] ||= {}
  options[:html].update(novalidate: true)

  output = ""
  output += base_error_messages(record).to_s
  output += form_for(record, options, &block).to_s

  output.html_safe
end

#decidim_form_slug_url(prepend_path = "", value = "") ⇒ Object

Helper method to show how slugs will look like. Intended to be used in forms together with some JavaScript code. More precisely, this will most probably show in help texts in forms. The space slug is surrounded with a ‘span` so the slug can be updated via JavaScript with the input value.

prepend_path - a path to prepend to the slug, without final slash value - the initial value of the slug field, so that edit forms have a value

Returns an HTML-safe String.



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/helpers/decidim/decidim_form_helper.rb', line 170

def decidim_form_slug_url(prepend_path = "", value = "")
  prepend_slug_path = if prepend_path.present?
                        "/#{prepend_path}/"
                      else
                        "/"
                      end
  (:span, class: "slug-url") do
    [
      request.protocol,
      request.host_with_port,
      prepend_slug_path
    ].join("").html_safe +
      (:span, value, class: "slug-url-value")
  end
end

#editor_field_tag(name, value, options = {}) ⇒ Object

A custom helper to include an editor field without requiring a form object

name - The input name value - The input value options - The set of options to send to the field

:label   - The Boolean value to create or not the input label (optional) (default: true)
:toolbar - The String value to configure WYSIWYG toolbar. It should be 'basic' or
           or 'full' (optional) (default: 'basic')
:lines   - The Integer to indicate how many lines should editor have (optional)

Returns a rich editor to be included in an html template.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'app/helpers/decidim/decidim_form_helper.rb', line 38

def editor_field_tag(name, value, options = {})
  options[:toolbar] ||= "basic"
  options[:lines] ||= 10

  (:div, class: "editor") do
    template = ""
    template += label_tag(name, options[:label]) if options[:label] != false
    template += hidden_field_tag(name, value, options)
    template += (:div, nil, class: "editor-container", data: {
                              toolbar: options[:toolbar]
                            }, style: "height: #{options[:lines]}rem")
    template.html_safe
  end
end

#form_field_has_error?(object, attribute) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
# File 'app/helpers/decidim/decidim_form_helper.rb', line 157

def form_field_has_error?(object, attribute)
  object.respond_to?(:errors) && object.errors[attribute].present?
end

#foundation_datepicker_locale_tagObject



193
194
195
# File 'app/helpers/decidim/decidim_form_helper.rb', line 193

def foundation_datepicker_locale_tag
  javascript_include_tag "datepicker-locales/foundation-datepicker.#{I18n.locale}.js" if I18n.locale != :en
end

#name_with_locale(name, locale) ⇒ Object

Helper method used by ‘translated_field_tag`



153
154
155
# File 'app/helpers/decidim/decidim_form_helper.rb', line 153

def name_with_locale(name, locale)
  "#{name}_#{locale.to_s.gsub("-", "__")}"
end

#scopes_picker_field_tag(name, value, id: nil) ⇒ Object

A custom helper to include a scope picker field without requiring a form object

name - The input name value - The input value as a scope id options - The set of options to send to the field

:id - The id to generate for the element (optional)

Returns a scopes picker tag to be included in an html template.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'app/helpers/decidim/decidim_form_helper.rb', line 62

def scopes_picker_field_tag(name, value, id: nil)
  picker_options = {
    id: id || sanitize_to_id(name),
    class: "picker-single",
    name: name
  }

  prompt_params = yield(nil)
  selected_scopes = value ? Decidim::Scope.where(id: value) : []
  scopes = selected_scopes.map { |scope| [scope, yield(scope)] }

  template = ""
  template += render("decidim/scopes/scopes_picker_input",
                     picker_options: picker_options,
                     prompt_params: prompt_params,
                     scopes: scopes,
                     checkboxes_on_top: true)
  template.html_safe
end

#tab_element_class_for(type, index) ⇒ Object

Helper method used by ‘translated_field_tag`



146
147
148
149
150
# File 'app/helpers/decidim/decidim_form_helper.rb', line 146

def tab_element_class_for(type, index)
  element_class = "tabs-#{type}"
  element_class += " is-active" if index.zero?
  element_class
end

#translated_field_tag(type, object_name, name, value = {}, options = {}) ⇒ Object

A custom helper to include a translated field without requiring a form object.

type - The type of the translated input field. object_name - The object name used to identify the Foundation tabs. name - The name of the input which will be suffixed with the corresponding locales. value - A hash containing the value for each locale. options - An optional hash of options.

* enable_tabs: Adds the data-tabs attribute so Foundation picks up automatically.
* tabs_id: The id to identify the Foundation tabs element.
* label: The label used for the field.

Returns a Foundation tabs element with the translated input field.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/helpers/decidim/decidim_form_helper.rb', line 94

def translated_field_tag(type, object_name, name, value = {}, options = {})
  locales = available_locales

  field_label = label_tag(name, options[:label])

  if locales.count == 1
    field_name = "#{name}_#{locales.first.to_s.gsub("-", "__")}"
    field_input = send(
      type,
      "#{object_name}[#{field_name}]",
      value[locales.first.to_s]
    )

    return safe_join [field_label, field_input]
  end

  tabs_id = options[:tabs_id] || "#{object_name}-#{name}-tabs".underscore
  enabled_tabs = options[:enable_tabs].nil? ? true : options[:enable_tabs]
  tabs_panels_data = enabled_tabs ? { tabs: true } : {}

  label_tabs = (:div, class: "label--tabs") do
    tabs_panels = "".html_safe
    if options[:label] != false
      tabs_panels = (:ul, class: "tabs tabs--lang", id: tabs_id, data: tabs_panels_data) do
        locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
          string + (:li, class: tab_element_class_for("title", index)) do
            title = I18n.with_locale(locale) { I18n.t("name", scope: "locale") }
            element_class = nil
            element_class = "is-tab-error" if form_field_has_error?(options[:object], name_with_locale(name, locale))
            tab_content_id = "#{tabs_id}-#{name}-panel-#{index}"
            (:a, title, href: "##{tab_content_id}", class: element_class)
          end
        end
      end
    end

    safe_join [field_label, tabs_panels]
  end

  tabs_content = (:div, class: "tabs-content", data: { tabs_content: tabs_id }) do
    locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
      tab_content_id = "#{tabs_id}-#{name}-panel-#{index}"
      string + (:div, class: tab_element_class_for("panel", index), id: tab_content_id) do
        send(type, "#{object_name}[#{name_with_locale(name, locale)}]", value[locale.to_s], options.merge(id: "#{tabs_id}_#{name}_#{locale}", label: false))
      end
    end
  end

  safe_join [label_tabs, tabs_content]
end