About Build Status Dependency Status Code Climate Coverage Status

The project defines a collection of widgets to be used inside views. It also contains some js files to provide additional behavior for html elemets, created by those widgets. Both helpers and js are compatible with Twitter Bootstrap framework.

Installation

Add this line to your application's Gemfile:

gem 'rails-bootstrap-widgets'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-bootstrap-widgets

Available widgets

List widgets

This group consists of two widgets to be used in views that contain items lists.

pagination_widget (helper method)

pagination_widget(items, options = {})

The widget simply wraps pager (from the will-paginate gem) into the <aside> tag.

Example

pagination_widget @items, class: 'span4'

This will create

<aside class="span4">
  <!-- Standard result of 'will_paginate(@items, inner_window: 0, outer_window: 0)' call -->
</aside>

filters_widget (helper method)

filters_widget(items, options = {})

The widgets create html for filtering, ordering and paging a list of items. Provided html will include:

  1. Input field to select filter from those are available
  2. Input field to select order from those are available
  3. (Hidden) button to reset filter values
  4. Button to reload the page with new filter values
  5. Items pager

This html code should provide basic functionality without js support.

If js support is turned on in a client's browser, jQuery method will show reset button (js required) and hide reload button. It also makes current page to be updated authomatically after new filter or ordering is selected, or reset button clicked.

Example

filters_widget (
  @items,
  filters: { published: :Published, unpublished: :Unpublished}, # list of filters to select from in a format { key: :name }
  filter: 'published',                                          # key of the current filter to apply to items
  orders: { tree: :Tree, feed: :Feed },                         # list of types of items ordering to select from
  order: 'tree'                                                 # key of the current order type
)

This will provide html:

<form accept-charset="UTF-8" action="/" class="span8" id="filters" method="get">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
  </div>
  <div class="input-prepend">
    <span class="add-on">
      <i class="icon-filter"></i>
    </span>
    <select id="filter" name="filter">
      <option value="published" selected="selected">Published</option>
      <option value="unpublished">Unpublished</option>
    </select>
  </div>
  <div class="input-prepend">
    <span class="add-on">
      <i class="icon-order"></i>
    </span>
    <select id="order" name="order">
      <option value="tree" selected="selected">Tree</option>
      <option value="feed">Feed</option>
    </select>
  </div>
  <a href="#" class="btn add-on hide" id="reset">
    <i class="icon-reset"></i>
  </a>
  <div class="input-prepend" id="reload">
    <span class="add-on">
      <i class="icon-reload"></i>
    </span>
    <input class="btn" name="commit" type="submit" value="Reload" />
  </div>
</form>
<aside class="span4">
  <!-- Standard result of 'will_paginate(items, inner_window: 0, outer_window: 0)' call -->
</aside>

Filters js support

The module adds file filters.js.coffee to app/assets/js/ to authomatically reload current page after new filter or ordering selected by a user.

When current page is reloaded:

  1. Filters reload button is removed (reloading became authomatic instead)
  2. Filters reset button is added (it clears both filter and order field and reload the page with no filter|order set. They can be set by default within a controller)
  3. Adds reloading the page on selecting new input field value (filter or order)
modal_form_widget(options = {}, &block)

The widget puts a list of fields (inputs, selectors etc.) into a modal form window (presented by <form id='modal' class='modal fade'...>)

Details

modal_form_widget (
  title: 'modal window title',              # required
  action: 'path to corresponding route',    # required
  method: 'request method for the form',    # "post" by default, "post", "get", "put" or "delete" extected
  button: 'text on the submit button',      # I18n.t("buttons.submit") by default
  cancel: 'text on the cancel form button'  # I18n.t("buttons.cancel") by default
) do
  "" # html code of form fields
end

Example

modal_form_widget(title: 'Title', button: 'Button', method: :put, action: '/some_addr', cancel: "Cancel") { "content" }

This will create

<form accept-charset="UTF-8" action="/some_addr" class="modal fade" data-remote="true" id="modal" method="post">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="&#x2713;" />
  </div>
  <input id="_method" name="_method" type="hidden" value="put" />
  <header class="modal-header">
    <button aria-hidden="true" class="close" data-dismiss="modal" type="button">&times;</button>
    <h1>Title</h1>
  </header>
  <div class="modal-body">content</div>
  <div class="modal-footer">
    <a href="#" aria-hidden="true" class="btn" data-dismiss="modal">Cancel</a>
    <input class="btn btn-primary" id="submit" name="commit" type="submit" value="Button" />
  </div>
</form>
modal_view_widget(options = {}, &block)

The widget puts html code into a modal window (presented by <div id='modal' class='modal fade'>)

Details

modal_view_widget (
  title: 'modal window title',              # required
  href: 'path for redirection to details',  # required
  redirect: true|false,                     # whether redirect button should be shown in the modal window footer (true by default),
  button: 'text on the redirect button',    # I18n.t("buttons.details") by default
  cancel: 'text on the cancel form button'  # I18n.t("buttons.cancel") by default
) do
  "" # modal window's html content
end

Example

modal_view_widget(title: 'Title', button: 'Button', href: '/some_addr', cancel: "Cancel") { "content" }

This will create

<div class="modal fade" id="modal">
  <header class="modal-header">
    <button aria-hidden="true" class="close" data-dismiss="modal" type="button">&times;</button>
    <h1>Title</h1>
  </header>
  <div class="modal-body">content</div>
  <div class="modal-footer">
    <a href="#" aria-hidden="true" class="btn" data-dismiss="modal">Cancel</a>
    <a href="/some_addr" class="btn btn-primary">Button</a>
  </div>
</div>

showModal (js function)

showModal(href, template, width = nil)

Provides jQuery method "show_modal" to download and open modal window via ajax.

Arguments

href - path to corresponding ajax request (required).

When modal window is loaded, any link with selected href and data-remote='true' attribute is converted to modal window call. Direct links (without data-remote) remain unchanged.

Before another modal window is loaded, the calls are reverted back to ajax links. Next time the modal should be downloaded by ajax again. To prevent excess downloading, use http request caching (see RailsCast episode #321 for example).

template - path to modal window template (required).

This template will be rendered and incerted by ajax to html - before the closing </body> tag.

Before another modal window is loaded, previous modal window is removed. Therefore at any given time the page will contain no more than one modal window

width - width in pixels for the modal link. If not set, the default bootstrap modal window is rendered.

Example

In the app/views/posts/show.js.coffee you could call:

showModal('<%= post_path(@item) %>', "<%= j render 'modal/show' %>")

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

This project rocks and uses MIT-LICENSE.