Skip to content

Improved data-remote for checkboxes? #440

Open
@ideasasylum

Description

@ideasasylum

Background

I have a form that I want to save automcatically via ajax as the options are changed. In particular, I want to have a checkbox that turns on/off a feature ("student booking", in this example).

Problem

I do something like this in my view:

= f.check_box :student_booking, data: { url: schedule_path, remote: true, method: :patch }
= f.select :minimum_notice, minimum_notice_options, {}, data: { url: schedule_path, remote: true, method: :patch }

The minimum notice attribute will be sent to the controller each time it's changed. Yay!

And when check the student_booking attribute, that updated value will be sent to the controller

But…

When they uncheck the student_booking attribute, UJS will send an empty request to the controller because unchecked checkbox values don't get sent in HTML forms (grrr... don't get me started on this decision!).

The empty request contains no parameters. So a common controller method like this

  def schedule_params
    params.require(:schedule).permit(:student_booking, :minimum_notice)
  end

will choke (400 Bad Request) because there's no required schedule parameter.

And worse, we can't assume that the absence of the student_booking parameter means that it's been turned off because when the minimum_notice attribute was updated, it didn't send the checkbox attribute either.

A Proposed Solution

It's a common pattern to force unchecked checkbox values to be sent using this:

= hidden_field_tag "schedule[student_booking]", false
= f.check_box :student_booking

If the checkbox is unchecked, the hidden field value will be sent instead.

Could, or more importantly, should UJS support this pattern? i.e., if the checkbox has been unchecked, check for a hidden input field of the same name, and submit that value to the controller.

As it is currently, I feel data-remote is not functional for checkboxes. In fact, it's deceptive because it works when checking the item, but not unchecking it.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions