Rails 7 adds weekday_select and weekday_options_for_select


Rails already provide several form helpers for our ease of use.

The latest addition is weekday_helper that provides a nice select dropdown with weekdays.

We can also use weekday_options_for_select with form.select.

Before

<%# In Rails 6.1 %>
<%= form_with(model: employee) do |form| %>
  <div class="field">
    <%= form.label :weekly_off %>
    <%= form.select :weekly_off, I18n.t('date.day_names') %>

    # OR

    <%= form.select :weekly_off, I18n.t('date.day_names').map.with_index.to_h %>
  </div>
<% end %>

The above will result in

<select name="employee[weekly_off]" id="employee_weekly_off">
  <option value="Sunday">Sunday</option>
  <option value="Monday">Monday</option>
  <option value="Tuesday">Tuesday</option>
  <option value="Wednesday">Wednesday</option>
  <option value="Thursday">Thursday</option>
  <option value="Friday">Friday</option>
  <option value="Saturday">Saturday</option>
</select>

<!-- AND -->

<select name="employee[weekly_off]" id="employee_weekly_off">
  <option value="0">Sunday</option>
  <option value="1">Monday</option>
  <option value="2">Tuesday</option>
  <option value="3">Wednesday</option>
  <option value="4">Thursday</option>
  <option value="5">Friday</option>
  <option value="6">Saturday</option>
</select>

After

Rails 7 adds weekday_select and weekday_options_for_select helper to render the select dropdown with weekdays.

<%= form_with(model: employee) do |form| %>
  <div class="field">
    <%= form.label :weekly_off %>
    <%= form.weekday_select :weekly_off, {selected: "Mon", day_format: :abbr_day_names} %>

    # OR

    <%= form.select :weekly_off, weekday_options_for_select("Mon", day_format: :abbr_day_names) %>
  </div>
<% end %>
weekday_options_for_select:

Let’s look into the weekday_options_for_select syntax and the available options we can pass to it.

weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names)
Available Options:

selected

  • default: nil

NOTE: Provide the correct default based on the values

E.g.

  • If the index_as_value is set to true the selected value should be between 0 to 6.
  • If :day_format is set to :abbr_day_names default should be set accordingly ("Sun", "Mon").
<!-- weekday_options_for_select("Monday") -->

<option value="Sunday">Sunday</option>
<option selected="selected" value="Monday">Monday</option>
<option value="Tuesday">Tuesday</option>
<option value="Wednesday">Wednesday</option>
<option value="Thursday">Thursday</option>
<option value="Friday">Friday</option>
<option value="Saturday">Saturday</option>

:index_as_value

  • default: false
  • Returns options with index as value (0 to 6)
<!-- weekday_options_for_select("1", index_as_value: true) -->

<option value="0">Sunday</option>
<option selected="selected" value="1">Monday</option>
<option value="2">Tuesday</option>
<option value="3">Wednesday</option>
<option value="4">Thursday</option>
<option value="5">Friday</option>
<option value="6">Saturday</option>

:day_format

  • default: :day_names
  • Pass :abbr_day_names for abbreviated week days.
<!-- weekday_options_for_select(day_format: :abbr_day_names) -->

<select name="employee[weekly_off]" id="employee_weekly_off">
  <option value="Sun">Sun</option>
  <option value="Mon">Mon</option>
  <option value="Tue">Tue</option>
  <option value="Wed">Wed</option>
  <option value="Thu">Thu</option>
  <option value="Fri">Fri</option>
  <option value="Sat">Sat</option>
</select>

If needed, we can also add custom days in en.yml and language-specific locales.

en:
  date:
    short_day_names: [Su, Mo, Tu, We, Th, Fr, Sa]
<!-- weekday_options_for_select(day_format: :short_day_names) -->

<option value="Su">Su</option>
<option value="Mo">Mo</option>
<option value="Tu">Tu</option>
<option value="We">We</option>
<option value="Th">Th</option>
<option value="Fr">Fr</option>
<option value="Sa">Sa</option>