Module: ListboxHelper

Defined in:
app/helpers/listbox_helper.rb

Constant Summary collapse

%w[dropdown b-dropdown gl-dropdown btn-group js-redirect-listbox].freeze
%w[btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle].freeze
'gl-dropdown-button-text'
'gl-button-icon dropdown-chevron gl-icon'

Instance Method Summary collapse

Instance Method Details

#gl_redirect_listbox_tag(items, selected, html_options = {}) ⇒ Object

Creates a listbox component with redirect behavior.

Use this for migrating existing deprecated dropdowns to become Pajamas-compliant. New features should use Vue components directly instead.

The ‘items` parameter must be an array of hashes, each with `value`, `text` and `href` keys, where `value` is a unique identifier for the item (e.g., the sort key), `text` is the user-facing string for the item, and `href` is the path to redirect to when that item is selected.

The ‘selected` parameter is the currently selected `value`, and should correspond to one of the `items`, or be `nil`. When `selected.nil?` or a value which does not correspond to one of the items, the first item is selected.

The final parameter ‘html_options` applies arbitrary attributes to the returned tag. Some of these are passed to the underlying Vue component as props, e.g., to right-align the menu of items, add `data: { placement: ’right’ }‘.

Examples:

# Create a listbox with two items, with the first item selected
- items = [{ value: 'foo', text: 'Name, ascending', href: '/foo' },
           { value: 'bar', text: 'Name, descending', href: '/bar' }]
= gl_redirect_listbox_tag items, 'foo'

# Create the same listbox, right-align the menu and add margin styling
= gl_redirect_listbox_tag items, 'foo', class: 'gl-ml-3', data: { placement: 'right' }


36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/helpers/listbox_helper.rb', line 36

def gl_redirect_listbox_tag(items, selected, html_options = {})
  # Add script tag for app/assets/javascripts/entrypoints/behaviors/redirect_listbox.js
  content_for :page_specific_javascripts do
    webpack_bundle_tag 'redirect_listbox'
  end

  selected_option = items.find { |opt| opt[:value] == selected }

  unless selected_option
    selected_option = items.first
    selected = selected_option[:value]
  end

  button = button_tag(type: :button, class: DROPDOWN_BUTTON_CLASSES) do
    (:span, selected_option[:text], class: DROPDOWN_INNER_CLASS) +
      sprite_icon('chevron-down', css_class: DROPDOWN_ICON_CLASS)
  end

  classes = [*DROPDOWN_CONTAINER_CLASSES, *html_options[:class]]
  data = html_options.fetch(:data, {}).merge(items: items, selected: selected)

  (:div, button, html_options.merge({
    class: classes,
    data: data
  }))
end