Window-size-dependent content toggler for an HTML form I had to build a responsive component which allows the user to display specific content in a page. I called it the contentToggler.

Here is my component in action

HTML Structure of togglers &amp; contents : 
On small screens : &lt;select&gt; with &lt;option&gt;
On big screens : &lt;div&gt; containing &lt;buttons&gt;

&lt;select id="paymentMethodSelector"&gt;
    &lt;option class="js-card-selector-option" value="Carte bancaire"&gt;Carte bancaire&lt;/option&gt;
    &lt;option class="js-money-transfer-selector-option" value="Virement"&gt;Virement&lt;/option&gt;
    &lt;option class="js-check-selector-option" value="Chèque"&gt;Chèque&lt;/option&gt;
&lt;/select&gt;

&lt;div&gt;
    &lt;div&gt;
        &lt;input type="radio" class="js-card-selector-radio" id="radio-checkout-selector-1" checked&gt;
        &lt;label for="radio-checkout-selector-1"&gt;Carte bancaire&lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;input type="radio" class="js-money-transfer-selector-radio" id="radio-checkout-selector-2"&gt;
        &lt;label for="radio-checkout-selector-2" class="radio-label"&gt;Virement&lt;/label&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;input type="radio" class="js-check-selector-radio" id="radio-checkout-selector-3"&gt;
        &lt;label for="radio-checkout-selector-3" class="radio-label"&gt;Chèque&lt;/label&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div id="paymentCardContent"&gt;content1&lt;/div&gt;
&lt;div id="paymentMoneyTransferContent"&gt;content2&lt;/div&gt;
&lt;div id="paymentCheckContent"&gt;content3&lt;/div&gt;


Associated JS which works however it makes my eyes bleed by its horrifying redundance.   

var paymentMethod = {
  selectorOptionWrapper: $('#paymentMethodSelector'),
  card: {
    selectorOption: $('.js-card-selector-option'),
    selectorRadio: $('.js-card-selector-radio'),
    content: $('#paymentCardContent')
  },
  moneyTransfer: {
    selectorOption: $('.js-money-transfer-selector-option'),
    selectorRadio: $('.js-money-transfer-selector-radio'),
    content: $('#paymentMoneyTransferContent')
  },
  check: {
    selectorOption: $('.js-check-selector-option'),
    selectorRadio: $('.js-check-selector-radio'),
    content: $('#paymentCheckContent')
  }
}

function updateCheckoutContent() {
  paymentMethod.selectorOptionWrapper.on('change', function() {
    if(paymentMethod.card.selectorOption.is(':selected')) {
      paymentMethod.card.content.siblings().addClass('u-hide')
      paymentMethod.card.content.removeClass('u-hide');
    }
  });
  paymentMethod.card.selectorRadio.on('change', function() {
    if($(this).is(':checked')) {
      paymentMethod.card.content.siblings().addClass('u-hide')
      paymentMethod.card.content.removeClass('u-hide');
    }
  });

  paymentMethod.selectorOptionWrapper.on('change', function() {
    if(paymentMethod.moneyTransfer.selectorOption.is(':selected')) {
      paymentMethod.moneyTransfer.content.siblings().addClass('u-hide')
      paymentMethod.moneyTransfer.content.removeClass('u-hide');
    }
  });
  paymentMethod.moneyTransfer.selectorRadio.on('change', function() {
    if($(this).is(':checked')) {
      paymentMethod.moneyTransfer.content.siblings().addClass('u-hide')
      paymentMethod.moneyTransfer.content.removeClass('u-hide');
    }
  });

  paymentMethod.selectorOptionWrapper.on('change', function() {
    if(paymentMethod.check.selectorOption.is(':selected')) {
      paymentMethod.check.content.siblings().addClass('u-hide')
      paymentMethod.check.content.removeClass('u-hide');
    }
  });
  paymentMethod.check.selectorRadio.on('change', function() {
    if($(this).is(':checked')) {
      paymentMethod.check.content.siblings().addClass('u-hide')
      paymentMethod.check.content.removeClass('u-hide');
    }
  });
}

updateCheckoutContent(paymentMethod);
What you could do is define in the markup the following:


A data attribute for option to indicate it's a toggle.
A data attribute for radios to indicate it's a toggle.
A data attribute for option to indicate the content it corresponds.
A data attrubute for radios to indicate the content it corresponds.


The data attributes could be selectors or any attribute you can use to target the content.

This way, your script can pick up these elements by class, get their data attribute, and toggle their corresponding contents. This is essentially how Bootstrap allows you to define modals, accordions and such without ever writing scripts. They just look for certain selectors, pick up data, and find the target selectors.

Here's a sample of how the markup would look like:

&lt;select data-component="select-toggle"&gt;
  &lt;option value="foo" data-content="#foo"&gt;foo&lt;/option&gt;
  &lt;option value="bar" data-content="#bar"&gt;bar&lt;/option&gt;
  &lt;option value="baz" data-content="#baz"&gt;baz&lt;/option&gt;
&lt;/select&gt;

&lt;input type="radio" value="foo" data-component="radio-toggle" data-content="#foo" &gt;
&lt;input type="radio" value="bar" data-component="radio-toggle" data-content="#bar" &gt;
&lt;input type="radio" value="baz" data-component="radio-toggle" data-content="#baz" &gt;

&lt;div id="foo"&gt;foo&lt;/div&gt;
&lt;div id="bar"&gt;bar&lt;/div&gt;
&lt;div id="baz"&gt;baz&lt;/div&gt;


And the script will look like the following. My jQuery is fuzzy at best, but you get the idea:

$('[data-component="select-toggle"]').on('change', function(){
  var contentSelector = $('option:selected', this).data('content');
  $(contentSelector).show().siblings().hide();
});

$('[data-component="radio-toggle"]').on('change', function(){
  var contentSelector = $(this).data('content');
  $(contentSelector).show().siblings().hide();
});