LoginSignup
6
12

Bootstrap3 tabs - コントローラに応じて、activeタブを変更する。

Last updated at Posted at 2015-07-01

#概要

  • Bootstrap3 tabsを使用。
  • どのコントローラから呼ばれたかを検知し、activeタブを切り替える。

#経緯
ユーザーがフォームを提出後、検証に引っかかり、エラーメッセージとともにやり直しさせることは、よくあります。全てが別々のテンプレートであれば何も問題がないのですが、タブを使用し一画面で複数の機能を持たせる場合、activeタブを状況に応じて、切り替えたくなります。
例えば、タブのひとつに新規作成フォームがあるとします。再レンダリング後は、フォームをactiveにするのが自然です。しかしながら、何もしないと、いつもデフォルトがactiveになってしまいフォームが隠れてしまいます。

#やりたいことの流れ
####1. デフォルトでは表が表示される。
Screenshot 2015-07-02 21.50.48.png

####2. 新規作成用タブをクリックするとフォームが表示される。(検証に引っかかるよう、わざと空フォームを提出)

Screenshot 2015-07-02 21.51.15.png

####3. やり直しさせるのだから、再レンダリング後、(デフォルトのページを表示する代わりに)フォームのタブをactiveにしたい。
Screenshot 2015-07-02 21.51.39.png

#解決策
解決策のひとつとして現在のコントローラ名に応じて、タブを切り替える方法があります。テンプレートはHAMLで書いています。
以下の例では、デフォルト:#tabs_1がactiveで、MovingItemsControllerからレンダリングされた場合のみ例外的に#tabs_2をactiveにするとします。

####1. 最初、レンダリング前にCSSクラスを入れ替える方法を考えました。

show.html.haml
-# タブ用クラス
- active_tab      = "active"
- active_content  = %w[tab-pane fade active in]
- default_tab     = ""
- default_content = %w[tab-pane fade]

-# タブ交換機 in Ruby
- if params[:controller] == 'moving_items'
  - tab1, content1 = default_tab, default_content
  - tab2, content2 = active_tab, active_content   #<= ACTIVE
- else
  - tab1, content1 = active_tab, active_content   #<= ACTIVE
  - tab2, content2 = default_tab, default_content

/ タブ
%ul{ class: "nav nav-tabs", role: 'tablist' }
  %li{ class: tab1 }
    %a{ href: "#tabs_1", role: "tab", data: { toggle: "tab" } }
      All items
  %li{ class: tab2 }
    %a{ href: "#tabs_2", role: "tab", data: { toggle: "tab" } }
      Add item

/ タブコンテンツ
.tab-content
  #tabs_1{ class: content1 }
    - if @moving_items.count > 0
      = render 'moving_items/table'
    - else
      %p No item found
  #tabs_2{ class: content2 }
    = render 'moving_items/form'

####2. その後、リファクタリングしていたら、JavaScriptで対応した方がスッキリすることに気がつきました。

show.html.haml
/ タブ
%ul{ class: "nav nav-tabs", role: 'tablist', id: "tabs_movings" }
  %li{ class: "active" }
    %a{ href: "#tabs_1", role: "tab", data: { toggle: "tab" } }
      All items
  %li
    %a{ href: "#tabs_2", role: "tab", data: { toggle: "tab" } }
      Add item

/ タブコンテンツ
.tab-content
  #tabs_1{ class: "tab-pane fade active in" }
    - if @moving_items.count > 0
      = render 'moving_items/table'
    - else
      %p No item found
  #tabs_2{ class: "tab-pane fade" }
    = render 'moving_items/form'

:coffee
  // タブ交換機 in JavaScript
  // ページが読み込まれた後、2番目のタブをactiveにする。
  jQuery ->
    if #{ params[:controller] == 'moving_items' }
      $('#tabs_movings li:eq(1) a').tab('show')

以上です。

6
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
12