This is not my strong point as you may have guessed. The checkboxes function below works well. It would however be brilliant if you could dynamically change the max value below based on a field on the form (a number field).
This way you could pass a value from another form and limit the choices based on that value. I have tried messing around but have not clue as to how to refer to the specific number field in the form. I min could also be dynamic even better.
I do appreciate this forum it has some very helpful and talented people.
new GFLimitCheckboxes(25,
array(
5 => array(
'min' => 1,
'max' => **4**
)
));
/**
* 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[$fieldgrab]);
} else {
$ids = array($key);
}
$options['field'] = $ids;
}
return $field_limits;
}
}