This guide assumes you’re using tinybind to build your form.
If you’re not using ourrv-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>