Last active
January 15, 2016 12:40
-
-
Save jesperronn/5bd3de5704ecaa5aedd0 to your computer and use it in GitHub Desktop.
Generic checkbox toggle select all/none functionality
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Generic checkbox toggle select all/none functionality. | |
# | |
# | |
# Given the following checkbox: | |
# <input type="checkbox" class="js-toggle-all" | |
# data-target=".approved-count" | |
# data-count="#counter" | |
# data-total="#total"> | |
# | |
# This checkbox kan toggle and count based on the selection of other checkboxes. | |
# | |
# Configuration: | |
# | |
# `data-target`: Required. Selector of all checkboxes you want to observe. | |
# `data-count`: Optional counter element. counts how many are checked | |
# `data-total`: optional total. | |
# All must refer to a css selector and if defined must exist. | |
# | |
# | |
# Emits the event `js-toggle:updated` with parameters `event, { count,total }`, | |
# when the counter functionality has been updated. Use it, if you want to | |
# enable/disable submit button or similar. | |
# | |
# written by Jesper Rønn-Jensen (@jesperronn), github.com/jesperronn/ | |
# https://gist.github.com/jesperronn/5bd3de5704ecaa5aedd0 | |
# simple logger silencer if needed. | |
# Turn off for debug, see below | |
silent_logger = { | |
log: -> #nothing | |
warn: -> #nothing | |
} | |
# comment this line if you want log comments: | |
console = silent_logger | |
# to export globally (this=window in browser): | |
root = exports ? this | |
# on document ready: | |
$ -> | |
# wrap the call to forEach since $(..) returns a nodelist, not an array | |
Array.prototype.forEach.call($('.js-toggle-all'), init) | |
# initialize the functionality | |
# Based on HTML element | |
init = (toggler) -> | |
checkbox = $(toggler) | |
notify_if_missing(checkbox, 'data-target', 'fail') | |
notify_if_missing(checkbox, 'data-count', ) | |
notify_if_missing(checkbox, 'data-total', ) | |
all_checkboxes_selector = checkbox.data('target') | |
all_checkboxes = $(all_checkboxes_selector) | |
console.log('initializing!!, args:', arguments) | |
checkbox.on('click', toggle_all) | |
.on('js-toggle:toggler_clicked', update_checkbox_count) | |
.on('js-toggle:checkbox_clicked', update_checkbox_count) | |
.on('js-toggle:updated', callback_debug) | |
# all_checkboxes.on('click', update_checkbox_count) | |
# initialize click event on checkboxes. This requires the registered | |
# callback to know the toggler where it must trigger an event | |
all_checkboxes.on('click', (e) -> checkbox.trigger('js-toggle:checkbox_clicked') ) | |
# the timeout is required for other pages to register before updating. | |
# Alternatively, you can trigger 'js-toggle:checkbox_clicked' from the other page | |
# when registration is done | |
root.setTimeout( -> | |
checkbox.trigger('js-toggle:checkbox_clicked') | |
, 80) | |
toggle_all = (e) -> | |
checkbox = $(e.target) | |
checked = checkbox.prop('checked') | |
all_checkboxes_selector = checkbox.data('target') | |
all_checkboxes = $(all_checkboxes_selector) | |
all_checkboxes.prop('checked', checked) | |
checkbox.trigger('js-toggle:toggler_clicked') | |
# counter is bound to the toggler checkbox, | |
# which makes it possible to have multiple togglers on a page | |
update_checkbox_count = (e) -> | |
checkbox = $(e.target) | |
all_checkboxes_selector = checkbox.data('target') | |
all_checkboxes = $(all_checkboxes_selector) | |
# text_selector = '#approved-count' | |
# container = $(page_selector) | |
# select_all = $(checkbox_toggler) | |
#all_checkboxes = container.find(approve_checkbox_selector) | |
selected_checkboxes = all_checkboxes.filter(':checked') | |
count = selected_checkboxes.length | |
total = all_checkboxes.length | |
console.log("#{count} af #{total} valgte") | |
checkbox.prop('checked', count is total) | |
count_elem = $(checkbox.data('count')) | |
total_elem = $(checkbox.data('total')) | |
count_elem.text(count) if count_elem.length | |
total_elem.text(total) if total_elem.length | |
checkbox.trigger('js-toggle:updated', {count: count, total: total}) | |
# visual indication that the callback has been triggered. | |
# Good for debugging purposes, or to inspire how to use the callback | |
# | |
# - event name: 'js-toggle:updated' | |
# - payload: { count: x, total: y } | |
# | |
callback_debug = (e, payload) -> | |
console.log("Triggered 'js-toggle:updated' with ", arguments) | |
notify_if_missing = (elem, selector, strategy = 'notify') -> | |
sel_found = $(elem).attr(selector) | |
return if sel_found | |
message = "#{sel_found} #{selector} on #{elem}" | |
console.log('NOTE: ', message, elem) if strategy is 'notify' | |
throw ("FATAL: " + message ) if strategy is 'fail' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment