Link Search Menu Expand Document

This guide assumes you’re using tinybind to build your form.
If you’re not using our rv-cf-custom-form binder to handle your custom form’s submission, then this guide is most likely irrelevant to you.

Radio and checkbox inputs

If your custom form requires you to use radio buttons and/or checkboxes, there are some extra steps you need to take.

The problem

If you’d like to use inputs with a type attribute of either checkbox or radio, things get a bit tricky. Our rv-cf-custom-form binder that allows your form to be parsed and submitted to our servers is limited, it parses data from fields by simply finding elements with a name attribute, and reading the value propery from each of the corresponding elements.

For example, consider this set of fields:

<input type="radio" name="customer[shirt_size]" value="Small"> Small
<input type="radio" name="customer[shirt_size]" value="Medium" checked> Medium
<input type="radio" name="customer[shirt_size]" value="Large"> Large

The user had checked the "Medium" radio option, but our custom form binder has determined the value of the shirt_size column to be "Large" because it’s the last element with that name. Obviously that’s not what the user had selected, so let’s fix it.

The solution

Use JavaScript to listen for change events, and use them to mutate the value of a hidden input element. Here are some examples:

<fieldset>
  <legend>
    Shirt size
  </legend>

  <!--
    These fields do not get submitted because there is an element after them with the 
    same name. If the names do not match, the radio buttons won't be auto-filled
    if the customer comes back to update their account.
  -->
  <input type="radio" name="customer[shirt_size]" value="Small"> Small
  <input type="radio" name="customer[shirt_size]" value="Medium"> Medium
  <input type="radio" name="customer[shirt_size]" value="Large"> Large
</fieldset>

<!--
  This is the actual field that gets submitted.

  Make sure the hidden input is AFTER the radio buttons,
  otherwise the data will not submit properly.
-->
<input type="hidden" name="customer[shirt_size]">

<script>
  (function() {
    // Get our hidden input so we can change its value
    var $shirtSizeInput = document.querySelector('input[type="hidden"][name="customer[shirt_size]"]');

    // Get a list of our radio buttons
    var $inputs = Array.from(document.querySelectorAll('input[type="radio"][name="customer[shirt_size]"]'));

    $inputs.forEach(function($input) {
      // Listen for change events on each radio button
      $input.addEventListener('change', function() {
        // Change the value of our hidden input when a new option is selected
        if ($input.checked) {
          $shirtSizeInput.value = $input.value;
        } 
      });
    });
  })();
</script>

You can use similar approaches for checkbox inputs:

<!-- Single checkbox example: -->
<input type="checkbox" name="customer[terms]"> I agree to the terms of service
<input type="hidden" name="customer[terms]">

<script>
  (function() {
    var $termsInput = document.querySelector('input[type="hidden"][name="customer[terms]"]');
    var $termsCheckbox = document.querySelector('input[type="checkbox"][name="customer[terms]"]');

    $termsCheckbox.addEventListener('change', function() {
      $termsInput.value = $termsCheckbox.checked;
    });
  })();
</script>

<!-- Multiple checkboxes example: -->
<fieldset>
  <legend>Abilities</legend>

  <input type="checkbox" name="customer[abilities]" value="code"> Write code
  <input type="checkbox" name="customer[abilities]" value="forms"> Build cool forms
  <input type="checkbox" name="customer[abilities]" value="learn"> Learn more about customers
</fieldset>

<input type="hidden" name="customer[abilities]">

<script>
  (function() {
    var $abilitiesInput = document.querySelector('input[type="hidden"][name="customer[abilities]"]');
    var $checkboxes = Array.from(document.querySelectorAll('input[type="checkbox"][name="customer[abilities]"]'));

    $checkboxes.forEach(function($checkbox) {
      $checkbox.addEventListener('change', function() {
        var abilities = $abilitiesInput.value.split(',');

        if ($checkbox.checked) {
          abilities.push($checkbox.value);
        } else {
          abilities.splice(abilities.indexOf($checkbox.value), 1);
        }

        $abilitiesInput.value = abilities.join(',');
      });
    });
  })();
</script>

Have any questions or comments about this post? Let us know! Your feedback is greatly appreciated.

Customer Fields is a Shopify app made by Helium.

Copyright © 2020 Helium Development, LLC