BanditHijo.dev

Selected Menu Item pada Rails View Template

Created at: 2021-02-09
Author by: BanditHijo

Prerequisite

ruby 2.7.2 rails 6.1.1 bootstrap 4.6.x

Latar Belakang

Kali ini saya kembali mencatat perihal front-end pada Ruby on Rails untuk membuat menu yang dapat menampilkan indikator aktif (selected) saat berada pada halaman yang dipilih.

Gambar 1

Gambar 1. Selected menu item di Rails

Pada demonstrasi Gambar 1 di atas, saya menggunakan Accordion/Collapsibles dengan Bootstrap card yang sudah dimodifikasi.

Cukup banyak cara yang dapat kita gunakan untuk membuat selected menu item.

Saya akan coba meng-cover sebanyak yang saya pernah gunakan.

INFO

Style class dan filename, hanya ilustrasi.

Saya perlu mempersingkat class agar code tidak terlalu panjang.

Jadi, jangan bingung apabila kode terapan tidak akan mirip dengan contoh di Gambar 1 di atas apabila digunakan.

Penerapan

Menggunakan Controller atau Action Name

Setiap params hash selalu berisi controller dan action, untuk mengetahui valuenya di view template dengan cara seperti ini.

1<%= controller.controller_name %>
1<%= controller.action_name %>

Atau yang lebih sederhana,

1<%= controller_name %>
1<%= action_name %>

Nah, kalau sudah begini, tinggal kita jadikan perbandingan saja.

Misal seperti ini:

1<div class="collapse <%= 'show' if controller_name == 'home' %>"></div>
1<div class="collapse <%= 'show' if action_name == 'index' %>"></div>

Penerapan ke view templatenya akan seperti ini:

app/views/shared/_navbar.html.erb
1<ul class="nav nav-tabs mb-3">
2 <li class="nav-item">
3 <%= link_to "Beranda", root_path,
4 class: "nav-link #{'active' if controller_name == 'home'}" %>
5 </li>
6 <li class="nav-item">
7 <%= link_to "Blog", blog_path,
8 class: "nav-link #{'active' if controller_name == 'blog'}" %>
9 </li>
10</ul>

Bagaimana kalau satu menu yang sama, tetapi digunakan untuk menampilkan dua atau lebih halaman yang berbeda?

Mudah, kita dapat menggunakan bentuk array dengan method include?.

1<div class="collapse <%= 'show' if ['home', 'blog'].include? controller_name %>"></div>
1<div class="collapse <%= 'show' if ['index', 'new', 'edit'].include? action_name %>"></div>

Menggunakan Routing Prefix dengan Request Path

1<div class="collapse <%= 'show' if [admins_root_path, admins_dashboard_path].include? request.path %>"></div>

Dapat dilihat, saya memiliki array dengan dua buah routing prefix:

1[admins_root_path, admins_dashboard_path]

Kemudian saya buat single if condition:

Tampilkan 'show' jika path yang di request termasuk di dalam isi dari array [admins_root_path, admins_dashboard_path].

Nah, penerapan ke view templatenya akan seperti ini:

Dapat dilihat pada bari 4, 11, 14.

app/views/shared/_sidebar.html.erb
1<div class="card">
2 <div class="card-header" id="headingOne">
3 <h2 class="mb-0">
4 <button class="btn btn-block <%= 'collapsed' unless [admins_root_path, admins_dashboard_path].include? request.path %>" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
5 <%= bootstrap_icon 'house-fill' %>
6 <%= 'Beranda' %>
7 </button>
8 </h2>
9 </div>
10
11 <div id="collapseOne" class="collapse <%= 'show' if [admins_root_path, admins_dashboard_path].include? request.path %>" aria-labelledby="headingOne">
12 <div class="card-body">
13 <ul class="list-group list-group-flush">
14 <li class="list-group-item <%= 'active' if [admins_dashboard_path, admins_root_path].include? request.path %>" aria-current="true">
15 <%= link_to admins_dashboard_path, class: 'child-menu-sidebar d-flex align-items-center' do %>
16 <%= bootstrap_icon 'pie-chart' %>
17 <%= 'Dashboard' %>
18 <% end %>
19 </li>
20 <li class="list-group-item d-flex align-items-center" aria-current="true">
21 <%= link_to nil, class: 'child-menu-sidebar d-flex align-items-center' do %>
22 <%= bootstrap_icon 'rss' %>
23 <%= 'Feed' %>
24 <% end %>
25 </li>
26 <li class="list-group-item d-flex align-items-center" aria-current="true">
27 <%= link_to nil, class: 'child-menu-sidebar d-flex align-items-center' do %>
28 <%= bootstrap_icon 'back' %>
29 <%= 'Landing' %>
30 <% end %>
31 </li>
32 </ul>
33 </div>
34 </div>
35</div>

Menggunakan ActionView Helper

Kita dapat membuat method sendiri yang dapat kita gunakan di view template.

Saya akan meletakkan di app/helpers/application_helper.rb.

app/helpers/application_helper.rb
1module ApplicationHelper
2 ACTIVE_CLASS = 'is-active'.freeze
3
4 def active_for(options)
5 name_of_controller = options.fetch(:controller) { nil }
6 name_of_action = options.fetch(:action) { nil }
7 request_path = options.fetch(:path) { nil }
8
9 return ACTIVE_CLASS if request_path && request_path == request.path
10
11 if name_of_controller == controller_name
12 ACTIVE_CLASS if name_of_action.nil? || (name_of_action == action_name)
13 end
14 end
15end

Dan, penerapan pada view templatenya akan seperti ini:

Terdapat 2 cara yang dapat digunakan:

  1. Menggunakan routing path
  2. Menggunakan controller atau action name
app/views/shared/_navbat.html.erb
1<div id="navbar" class="navbar-collapse collapse">
2 <ul class="nav navbar-nav navbar-right">
3 <li class='<%= active_for(path: "/users/#{current_user.id}") %>'>
4 <%= link_to current_user %>
5 </li>
6 <li class='<%= active_for(controller: "events") %>'>
7 <%= link_to events_path %>
8 </li>
9 <li class='<%= active_for(controller: "users", action: "edit") %>'>
10 <%= link_to edit_user_path(current_user) %>
11 </li>
12 </ul>
13</div>

Pesan Penulis

Sepertinya, segini dulu yang dapat saya tuliskan.

Selanjutnya, saya serahkan kepada imajinasi dan kreatifitas teman-teman. Hehe.

Mudah-mudahan dapat bermanfaat.

Terima kasih.

(^_^)

Referensi

  1. How TO - Collapsibles/Accordion
    Diakses tanggal: 2021/02/09

  2. gist.github.com/pelted/5dac756f690a61f698145dc9495a9633
    Diakses tanggal: 2021/02/09

  3. pelted/application_helper.rb.
    Diakses tanggal: 2021/02/09