# Hide/show elements dynamically according to their `data-visible-if` attribute. # # All elements with a `data-visible-if` attribute are checked on change, focusout and click events: # For each element, the content of its `data-visible-if` attribute is eval'd. If the eval'd code # returns true, the element is shown – otherwise it is hidden. (The attribute must contain valid # JavaScript code.) # # Use `$("body").conditionalVisibility()` to enable the functionality for the whole document, # or use a more specific selector to enable it only for some elements. # # The following options can be specified when initializing the plugin: # # - `events`: The events which should trigger re-evaluation of visibilities (default: # `"change focusout click"`) # # - `animate`: If elements should be shown/hidden using animations (default: `true`). # # There are two ways to manually force re-evaluation of visibilities: # # - `$(…).trigger("updateVisibilities")` updates visibilities (using animations) and then triggers # `shown.conditionalVisibility` / `hidden.conditionalVisibility` events accordingly. # # - `$(…).trigger("setVisibilities")` sets visibilities directly (no animations, does not trigger # custom events). This is already called automatically on pageready. You may want to call this # manually after new elements have been added to the DOM (eg a modal with content fetched via # ajax). # # Example: # # <form id="myform"> # <input id="checkbox" type="checkbox" > # <input id="text" data-visible-if="$('#checkbox')[0].checked"> # </form> # <script> # $("#myform").conditionalVisibility({events: "click change keypress"}) # </script> $.fn.conditionalVisibility = (options = {}) -> defaults = animate: true events: "change focusout click" options = $.extend({}, defaults, options) updateVisibilities = (event) -> $(this).find("[data-visible-if]").each -> $this = $(this) if eval($this.data("visible-if")) if $this.is(":hidden") if options.animate then $this.slideDown(100) else $this.show() $this.promise().done -> $this.trigger("shown.conditionalVisibility") else if $this.is(":visible") if options.animate then $this.slideUp(100) else $this.hide() $this.promise().done -> $this.trigger("hidden.conditionalVisibility") setVisibilities = (event) -> $(this).find("[data-visible-if]").each -> $this = $(this) $this.toggle !!eval($this.data("visible-if")) this .on "#{options.events} updateVisibilities", updateVisibilities .on "setVisibilities", setVisibilities .trigger "setVisibilities"