I have two different set of checkboxes. With the coffescript code below I set the maximum amount of checkable items at 3. I would like to refactor this code, to be cleaner and compact, but I can't get it.

$("div.feature_list :checkbox").click ->
  if $("div.feature_list :checked").length >= 3
    $("div.feature_list :checkbox:not(:checked)").attr "disabled", "disabled"
    $("div.feature_list :checkbox:not(:checked)").button disabled: true
    $("div.feature_list :checkbox:not(:checked)").button disabled: false

$("div.style_list :checkbox").click ->
   if $("div.style_list :checked").length >= 3
     $("div.style_list :checkbox:not(:checked)").attr "disabled", "disabled"
     $("div.style_list :checkbox:not(:checked)").button disabled: true
     $("div.style_list :checkbox:not(:checked)").button disabled: false 
  • 1
    \$\begingroup\$ FYI, to enable/disable a button use .prop('disabled', true_or_false) instead of setting the attribute. \$\endgroup\$ Oct 6 '12 at 19:17

Step 1: DRY. Encapsulate the "limit checkboxes" behavior in a function

limitCheckboxesIn = (container, limit = 3) ->
  checkboxes = $(container).find ":checkbox"
  checkboxes.on "click", (event) ->
    checked   = checkboxes.filter ":checked"
    unchecked = checkboxes.not checked
    state     = disabled: checked.length >= limit
    unchecked.prop(state).button state

Step 2: ... well, that pretty much it. Call it like so:

$ ->
  limitCheckboxesIn "div.feature_list"
  limitCheckboxesIn "div.style_list"

Here's a demo

By the way, if you just want the most compact solution, you can skip some assignments:

limitCheckboxesIn = (container, limit = 3) ->
  checkboxes = $(container).find ":checkbox"
  checkboxes.on "click", (event) ->
    disabled = checkboxes.filter(":checked").length >= limit
    checkboxes.not(":checked").prop({disabled}).button {disabled}

Personally, I find this a little less readable, but it's a matter of taste; the code's functionally identical.

  • \$\begingroup\$ It works with plain checkboxes but it doesnt work with jquery ui buttonset. I think the last line should be different \$\endgroup\$
    – framomo86
    Oct 7 '12 at 0:29
  • \$\begingroup\$ @framomo86 Whoops, you're right - I've corrected my answer, and the demo. \$\endgroup\$
    – Flambino
    Oct 7 '12 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.