Mulai April 2020, bandithijo.com akan menggunakan GitHub subdomain menjadi bandithijo.github.io. Penggunaan domain .com tidak sejalan dengan cara pandang saya terhadap sebuah blog, dimana blog harus bisa tetap hidup tanpa saya. Terima kasih (^_^) (bandithijo, 2020/03/25) ●

بسم الله الرحمن الرحيم

Latar Belakang

Tujuannya menggunakan AJAX untuk menampilkan hasil tanpa perlu mereload tempate berulang kali. Cukup sekali panggil dan yang berubah adalah pada bagian hasilnya saja.

gambar_1

Gambar 1 - Kotak merah adalah satu-satunya bagian yang berubah, sedangkan bagian lain tidak.

Cara yang umum, untuk menampilkan output seperti di atas, adalah seperti ini.

FILEapp/controllers/stocks_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class StocksController < ApplicationController
  def index
    @tracked_stocks = current_user.stocks
  end

  def search
    if params[:stock].present?
      @stock = Stock.new_lookup(params[:stock].upcase)
      if @stock
        render 'users/my_portfolio'
      else
        flash[:alert] = 'Please enter a VALID symbol to search'
        redirect_to my_portfolio_path
      end
    else
      flash[:alert] = 'Please enter a symbol to search'
      redirect_to my_portfolio_path
    end
  end
end
FILEconfig/routes.rb
1
2
3
4
5
6
7
Rails.application.routes.draw do
  root 'welcome#index'
  devise_for :users

  get 'my_portfolio', to: 'stocks#index'
  get 'search_stock', to: 'stocks#search'
end
FILEapp/views/stocks/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<h3>Search Stocks</h3>
<%= form_tag search_stock_path, method: :get do %>
  <div class="input-group">
    <%= text_field_tag :stock, params[:stock],
                       class: "form-control form-control-lg",
                       placeholder: "Stock ticker symbol",
                       onkeyup: "this.value = this.value.toUpperCase();",
                       autofocus: true %>
    <div class="input-group-append">
      <%= button_tag type: :submit, class: "btn btn-success" do %>
        <%= fa_icon "search 2x" %>
      <% end %>
    </div>
  </div>
<% end %>

<% if @stock %>
  <div class="alert alert-success">
    <div class="row d-flex justify-content-between">
      <div class="col-sm-9 align-self-center">
        <strong>Symbol: </strong><%= @stock.ticker %>
        <strong>Name: </strong><%= @stock.name %>
        <strong>Price: </strong><%= @stock.last_price %>
      </div>
      <div class="col-sm-3">
        <%= link_to "Add to Portfolio", stocks_path(user: current_user, ticker: @stock.ticker),
                    method: :post,
                    class: "btn btn-success btn-block mx-2" %>
      </div>
    </div>
  </div>
<% end %>

<% unless @tracked_stocks.empty? %>
  <table class="table table-borderless table-hover my-3">
    <thead>
      <tr>
        <th>Ticker</th>
        <th>Name</th>
        <th>Price</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <% @tracked_stocks.each do |stock| %>
        <tr>
          <td><%= stock.ticker %></td>
          <td><%= stock.name %></td>
          <td><%= stock.last_price %></td>
          <td>'Action Placeholder'</td>
        </tr>
      <% end %>
    </tbody>
  </table>
<% end %>

Setelah form diinputkan, dan hasil ditampilkan, akan mendapatkan URL seperti ini.

localhost:3000/search_stock?stock=AMZN&button=

Apabila kita menginputkan nilai yang lain, maka template akan ikut dirender untuk menampilkan hasil pencarian yang baru.

localhost:3000/search_stock?stock=GOOG&button=

Nah, pada catatan kali ini, saya akan membuat template dirender sekali saja dan hanya pada bagian yang menampilkan hasil pencarian yang dirender berkali-kali.

Pemecahan Masalah

Pertama-tama, saya akan merubah output di stocks_controller pada action search menjadi format Javascript.

FILEapp/controllers/stocks_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class StocksController < ApplicationController
  def index
    @tracked_stocks = current_user.stocks
  end

  def search
    if params[:stock].present?
      @stock = Stock.new_lookup(params[:stock].upcase)
      if @stock
        respond_to do |format|
          format.js { render partial: 'users/result' }
        end
      else
        respond_to do |format|
          flash.now[:alert] = 'Please enter a VALID symbol to search'
          format.js { render partial: 'users/result' }
        end
      end
    else
      respond_to do |format|
        flash.now[:alert] = 'Please enter a symbol to search'
        format.js { render partial: 'users/result' }
      end
    end
  end
end


Kemudian, pada bagian view, pisahkan bagian result, menjadi render partial, saya beri nama _result.html.erb.

FILEapp/views/stocks/_result.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<% if stock %>
  <div class="alert alert-success">
    <div class="row d-flex justify-content-between">
      <div class="col-sm-9 align-self-center">
        <strong>Symbol: </strong><%= stock.ticker %>
        <strong>Name: </strong><%= stock.name %>
        <strong>Price: </strong><%= stock.last_price %>
      </div>
      <div class="col-sm-3">
        <%= link_to "Add to Portfolio", stocks_path(user: current_user, ticker: stock.ticker),
                    method: :post,
                    class: "btn btn-success btn-block mx-2" %>
      </div>
    </div>
  </div>
<% end %>


Pada bagian yang kita pindahkan (kode di atas) di view stocks/index.html.erb, kita ganti dengan <div id=results>.

FILEapp/views/stocks/index.html.erb
1
2
3
4
...
...

<div id="results"></div>


Kita akan meletakkan hasil yang diberikan oleh controller pada div denga id=result tersebut.

Kita akan atur di dalam file javascript, buat file _result.js.erb.

FILEapp/views/stocks/_result.js.erb
1
document.querySelector('#results').innerHTML = "<%= escape_javascript(render 'users/result.html', stock: @stock) %>"


Terakhir, tinggal menambahkan asynchronous form pada form pencarian dengan remote: true.

FILEapp/views/stocks/index.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<h3>Search Stocks</h3>
<%= form_tag search_stock_path, remote:true, method: :get do %>
  <div class="input-group">
    <%= text_field_tag :stock, params[:stock],
                       class: "form-control form-control-lg",
                       placeholder: "Stock ticker symbol",
                       onkeyup: "this.value = this.value.toUpperCase();",
                       autofocus: true %>
    <div class="input-group-append">
      <%= button_tag type: :submit, class: "btn btn-success" do %>
        <%= fa_icon "search 2x" %>
      <% end %>
    </div>
  </div>
<% end %>

...
...


Hasilnya,

gambar_2

Kalau diperhatikan pada bagian address bar, alamat tidak berubah. Karena kita tidak merender template lagi untuk menampilkan hasil, namun hanya merubah bagian yang memiliki <div id=results></div>.

Pesan Penulis

Sepertinya, segini dulu yang dapat saya tuliskan.

Mudah-mudahan dapat bermanfaat.

Terima kasih.

(^_^)

Penulis

bandithijo

BanditHijo adalah nama pena saya – meminjam istilah keren dari para penulis. Teman-teman menyebut saya sebagai GNU/Linux Enthusiast. Saya memang gemar mengutak-atik sistem operasi ini. Bukan karena hobi tapi karena saya perlu untuk menggunakannya. Hehe.

- Rizqi Nur Assyaufi

Berlangganan via Email

Jangan sampai ketinggalan kabar dan info terbaru mengenai BanditHijo (R)-Chive.
Ayo bergabung!

0ff240f243b765977899a018a09bb6392e00b025