February 9, 2013: Updated to only apply validation on currently submitted page for multi-page forms.
Stop! There's a better way.
This snippet is available as a plugin with Gravity Perks, a suite of over 40 premium Gravity Forms plugins!
The snippet might look daunting but it only requires a quick copy and paste and two simple configurations to get it up and running!
<?php | |
/** | |
* Limit How Many Checkboxes Can Be Checked | |
* http://gravitywiz.com/2012/06/11/limiting-how-many-checkboxes-can-be-checked/ | |
*/ | |
class GFLimitCheckboxes { | |
private $form_id; | |
private $field_limits; | |
private $output_script; | |
function __construct($form_id, $field_limits) { | |
$this->form_id = $form_id; | |
$this->field_limits = $this->set_field_limits($field_limits); | |
add_filter("gform_pre_render_$form_id", array(&$this, 'pre_render')); | |
add_filter("gform_validation_$form_id", array(&$this, 'validate')); | |
} | |
function pre_render($form) { | |
$script = ''; | |
$output_script = false; | |
foreach($form['fields'] as $field) { | |
$field_id = $field['id']; | |
$field_limits = $this->get_field_limits($field['id']); | |
if( !$field_limits // if field limits not provided for this field | |
|| RGFormsModel::get_input_type($field) != 'checkbox' // or if this field is not a checkbox | |
|| !isset($field_limits['max']) // or if 'max' is not set for this field | |
) | |
continue; | |
$output_script = true; | |
$max = $field_limits['max']; | |
$selectors = array(); | |
foreach($field_limits['field'] as $checkbox_field) { | |
$selectors[] = "#field_{$form['id']}_{$checkbox_field} .gfield_checkbox input:checkbox"; | |
} | |
$script .= "jQuery(\"" . implode(', ', $selectors) . "\").checkboxLimit({$max});"; | |
} | |
GFFormDisplay::add_init_script($form['id'], 'limit_checkboxes', GFFormDisplay::ON_PAGE_RENDER, $script); | |
if($output_script): | |
?> | |
<script type="text/javascript"> | |
jQuery(document).ready(function($) { | |
$.fn.checkboxLimit = function(n) { | |
var checkboxes = this; | |
this.toggleDisable = function() { | |
// if we have reached or exceeded the limit, disable all other checkboxes | |
if(this.filter(':checked').length >= n) { | |
var unchecked = this.not(':checked'); | |
unchecked.prop('disabled', true); | |
} | |
// if we are below the limit, make sure all checkboxes are available | |
else { | |
this.prop('disabled', false); | |
} | |
} | |
// when form is rendered, toggle disable | |
checkboxes.bind('gform_post_render', checkboxes.toggleDisable()); | |
// when checkbox is clicked, toggle disable | |
checkboxes.click(function(event) { | |
checkboxes.toggleDisable(); | |
// if we are equal to or below the limit, the field should be checked | |
return checkboxes.filter(':checked').length <= n; | |
}); | |
} | |
}); | |
</script> | |
<?php | |
endif; | |
return $form; | |
} | |
function validate($validation_result) { | |
$form = $validation_result['form']; | |
$checkbox_counts = array(); | |
// loop through and get counts on all checkbox fields (just to keep things simple) | |
foreach($form['fields'] as $field) { | |
if( RGFormsModel::get_input_type($field) != 'checkbox' ) | |
continue; | |
$field_id = $field['id']; | |
$count = 0; | |
foreach($_POST as $key => $value) { | |
if(strpos($key, "input_{$field['id']}_") !== false) | |
$count++; | |
} | |
$checkbox_counts[$field_id] = $count; | |
} | |
// loop through again and actually validate | |
foreach($form['fields'] as &$field) { | |
if(!$this->should_field_be_validated($form, $field)) | |
continue; | |
$field_id = $field['id']; | |
$field_limits = $this->get_field_limits($field_id); | |
$min = isset($field_limits['min']) ? $field_limits['min'] : false; | |
$max = isset($field_limits['max']) ? $field_limits['max'] : false; | |
$count = 0; | |
foreach($field_limits['field'] as $checkbox_field) { | |
$count += rgar($checkbox_counts, $checkbox_field); | |
} | |
if($count < $min) { | |
$field['failed_validation'] = true; | |
$field['validation_message'] = sprintf( _n('You must select at least %s item.', 'You must select at least %s items.', $min), $min ); | |
$validation_result['is_valid'] = false; | |
} | |
else if($count > $max) { | |
$field['failed_validation'] = true; | |
$field['validation_message'] = sprintf( _n('You may only select %s item.', 'You may only select %s items.', $max), $max ); | |
$validation_result['is_valid'] = false; | |
} | |
} | |
$validation_result['form'] = $form; | |
return $validation_result; | |
} | |
function should_field_be_validated($form, $field) { | |
if( $field['pageNumber'] != GFFormDisplay::get_source_page( $form['id'] ) ) | |
return false; | |
// if no limits provided for this field | |
if( !$this->get_field_limits($field['id']) ) | |
return false; | |
// or if this field is not a checkbox | |
if( RGFormsModel::get_input_type($field) != 'checkbox' ) | |
return false; | |
// or if this field is hidden | |
if( RGFormsModel::is_field_hidden($form, $field, array()) ) | |
return false; | |
return true; | |
} | |
function get_field_limits($field_id) { | |
foreach($this->field_limits as $key => $options) { | |
if(in_array($field_id, $options['field'])) | |
return $options; | |
} | |
return false; | |
} | |
function set_field_limits($field_limits) { | |
foreach($field_limits as $key => &$options) { | |
if(isset($options['field'])) { | |
$ids = is_array($options['field']) ? $options['field'] : array($options['field']); | |
} else { | |
$ids = array($key); | |
} | |
$options['field'] = $ids; | |
} | |
return $field_limits; | |
} | |
} | |
new GFLimitCheckboxes(115, array( | |
5 => array( | |
'min' => 2, | |
'max' => 3 | |
), | |
13 => array( | |
'max' => 3 | |
) | |
)); |
How do I install this snippet?
Just copy and paste the code into your theme’s functions.php file.
Do I need to modify this snippet to work with my form?
This snippet now uses a class format. This means you can more easily use it on multiple forms! To instantiate this class you will need to know the form ID, field ID and minimum/maximum number of checkboxes which should be allowed/enforced for that field. It will look something like this:
new GFLimitCheckboxes(115, array( | |
5 => array( | |
'min' => 2, | |
'max' => 3 | |
) | |
)); |
In template form:
new GFLimitCheckboxes(FORM_ID, array( | |
FIELD_ID => array( | |
'min' => MIN_NUMBER, | |
'max' => MAX_NUMBER | |
) | |
)); |
You can specify multiple checkbox fields on a specific form like so:
new GFLimitCheckboxes(115, array( | |
5 => array( | |
'min' => 2, | |
'max' => 3 | |
), | |
13 => array( | |
'max' => 3 | |
) | |
)); |
Finally, you can apply this functionality to multiple forms:
new GFLimitCheckboxes(115, array( | |
5 => array( | |
'min' => 2, | |
'max' => 3 | |
), | |
13 => array( | |
'max' => 3 | |
) | |
)); | |
new GFLimitCheckboxes(38, array( | |
2 => array( | |
'min' => 5, | |
'max' => 5 | |
) | |
)); |
And that’s it!
input[type="checkbox"]:disabled + label { color: #999; }
Did this resource help you do something awesome with Gravity Forms? Then you'll absolutely love Gravity Perks; a suite of 39+ essential add-ons for Gravity Forms with support you can count on.
Great little piece of code but it seems to be stopping users not logged in from being able to add items to the cart (well it says they have been added but going to the cart page its empty)? The code all works as expected with the checkboxes and it works fine if you are logged in.
I removed the code and it allows me to add to cart if not logged in.
Hi Paul, I’m unable to recreate the issue. I suggest purchasing a Gravity Perks license for the GP Limit Checkboxes Perk which comes with fantastic support.
Hi,
I put the code on my functions.php and appear a fatal error. I will show you what i paste:
Estoy copiando lo siguiente: new GFLimitCheckboxes(4, array( 21 => array( ‘min’ => 1, ‘max’ => 5 ), 23 => array( ‘min’ => 1, ‘max’ => 5 ) ));
The number 4 is my ID form and the 21 and 23 is the ID field. I don´t understand if apart of the gravity´s plugin i need to do something else.
I suspect you may have not copied the full snippet and only the configuration. More troubleshooting steps here: https://gravitywiz.com/documentation/snippet-troubleshooting/
Thanks, worked perfectly
Glad to help, Filip!
Does the plugin support the Poll add-on and the limits can be set for the Poll field type?
Yep! It sure does. ?
Hi there! nice code :)
I see all the page but not the form.
Here is the error in chrome console: https://ibb.co/HDd1cHc
Hi Danilo, the demo is still working so there is likely a theme/plugin conflict at play.
i face the same issue. it used to be working.
Awesome snippet, thanks David!
For anyone experiencing issues: I had to make this a plugin in order for it to work. I couldn’t get it working just pasting everything in the functions.php, the code wouldn’t output the script to the page containing the form at all. I would recommend the same approach for anyone experiencing the same issue.
There may have been a formatting issue in your functions.php file but glad the plugin solution works for you. ?
Both my max fields are 3 but my form is letting 4 be picked, any idea on this?
Hi Karl, I’m not able to recreate the issue. I’d recommend picking up a copy of Gravity Perks for the GP Limit Checkboxes perk which comes with excellent support.
I’m getting a blank page using the raw code with my form/field IDs. I see this error in the log files:
PHP Parse error: syntax error, unexpected ’15’ (T_LNUMBER), expecting ‘)’ in /var/www/vhosts/curlysicecream.com/httpdocs/wp-content/themes/oceanwp-child/functions.php on line 229
Any thoughts?
This is great, but any way where I can set the limits dynamically based on the input of another field?
For example.. Since we don’t have proper checkbox products in gravity forms.. (yes I saw https://gravitywiz.com/checkbox-products-gravity-forms/, but I don’t think it’s viable when you have a few hundred options).. A person is buying and selecting seats to a concert..
How many tickets do you want to buy? (Product Dropdown: 1..10).
Results of the dropdown will limit the number of checkboxes/seats that they can select.
Let me know if it’s possible either with this snippet or with your plugin at https://gravitywiz.com/documentation/gravity-forms-limit-checkboxes/
We have a snippet that works in conjunction with our GF Limit Checkboxes perk. https://gist.github.com/spivurno/42ca347547088029b986e2b5287ccaea Happy to answer any questions.
Thanks for sharing.. this is good.. I will play with it, I see the configuration section will need to be populated with the ID’s and values..
But it seems to be related to specific values of a dropdown. What if you want a user to enter in any number (i.e. a quantity)?
Would this work for (a) spanning mutiple fields (using the Limit Checkboxes Perk) and (b) 2 different limits based for 2 different fields?
My initial testing on a site using the limit checkboxes perk, using a “Product” in the form of a dropdown doesn’t appear to be impacting.. Does the “Limit how many checkboxes can be checked” need to be enabled? If so, do we put a min/max limit, or leave blank? In the product, I tried “Show Values” using both numbers or strings like Q1, Q2, Q3, etc.. neither seemed to have an impact.. Any further documentation?
Hi Jacob, reach out to us via the support form and we’ll be happy to take a closer look at your setup. Please include an export of your form, your configuration of the conditional limits snippet and the field labels & IDs you are working with.
Thank you for supplying this. I have installed it as a plugin instead of all that code in the functions.php file.
Just created a plugin folder, dumped the code provided into an index.php file with the following header:
/* Plugin Name: Limit How Many Checkboxes Can Be Checked Plugin URI: https://gravitywiz.com/2012/06/11/limiting-how-many-checkboxes-can-be-checked/ Description: Limit How Many Checkboxes Can Be Checked Version: 0.1 */
Awesome! Thanks for sharing. :)
Awesome Bro,
Thank you so much
My pleasure, Simarjot. :)
Hi, I just stumbled onto your code and it works awesome except I have one dilemma. I have multiple field IDs being used in the same form. I added the snippet for each field ID however I need to restrict the form to max out at 15 selected checkboxes for the entire form with the combined field IDs. Is there a way to make it add together what’s taken from a separate field to combine in total for the form?
Hi Tim, spanning the limit across multiple checkbox fields is supported in GP Limit Checkboxes.
The last update for this reads, “Updated to only apply validation on currently submitted page for multi-page forms.”
What would I need to do if I wanted this to validate from any page?
Hey Greg, I’m not sure you’d ever want this. If it validates from every page, you would get validation errors on form pages that are inaccessible.
I would also recommend using the perk-version of this snippet which has been dramatically optimized.
Really a great snippet and very useful. works perfectly. Thank you
Glad to help. :)
THANK YOU for this great snippet & the introduction to Gravity Perks! For the users above who are experiencing the ‘white screen’ after copying & pasting the snippet into their functions.php, it COULD be that they are just copying one of the snippets shown on this page, such as:
new GFLimitCheckboxes(115, array( 5 => array( ‘min’ => 2, ‘max’ => 3 ) ));
RATHER than using the FULL CODE from the “DOWNLOAD CODE” button at the top of the page. The instructions within “How do I install this snippet?” do make it sound as if they only need to copy the small snippet rather than the more extensive code available within the “DOWNLOAD CODE” button.
Hope this helps someone!
Glad to help! And thanks for sharing this tip. :)
Hi David,
Really a great snippet and very useful. Few days ago I did it with javascript on front-end but this method is quite elegant. Just thinking about drop-down or multi select fields is that possible to customize this snippet to limit selection in dropdown or multiselect fields?
Hi Jamil, glad you found this snippet useful. Drop downs only allow one selection regardless. It is possible to limit multiselect fields but the code would require many changes.
Dear David, Is it possible to apply this to post categories, or product categories in the Woocommerce form? Thank you.
Not easily. You’d probably be better off with a custom solution like this.
Thanks David! The trouble with all those solutions is that they operate in the browser, which the user can change.
Wow! Thank you so much for sharing the snippet! This is going to save a lot of confusion :)
Glad to help, William. :)
I’m interested in having 15 questions, each a checkbox with one option.
Do you like scarves? as the question and a single checkbox “yes” underneath. I’ll have 15 such questions but I only want people to be able to select 8 checkboxes, i.e. select 8 yes times. Is this possible since the checkboxes are in different questions? If so, how? And do I need to buy the plugin to achieve this?
Yes, this is possible with the GP Limit Checkboxes plugin. It has a feature that allows you to span the limit over multiple files (screenshot).
Great little snippet, will come in handy.
Any chance you can help me with something? I have two separate checkbox fields, can we combine them so say no more than 7 can be checked between the two checkbox fields? Get what im saying?
Thanks -Dan
This is possible with the GP Limit Checkboxes perk. See the “Spanning limits across multiple fields” section. :)