1

I have a Rails form that allows the user to choose from a collection of objects with checkboxes, and also to choose an optional one of those as the "Primary" choice. However, there is not always a primary choice, and as it stands now if the user accidentally clicks on a radio button, there doesn't seem to be a way for the casual user to de-select it.

<%= form_tag song_part_singer_parts_path(@song, @part) do %>
    <input type="hidden" name="song_id" value="<%= @song.id %>" />
    <table>
        <tr>
            <th>Singer</th>
            <th>Primary?</th>
        </tr>
    <% Singer.active.each do |s| %>
        <tr>
            <td>
                <%= check_box_tag "singer_ids[]", s.id  %>
                <%= s.name %>
            </td>
            <td>
                <%= radio_button_tag "primary", s.id %>
            </td>
        </tr>
    <% end %>
    </table>
    <%= submit_tag "Update" %>
<% end %>

Edit: Further research suggests that this is not possible, by design of the radio button. I would also accept other solutions to this problem. I need the user to have the ability to choose zero or one options, but not more, and to correct a mistake if they made it.

thumbtackthief
  • 6,093
  • 10
  • 41
  • 87
  • 1
    How about creating a 'reset' button that clears the radios? Something, perhaps, like [this Q&A](https://stackoverflow.com/questions/2554116/how-to-clear-radio-button-in-javascript). – jvillian Aug 01 '19 at 22:53
  • If you don't want to use a clear-option as @jvillian suggested, maybe you could use a checkbox instead of a radio button and use javascript to allow only one checkbox selected – Fagundes Aug 02 '19 at 16:24

1 Answers1

1

There are different ways to solve this problem:

1) You could add an additional, blank value radio button somewhere <%= radio_button_tag "primary", nil %> No Primary.

2) You could use a select, with a blank default/prompt instead:

    ...
</table>
<%= select_tag "primary", options_from_collection_for_select(Singer.active.all, "id", "name"), prompt: 'No Primary' %>

3) You can use javascript to toggle off the selection:

<td>
    <%= radio_button_tag "primary", s.id %>
    <span class="toggle-label">Clear primary</span>
</td>

<style>
/* hide label when unchecked */
input[type=radio] + span {
  display: none;
}
input[type=radio]:checked + span {
  display: inline;
  cursor: pointer;
}
</style>

<script>
document.addEventListener('click', function(event) {
    if (event.target.matches('.toggle-label')) {
        var td = event.target.parentElement;
        var input = td.querySelector('input')
        input.checked = false
    }
});
</script>
Jonathan Bennett
  • 1,055
  • 7
  • 14