Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generic checkbox toggle select all/none functionality
# 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
You can’t perform that action at this time.