Module: NdrUi::BootstrapHelper

Overview

Provides helper methods for the Twitter Bootstrap framework

Constant Summary collapse

TYPE_STYLE_MAP =
{
  important: :danger,
  default: :secondary
}.freeze

Constants included from NdrUi::Bootstrap::ModalHelper

NdrUi::Bootstrap::ModalHelper::MODAL_SIZES

Constants included from NdrUi::Bootstrap::CardHelper

NdrUi::Bootstrap::CardHelper::CARD_TYPES

Instance Method Summary collapse

Methods included from NdrUi::Bootstrap::ModalHelper

#bootstrap_modal_body_tag, #bootstrap_modal_box, #bootstrap_modal_button, #bootstrap_modal_dialog_tag, #bootstrap_modal_footer_tag, #bootstrap_modal_header_tag, #bootstrap_modal_save_buttons

Methods included from NdrUi::Bootstrap::DropdownHelper

#bootstrap_list_divider_tag, #bootstrap_list_header_tag, #bootstrap_list_link_to

Methods included from NdrUi::Bootstrap::CardHelper

#bootstrap_card_body_tag, #bootstrap_card_list, #bootstrap_card_tag, #bootstrap_well_tag

Methods included from CssHelper

#css_class_options_merge

Methods included from NdrUi::Bootstrap::BreadcrumbsHelper

#bootstrap_breadcrumb, #bootstrap_breadcrumbs

Methods included from NdrUi::Bootstrap::AccordionHelper

#bootstrap_accordion_tag

Instance Method Details

#bootstrap_abbreviation_tag(name, abbreviation) ⇒ Object

Creates a Boostrap abbreviation tag (note: the acronym tag is not valid HTML5). Also adds the “initialism” class if the abbreviation is all upper case.

Signatures

bootstrap_abbreviation_tag(name, abbreviation)

Examples

<%= bootstrap_abbreviation_tag('NPI', 'Nottingham Prognostic Index') %>
# => <abbr class="initialism" title="Nottingham Prognostic Index">NPI</abbr>


234
235
236
237
238
239
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 234

def bootstrap_abbreviation_tag(name, abbreviation)
  (:abbr,
              name,
              title: abbreviation,
              class: (name == name.upcase ? 'initialism' : nil))
end

#bootstrap_alert_tag(*args, &block) ⇒ Object

Creates an alert box of the given type. It supports the following alert box types :alert, :danger, :info and :success.

Signatures

bootstrap_alert_tag(type, message, options = {})
bootstrap_alert_tag(type, options = {}) do
  # message
end

Options

  • dismissible: true - This will set whether or not a close X button will appear, allowing the alert box to be dismissed by the user. This is only supported with the Bootstrap layout and defaults to true. link to open in a popup window. By passing true, a default browser window will be opened with the URL. You can also specify an array of options that are passed-thru to JavaScripts window.open method.

  • All remaining options are treated as html attributes for the containing div tag. The class attribute is overwritten by the helper and so will be ignored if specified.

Examples

<%= bootstrap_alert_tag(:info, 'Check it out!!') %>
# => <div class="alert alert-info"><a href="#" class="btn-close"
data-bs-dismiss="alert"></a>Check it out!!</div>

You can use a block as well if your alert message is hard to fit into the message parameter. ERb example:

<%= bootstrap_alert_tag(:info) do %>
  Check it out!!
<% end %>
# => <div class="alert alert-info">Check it out!!
     <button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>

Ids for css and/or javascript are easy to produce:

<%= bootstrap_alert_tag(:info, 'Check it out!!', dismissible: false, id: "news") %>
# => <div class="alert alert-info" id="news">Check it out!!</div>


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 62

def bootstrap_alert_tag(*args, &block)
  type = args[0]
  if block_given?
    message = capture(&block)
    options = args[1] || {}
    bootstrap_alert_tag(type, message, options)
  else
    message = args[1] || ''
    options = args[2] || {}
    options.stringify_keys!

    classes = ['alert']
    classes << "alert-#{type}" if type && type != :alert
    unless options.include?('dismissible') && !options['dismissible']
      classes << 'alert-dismissible'
      options['dismissible'] = true
    end
    options['class'] = classes.join(' ')

    if options.delete('dismissible')
      message = message.html_safe + button_tag('', type: 'button', class: 'btn-close', 'data-bs-dismiss': 'alert')
    end
    (:div, message, options)
  end
end

#bootstrap_badge_tag(type, count) ⇒ Object

Creates an bootstrap badge of the given type. Bootstrap 3 does not support any types.

Signatures

bootstrap_badge_tag(type, count)

Examples

<%= bootstrap_badge_tag(:success, 'Check it out!!') %>
# => <span class="badge rounded-pill text-bg-success">Check it out!!</span>


117
118
119
120
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 117

def bootstrap_badge_tag(type, count)
  style = TYPE_STYLE_MAP[type] || type
  (:span, count, class: "badge rounded-pill text-bg-#{style}")
end

#bootstrap_caret_tagObject

Creates a simple bootstrap navigation caret.

Signatures

bootstrap_caret_tag

Examples

<%= bootstrap_caret_tag %>
# => <b class="caret"></b>


132
133
134
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 132

def bootstrap_caret_tag
  (:b, '', class: 'caret')
end

#bootstrap_dropdown_toggle_tag(body) ⇒ Object

Creates a simple bootstrap navigation dropdown.

Signatures

bootstrap_dropdown_toggle_tag(body)

Examples

<%= bootstrap_dropdown_toggle_tag('Check it out!!') %>
# => <a href="#" role="button" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Check it out!! <b class="caret"></b></a>


147
148
149
150
151
152
153
154
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 147

def bootstrap_dropdown_toggle_tag(body)
  link_to(ERB::Util.html_escape(body) + ' '.html_safe + bootstrap_caret_tag,
          '#',
          role: 'button',
          class: 'nav-link dropdown-toggle',
          'data-bs-toggle': 'dropdown',
          'aria-expanded': 'false')
end

#bootstrap_form_for(record_or_name_or_array, *args, &_proc) ⇒ Object

Identical signature to form_for, but uses NdrUi::BootstrapBuilder. See ActionView::Helpers::FormHelper for details



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 243

def bootstrap_form_for(record_or_name_or_array, *args, &_proc)
  options = args.extract_options!
  options[:html] ||= {}

  # :horizontal
  horizontal = options.delete(:horizontal)

  # stimuls controller, default `form_controller`
  options[:html][:'data-controller'] ||= ''
  controllers = (options[:html][:'data-controller'].split << 'form').uniq.join(' ')
  options[:html][:'data-controller'] = controllers

  # We switch autocomplete off by default
  raise 'autocomplete should be defined an html option' if options[:autocomplete]

  options[:html][:autocomplete] ||= 'off'

  form_for(record_or_name_or_array, *(args << options.merge(builder: NdrUi::BootstrapBuilder))) do |form|
    # Put the form builder into horizontal mode (if necessary)
    form.horizontal_mode = horizontal if horizontal

    # yield to the provided form block
    yield(form)
  end
end

#bootstrap_form_with(**options, &block) ⇒ Object

Identical signature to form_with, but uses NdrUi::BootstrapBuilder. See ActionView::Helpers::FormHelper for details



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 271

def bootstrap_form_with(**options, &block)
  options[:html] ||= {}
  options[:builder] = NdrUi::BootstrapBuilder
  horizontal = options.delete(:horizontal)

  # stimuls controller, default `form_controller`
  options[:html][:'data-controller'] ||= ''
  controllers = (options[:html][:'data-controller'].split << 'form').uniq.join(' ')
  options[:html][:'data-controller'] = controllers

  # We switch autocomplete off by default
  raise 'autocomplete should be defined an html option' if options[:autocomplete]

  options[:html][:autocomplete] ||= 'off'

  form_with(**options) do |form|
    # Put the form builder into horizontal mode (if necessary)
    form.horizontal_mode = horizontal if horizontal

    # yield to the provided form block
    block.call(form)
  end
end

#bootstrap_horizontal_form_group(label = nil, ratio = [2, 10], &block) ⇒ Object

Supply optional label. Use options for grid split/offset. The default is [2, 10], where 2 is label columns / offset, and 10 is content width. If the label is omitted, the content is offset by the same number of columns instead.

Examples

bootstrap_horizontal_form_group("The Label", [3, 9]) { 'This is the content' }
# =>
  <div class="form-group row">
    <label class="col-sm-3 col-form-label">The Label</label>
    <div class="col-sm-9">This is the content</div>
  </div>


389
390
391
392
393
394
395
396
397
398
399
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 389

def bootstrap_horizontal_form_group(label = nil, ratio = [2, 10], &block)
  l, r   = ratio[0..1].map(&:to_i)
  offset = label.nil? ? " offset-sm-#{l}" : ''

  # Main content:
  content = (:div, class: "col-sm-#{r}" + offset, &block)
  # Prepend optional label:
  content = (:label, label, class: "col-sm-#{l} col-form-label") + content unless label.nil?

  (:div, content, class: 'form-group row')
end

#bootstrap_icon_spinner(type = :default) ⇒ Object

Creates a simple bootstrap icon spinner.

Signatures

bootstrap_icon_spinner(type)

Examples

<%= bootstrap_icon_spinner(:danger) %>

> <img style=“width:12px;padding-bottom:2px;” src=“/assets/indicator-danger.gif”>



186
187
188
189
190
191
192
193
194
195
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 186

def bootstrap_icon_spinner(type = :default)
  spinner = case type
            when :danger
              'indicator-danger.gif'
            else
              'indicator-white.gif'
            end

  image_tag(spinner, style: 'width:12px;padding-bottom:2px;', alt: spinner)
end

#bootstrap_icon_tag(type, set = :glyphicon) ⇒ Object

Creates a simple bootstrap icon.

Signatures

bootstrap_icon_tag(type)

Examples

<%= bootstrap_icon_tag(:search, :bi) %>
# => <i class="bi-search"></i>

<%= bootstrap_icon_tag(:search, :glyphicon) %>
# => <span class="glyphicon glyphicon-search"></span>


169
170
171
172
173
174
175
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 169

def bootstrap_icon_tag(type, set = :glyphicon)
  if set == :bi
    (:i, '', class: "bi-#{type}")
  else
    (:span, '', class: "glyphicon glyphicon-#{type}")
  end
end

#bootstrap_label_tag(type, message) ⇒ Object

Creates an bootstrap label of the given type. It supports the following types :default, :success, :warning, :danger, :info and :primary.

Signatures

bootstrap_label_tag(type, message)

Examples

<%= bootstrap_label_tag(:info, 'Check it out!!') %>
# => <span class="label label-info">Check it out!!</span>


101
102
103
104
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 101

def bootstrap_label_tag(type, message)
  style = TYPE_STYLE_MAP[type] || type
  (:span, message, class: "badge text-bg-#{style}")
end

Convenience wrapper for a bootstrap_list_link_to with badge



214
215
216
217
218
219
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 214

def bootstrap_list_badge_and_link_to(type, count, name, path)
  html = (:div, bootstrap_badge_tag(type, count), class: 'float-end') +
         (:div, name, class: 'pe-5')

  bootstrap_list_link_to(html, path)
end

#bootstrap_progressbar_tag(*args) ⇒ Object

Creates a Boostrap progress bar.

Signatures

bootstrap_progressbar_tag(options)

Examples

<%= bootstrap_progressbar_tag(40) %>
# => <div class="progress progress-striped active" title="40%"><div class="progress-bar"
style="width:40%"></div></div>

<%= bootstrap_progressbar_tag(40), type: :danger %>
# => <div class="progress progress-striped active" title="40%"><div
class="progress-bar bg-danger" style="width:40%"></div></div>

Browser compatibility

Bootstrap Progress bars use CSS3 gradients, transitions, and animations to achieve all their effects. These features are not supported in IE7-9 or older versions of Firefox. Versions earlier than Internet Explorer 10 and Opera 12 do not support animations.



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 351

def bootstrap_progressbar_tag(*args)
  percentage = args[0].to_i
  options = args[1] || {}
  options.stringify_keys!
  options['title'] ||= "#{percentage}%"

  classes = ['progress']
  classes << options.delete('class')
  classes << 'progress-striped'

  type = options.delete('type').to_s
  type = " bg-#{type}" if type.present?

  # Animate the progress bar unless something has broken:
  classes << 'active' unless type == 'danger'

  inner = (:div, '', class: "progress-bar#{type}", style: "width:#{percentage}%")

  options['class'] = classes.compact.join(' ')
  (:div, inner, options)
end

#bootstrap_tab_nav_tag(title, linkto, active = false) ⇒ Object

Creates a simple bootstrap tab navigation.

Signatures

bootstrap_tab_nav_tag(title, linkto, active = false)

Examples

<%= bootstrap_tab_nav_tag("Fruits", "#fruits", true) %>
# => <li class="nav-item"><a class="nav-link active" href="#fruits" data-bs-toggle="tab">Fruits</a></li>


207
208
209
210
211
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 207

def bootstrap_tab_nav_tag(title, linkto, active = false)
  ('li',
              link_to(title, linkto, 'data-bs-toggle': 'tab', class: "nav-link#{active ? ' active' : ''}"),
              class: 'nav-item')
end

#button_control_group(*args, &block) ⇒ Object

Creates a Boostrap control group for button.

Signatures

button_control_group(controls, options = {})
button_control_group(options = {}) do
  # controls
end

Examples

<%= button_control_group("Apples", class: "some_class") %>
# =>
<div class="form-group">
  <div class="col-sm-9 offset-sm-3">
    <div class="some_class">Apples</div>
  </div>
</div>


315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 315

def button_control_group(*args, &block)
  return button_control_group(capture(&block), *args) if block_given?
  options = args.extract_options!
  options.stringify_keys!

  if options.delete('horizontal') == false
    options['class'] = ('form-group' + ' ' + options['class'].to_s).strip
    (:div, args.first, options)
  else
    bootstrap_horizontal_form_group nil, [3, 9] do
      options.blank? ? args.first : (:div, args.first, options)
    end
  end
end

#button_group(&block) ⇒ Object

Creates a Boostrap button group.

Signatures

button_group(&block)

Examples

<%= button_group { link_to('Hello World', '#') } %>
# => <div class="btn-group"><a href="#">Hello World</a></div>


450
451
452
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 450

def button_group(&block)
  (:div, capture(&block), class: 'btn-group')
end

#button_toolbar(&block) ⇒ Object

Creates a Boostrap button toolbar.

Signatures

button_toolbar(&block)

Examples

<%= button_toolbar { link_to('Hello World', '#') } %>
# => <div class="btn-toolbar"><a href="#">Hello World</a></div>


435
436
437
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 435

def button_toolbar(&block)
  (:div, capture(&block), class: 'btn-toolbar')
end

Creates a Boostrap ‘Delete’ link.

Signatures

delete_link(path, options = {})

Examples

<%= delete_link('#') %>
# => <a title="Delete" class="btn btn-sm btn-outline-danger" rel="nofollow" href="#"
        data-method="delete" data-confirm="Are you sure?">
       <span class="glyphicon glyphicon-trash icon-white"></span>
     </a>'


537
538
539
540
541
542
543
544
545
546
547
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 537

def delete_link(path, options = {})
  return unless options.delete(:skip_authorization) || ndr_can?(:delete, path)

  defaults = {
    icon: 'trash icon-white', title: 'Delete', path: path,
    class: 'btn btn-sm btn-outline-danger', method: :delete,
    'data-confirm': I18n.t(:'ndr_ui.confirm_delete', locale: options[:locale])
  }

  link_to_with_icon(defaults.merge(options))
end

#description_list_name_value_pair(name, value, blank_value_placeholder = nil) ⇒ Object

This helper produces a pair of HTML dt, dd tags to display name and value pairs. If a blank_value_placeholder is not defined then the pair are not shown if the value is blank. Otherwise the placeholder is shown in the text-muted style.

Signature

description_list_name_value_pair(name, value, blank_value_placeholder = nil)

Examples

<%= description_list_name_value_pair("Pear", "Value") %>
# => <dt>Pear</dt><dd>Value</dd>

<%= description_list_name_value_pair("Pear", nil, "[none]") %>
# => <dt>Pear</dt><dd><span class="text-muted">[none]</span></dd>


417
418
419
420
421
422
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 417

def description_list_name_value_pair(name, value, blank_value_placeholder = nil)
  # SECURE: TPG 2013-08-07: The output is sanitised by content_tag
  return unless value.present? || blank_value_placeholder.present?
  (:dt, name) +
    (:dd, value || (:span, blank_value_placeholder, class: 'text-muted'))
end

Creates a Boostrap ‘Details’ link.

Signatures

details_link(path, options = {})

Examples

<%= details_link('#') %>
# => <a title="Details" class="btn btn-default btn-sm" href="#">
       <span class="glyphicon glyphicon-share-alt"></span>
     </a>


497
498
499
500
501
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 497

def details_link(path, options = {})
  return unless options.delete(:skip_authorization) || ndr_can?(:read, path)

  link_to_with_icon({ icon: 'share-alt', title: 'Details', path: path }.merge(options))
end

Creates a Boostrap ‘Edit’ link.

Signatures

edit_link(path, options = {})

Examples

<%= edit_link(#) %>
# => <a title="Edit" class="btn btn-default btn-sm" href="#">
       <span class="glyphicon glyphicon-pencil"></span>
     </a>


516
517
518
519
520
521
522
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 516

def edit_link(path, options = {})
  return unless options.delete(:skip_authorization) || ndr_can?(:edit, path)

  path = edit_polymorphic_path(path) if path.is_a?(ActiveRecord::Base)

  link_to_with_icon({ icon: 'pencil', title: 'Edit', path: path }.merge(options))
end

#inline_controls_for(object, options = {}) ⇒ Object

Creates a Boostrap inline menu, with show/edit/delete links. If possibly, conditionally checks permissions

Signatures

inline_controls_for(object, options = {})

Examples

# creates: [ [delete] ] [ [edit] [details] ]
<%= inline_controls_for(@post) %>


561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 561

def inline_controls_for(object, options = {})
  groups = []

  groups << delete_link(object)

  main_group = [edit_link(object, options), details_link(object, options)]
  groups << safe_join(main_group) if main_group.any?

  groups.compact!
  groups.map! { |group| button_group { group } }

  button_toolbar { safe_join(groups) } if groups.any?
end

Creates a Boostrap link with icon.

Signatures

link_to_with_icon(options)

Examples

<%= link_to_with_icon( { icon: 'trash icon-white', title: 'Delete', path: '#' } ) %>
# => <a title="Delete" class="btn btn-default btn-sm" href="#">
       <span class="glyphicon glyphicon-trash icon-white"></span>
     </a>'


587
588
589
590
591
592
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 587

def link_to_with_icon(options = {})
  options[:class] ||= 'btn btn-default btn-sm'
  icon = bootstrap_icon_tag(options.delete(:icon))
  content = options.delete(:text) ? "#{icon} #{options[:title]}" : icon
  link_to content, options.delete(:path), options
end

Creates a Boostrap ‘New’ link.

Signatures

new_link(path, options = {})

Examples

<%= new_link('#') %>
# => <a title="New" class="btn btn-primary btn-sm" href="#">
       <span class="glyphicon glyphicon-plus-sign"></span>
     </a>

<%= new_link(Post.new) %>
# => <a title="New" class="btn btn-primary btn-sm" href="/posts/new">
       <span class="glyphicon glyphicon-plus-sign"></span>
     </a>


472
473
474
475
476
477
478
479
480
481
482
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 472

def new_link(path, options = {})
  return unless options.delete(:skip_authorization) || ndr_can?(:new, path)

  path = new_polymorphic_path(path) if can_generate_polymorphic_path?(path)

  defaults = {
    icon: 'plus-sign', title: 'New', path: path, class: 'btn btn-primary btn-sm'
  }

  link_to_with_icon(defaults.merge(options))
end

#select_tag(name, option_tags = nil, options = {}) ⇒ Object

ensure ‘form-control` and `form-select` classes added to select_tag



16
17
18
19
20
# File 'app/helpers/ndr_ui/bootstrap_helper.rb', line 16

def select_tag(name, option_tags = nil, options = {})
  options = css_class_options_merge(options, %w[form-control form-select])

  super(name, option_tags, options)
end