LoginSignup
0
0

RailsとAjaxを用いて日付入力フィールドの変更をリアルタイムで反映する方法

Posted at

導入

Webアプリケーションにおいて、フォーム入力のリアルタイム処理はユーザー体験を向上させる重要な要素です。特に予約システムのようなアプリケーションでは、利用者が入力する日付に応じて利用可能な時間帯やサービスの情報を動的に更新することが求められます。この記事では、Railsを使用して日付入力フィールドからの入力をAjaxを通じてリアルタイムに処理し、ページの特定の部分を更新する方法を紹介します。

実装手順

1. 日付フィールドの準備

まず、日付を入力するためのフィールドを用意します。このフィールドには、JavaScriptでイベントリスナーを設定するためのIDが必要です。

<%= form_with model: @reservation, local: true do |form| %>
  <%= form.label :date, "日付" %>
  <%= form.date_field :date, id: 'date_field', value: Date.today, class: 'form-control' %>
<% end %>

2. JavaScriptでのイベントハンドラの設定

日付フィールドの値が変更されたときに、Ajaxリクエストを発行するイベントハンドラを設定します。

application.js
document.addEventListener('turbo:load', function() {
  const dateField = document.querySelector('#date_field'); // 日付フィールドのIDを指定
  if (dateField) {
    const debouncedFetch = debounce(function(date) {
      fetch(`/reservations/update_slots?date=${date}`, {
        headers: {
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
          'X-CSRF-Token': document.querySelector("[name='csrf-token']").content
        },
        credentials: 'include'
      })
      .then(response => response.json())
      .then(data => updateTable(data));
    }, 500); // 500ミリ秒のデバウンスタイム

    // inputイベントにデバウンス関数を適用
    dateField.addEventListener('input', function() {
      debouncedFetch(this.value);
    });
  }
});

// デバウンス関数
function debounce(func, wait) {
  let timeout;
  return function() {
    const context = this, args = arguments;
    const later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

function updateTable(data) {
  // ここでテーブルの内容を更新
  const tableBody = document.querySelector('.table-responsive tbody');
  tableBody.innerHTML = ''; // 現在の内容をクリア
  data.services.forEach(service => {
    let row = `<tr>
      <th class="service-name sticky-left">${service.name}</th>
      <th class="service-duration sticky-duration">${service.duration}</th>`;
    service.time_slots.forEach(slot => {
      row += `<td>${slot.availability}</td>`;
    });
    row += '</tr>';
    tableBody.innerHTML += row;
  });
}

3. Railsコントローラーの設定

Ajaxリクエストを受け取り、必要なデータを処理してJSON形式で返すアクションをコントローラーに追加します。

reservations_controller.rb
def update_slots
  @date = Date.parse(params[:date])
  @time_slots = generate_time_slots(@date)
  @services = Service.where(available_on: @date)
  
  render json: @services.map { |service|
    {
      name: service.name,
      slots: format_slots(service, @time_slots)
    }
  }
end

4. ルーティングの設定

router.rb
  resources :reservations do
    collection do
      get :update_slots
    end
  end

まとめ

この方法を使用することで、ユーザーが日付を入力するたびにその日に利用可能なサービスの情報を動的に更新でき、ユーザーにとって直感的で反応性の高いインターフェースを提供することが可能になります。AjaxとRailsの組み合わせは、このような動的なページ更新に非常に効果的です。

注意点

実装時にはセキュリティ対策(特にCSRFトークンの管理)と、不要なリクエストの発生を抑制するための工夫(デバウンスなど)を忘れないでください。

0
0
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
0
0