Skip to content

Instantly share code, notes, and snippets.

@jacobsimeon
Created September 26, 2013 22:09
Show Gist options
  • Save jacobsimeon/6721283 to your computer and use it in GitHub Desktop.
Save jacobsimeon/6721283 to your computer and use it in GitHub Desktop.
# FancyCheckbox: A customizable checkbox tool.
#
# Hides a given checkbox and replaces it with a div, binding the appropriate
# event handlers to manipulate the real, underlying checkbox.
# Also copies any existing label into the replacement markup.
#
# DOM tree looks like this:
# <input name="john-doe" type="checkbox" style="display: none;">
# <div class="fancy-checkbox-container">
# <div class="fancy-checkbox-label-wrapper">
# <!-- Existing label is moved here -->
# <label for="john-doe" class="fancy-checkbox-label">John Doe</label>
# </div>
# <div class="fancy-checkbox-checkmark-wrapper">
# <span class="fancy-checkbox-checkmark icon-checkbox-active"></span>
# </div>
# </div>
class FancyCheckbox
constructor: (@el, options={}) ->
@buildOptions(options)
@hideCheckboxAndLabel()
@insertReplacementMarkup()
@bindEvents()
buildOptions: (options) ->
defaults =
checkedClass: "icon-checkbox-checked",
uncheckedClass: "icon-checkbox-unchecked"
changed: ->
@options = $.extend(defaults, options)
hideCheckboxAndLabel: ->
@el.hide()
insertReplacementMarkup: ->
@container = @nodeWithClass("div", "container")
@buildDisplayLabel()
@buildCheckbox()
@appendToDom()
bindEvents: ->
@container.click @toggle
buildDisplayLabel: ->
@label = $("label[for='#{@el.attr('name')}']")
@label.addClass "fancy-checkbox-label"
@displayLabelWrapper = @nodeWithClass("div", "label-wrapper")
@displayLabelWrapper.append(@label)
buildCheckbox: ->
@checkBox = @nodeWithClass("span", "checkmark")
@initializeCheckboxState()
@checkBoxWrapper = @nodeWithClass("div", "checkmark-wrapper")
@checkBoxWrapper.append(@checkBox)
appendToDom: ->
@container.append @displayLabelWrapper, @checkBoxWrapper
@el.after @container
initializeCheckboxState: ->
if @el.prop("checked")
@checkBox.addClass @options.checkedClass
else
@checkBox.addClass @options.uncheckedClass
toggle: =>
@el.prop("checked", !@el.prop("checked"))
@options.changed(@)
@checkBox.toggleClass(@options.checkedClass)
@checkBox.toggleClass(@options.uncheckedClass)
nodeWithClass: (nodeName, className) ->
$("<#{nodeName}>").addClass("fancy-checkbox-#{className}")
$ ->
$.fn.fancyCheckbox = (options) ->
@.map -> new FancyCheckbox($(@), options)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment