導入
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トークンの管理)と、不要なリクエストの発生を抑制するための工夫(デバウンスなど)を忘れないでください。