ReusableBehaviour

by Andrea Ercolino

HTML

<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<form id="edit_order_25" method="post" action="http://www.hashemian.com/tools/form-post-tester.php" accept-charset="UTF-8">
    <label for="order_25_breakfast">Breakfast: </label>
    <select id="order_25_breakfast" name="order[breakfast]">
        <option selected="selected" value="coffee">Coffee</option>
        <option value="orange_juice">Orange juice</option>
        <option value="tea">Tea</option>
    </select>
    <input name="order[addons]" type="hidden">
    <label for="order_25_addon1" data-show-when='{"#order_25_breakfast":["coffee","tea"]}'>
        <input id="order_25_addon1" name="order[addons]" type="checkbox" value="with_milk">With milk
    </label>
    <label for="order_25_addon2" data-show-when='{"#order_25_breakfast":"orange_juice"}'>
        <input id="order_25_addon2" name="order[addons]" type="checkbox" value="with_milk">With mint
    </label>
    <input type="submit" value="Send">
</form>

JavaScript

jQuery(function ($) {
  var count = 0;
  $('[data-show-when]')
    .each(function (i, elem_i) {
      var compiled = compile(elem_i);
      if (! compiled) {
        return;
      }
      compiled.target.on('change', function (event) {
        console.log((++count) + ': compile.values = '+JSON.stringify(compiled.values));
        show_hide(elem_i, compiled.target.val(), compiled.values);
      });
      show_hide(elem_i, compiled.target.val(), compiled.values);
    });

  function compile(elem) {
    var options = $(elem).data('showWhen');
    if (! $.isPlainObject(options)) {
      console.log('ERROR: Expected "data-show-when" attribute to be a JSON value.');
      return false;
    }
    var target = Object.keys(options)[0];
    if ('' === target) {
      console.log('ERROR: Expected a non empty target selector.');
      return false;
    }
    var target$ = $(target);
    if (0 === target.length) {
      console.log('ERROR: Expected a target element.');
      return false;
    }
    var result = {
      target: target$,
      values: $.isArray(options[target]) ? options[target] : [options[target]]
    };
    return result;
  }
  
  function show_hide(elem, current_value, show_values) {
    if (-1 < $.inArray(current_value, show_values)) {
      $(elem).show();
    }
    else {
      $(elem).hide();
    }
  }
  
});