Dynamic max value. / Checkbox

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;
    }

}

Hi Adey. I will leave this open and ping the developer @spivurno but I suspect the best support for that customization would come from Gravity Wiz directly or if you are a Gravity Perks customer, from their talented support staff. As I said though, I’ll leave this open to see if anyone can suggest an approach for you.

1 Like

Thanks Chris (again).

I’m not a percs customer, I found that example online and it appeared to be open to all. If @spivurno could shed some light it would be wonderful. I fully appreciate him and his team are very busy although I have noticed he steps in to assist from time to time on the forums.

Thanks for leaving this open. :+1:

Hi Adey,

This basic snippet does not support it; however, if you decide to pick up a copy of Gravity Perks and use Gravity Forms Limit Checkboxes, we have a snippet that works with it to allow dynamically setting the limit.

1 Like

Thanks David,

I tried the function with the parameters below.

Am I correct in thinking it works like so

I set the form ID in this case 25.

The number field on form to refence is id 6

The checkbox ID is 5.

The number field #6 with either be 4 or 8 depending on what gets passed to it from another form.

I tried below and it has no affect on the checkbox number limitations. If I have misunderstood the functionality then please do let me know thanks.

new GPLC_Conditional_Limits( array(

    'form_id' => 25,

    'field_id' => 5,

    'conditionals' => array(

        array(

            'min' => 4,

            'max' => 4,

            'conditionalLogic' => array(

                'logicType' => 'all',

                'actionType' => 'show',

	            'rules' => array(

                    array(

                        'fieldId'  => 6,

                        'operator' => 'is',

                        'value'    => '4'

                    )

	            )

            )

        ),

	    array(

		    'min' => 8,

		    'max' => 8,

		    'conditionalLogic' => array(

			    'logicType' => 'all',

                'actionType' => 'show',

			    'rules' => array(

				    array(

					    'fieldId'  => 6,

					    'operator' => 'is',

					    'value'    => '8'

				    )

			    )

		    )

	    )

    )

) );

Ok scrap that sorry it was if I purchased the gravity perk. I’m stuck then. Not to worry thanks for replying anyway,

1 Like