はじめに
年、月、日を別々のセレクトボックスで入力するようなフォームを作成します。
難しいところは年と月の値によって日数が変わることでした。
様々な方法を考えたのですが、JavaScriptを使って対応することにしました。
環境
rails 6.1.7.6
ruby 3.0.6
実装
html.erbの下にscriptタグを設けてそこにJSのコードを書いていきます。
<%= form_for(hoge, url: hoge_path) do |f| %>
<div class="field">
<%=
f.select :birthdate_year,
(1900..Date.today.year).reverse_each.to_a,
{ prompt: '' },
{ id: 'birthdate_year' }
%>
</div>
<div class="field">
<%=
f.select :birthdate_month,
(1..12).to_a,
{ prompt: '' },
{ id: 'birthdate_month' }
%>
</div>
<div class="field">
<%=
f.select :birthdate_day,
(1..31).to_a,
{ prompt: '' },
{ id: 'birthdate_day' }
%>
</div>
<% end %>
<script>
document.addEventListener('DOMContentLoaded', () => {
const yearSelect = document.getElementById('birthdate_year')
const monthSelect = document.getElementById('birthdate_month')
const daySelect = document.getElementById('birthdate_day')
function updateDayOptions() {
const year = yearSelect.value
const month = monthSelect.value
const daysInMonth = new Date(year, month, 0).getDate()
while (daySelect.firstChild) {
daySelect.removeChild(daySelect.firstChild);
}
for (var i = 1; i <= daysInMonth; i++) {
var option = document.createElement('option');
option.value = i;
option.text = i;
daySelect.appendChild(option);
}
}
updateDayOptions()
yearSelect.addEventListener('change', updateDayOptions);
monthSelect.addEventListener('change', updateDayOptions);
})
</script>
以上で動的に日数の変わるフォームを作ることができました。
railsにはdate_pickerというヘルパーもあったのですがカスタマイズが難しく今回の方法を見つけました。
カスタマイズが求められるアプリケーションでは参考にしていただけると嬉しいです。