Read more

Unobtrusive jQuery to toggle visibility with selects and checkboxes

Tobias Kraze
September 02, 2010Software engineer at makandra GmbH

Use this if you want to show or hide part of a form if certain options are selected or boxes are checked.

Illustration online protection

Rails professionals since 2007

Our laser focus on a single technology has made us a leader in this space. Need help?

  • We build a solid first version of your product
  • We train your development team
  • We rescue your project in trouble
Read more Show archive.org snapshot

The triggering input gets an data-selects-visibility attribute with a selector for the elements to show or hide, like

<%= form.select :advancedness, [['basic', 'basic'], ['advanced', 'advanced'], ['very advanced', 'very_advanced]], {}, :"data-selects-visibility" => ".sub_form" %>

The elements that are shown/hidden look like

<div class="sub_form" data-show-for="basic"> 
  only shown for advancedness = basic 
</div>

<div class="sub_form" data-hide-for="basic"> 
  hidden for advancedness = basic
</div>

<div class="sub_form" data-show-for="advanced very_advanced">
  shown for advancedness = advanced or very_advanced
</div>

For checkboxes you can use the pseudo-value _checked or _unchecked, so

<%= form.check_box :check_box, :"data-selects-visibility" => ".triggered_by_checkbox" %>

<div class="triggered_by_checkbox" data-show-for="_checked">
  only shown when checkbox is checked
</div>

For blank values you can use _blank.

Here is the code:

$(function() {
  function selectVisibility() {
    var selector = $($(this).attr('data-selects-visibility'));
    if ($(this).is('input[type="checkbox"]')) {
      if ($(this).is(':checked')) {
        value = '_checked';
      } else {
        value = '_unchecked';
      }
    } else if ($(this).is('input[type=radio]')) {
      var checkedRadioButton = $(this).closest('form').find('input[type="radio"][name="' + $(this).attr('name') + '"]:checked');
      if (checkedRadioButton.length > 0) {
        value = checkedRadioButton.val();
      }
    } else {
      var value = $(this).val();
    }
    if (!value) {
      value = '_blank';
    }
    selector.filter('[data-show-for]:not([data-show-for~="' + value + '"])').hide();
    selector.filter('[data-hide-for~="' + value + '"]').hide();
    selector.filter('[data-hide-for]:not([data-hide-for~="' + value + '"])').show();
    selector.filter('[data-show-for~="' + value + '"]').show();
  }

  $(this).find('[data-selects-visibility]').change(selectVisibility);
  $(this).find('select[data-selects-visibility]').each(selectVisibility);
  $(this).find('input[data-selects-visibility][type="checkbox"]').each(selectVisibility);
  $(this).find('input[data-selects-visibility][type="radio"]:checked').each(selectVisibility);
});

Tobias Kraze
September 02, 2010Software engineer at makandra GmbH
Posted by Tobias Kraze to makandra dev (2010-09-02 14:07)