Custom GF_Field_Checkbox does not take checked values

I’m trying to make a custom field of type checkbox that lists dynamically populated choices based on custom logic.

The field extends GF_Field_Checkbox and overrides the get_checkbox_choices method by going to populate the choices, and then delegating the markup printing to the same parent method.

The checkboxes come correctly rendered and to the submission of the form the values come correctly sent, however Gravity Forms rather than giving me confirmation of submission brings me back to the page of the form telling me that the field is obligatory, and none of the choices that I had ticked turns out selected. As if Gravity Forms does not “see” the choices to validate, and tells me that the field has not been compiled.

What am I doing wrong?

This is the source of the plugin:

<?php

/*
Plugin Name: Espero - Gravity Forms Opere Museo
Plugin URI: https://www.espero.it
Description: Recupera le opere di un post di tipo Museo e le mostra come radio nel form.
Version: 1.0
Author: Federico Liva
Author URI: https://www.espero.it
*/

if (class_exists('GF_Field')) {

    class GFOpereMuseo_Field extends GF_Field_Checkbox
    {
        public $type = 'operemuseo';

        /**
         * @return string
         */
        public function get_form_editor_field_title()
        {
            return esc_attr__('Opere Museo', 'operemuseo');
        }

        /**
         * @return string
         */
        public function get_form_editor_field_icon()
        {
            return plugin_dir_url(__FILE__) . '/icon.png';
        }

        /**
         * @return string[]
         */
        public function get_form_editor_button()
        {
            return [
                'group' => 'post_fields',
                'text' => $this->get_form_editor_field_title(),
                'description' => 'Mostra la lista delle opere impostate negli articoli Museo.',
            ];
        }

        /**
         * Eredita le impostazioni del campo radio, rimuovendo la definizione delle scelte, che verranno recuperate
         * direttamente dal post di tipo Museo.
         *
         * @return string[]
         */
        public function get_form_editor_field_settings()
        {
            return array_diff(parent::get_form_editor_field_settings(), ['choices_setting']);
        }

        /**
         * @param array|string $value
         * @param string $disabled_text
         * @param int $form_id
         * @return string
         */
        public function get_checkbox_choices($value, $disabled_text, $form_id = 0)
        {
            if ($this->is_form_editor()) {
                return '';
            }

            $this->choices = [];
            $museoId = $_GET[$this->inputName] ?? 0;
            $opere = get_field('opere', $museoId);

            foreach ($opere as $opera) {
                $label = <<<HTML

                <img src="{$opera['immagine']['sizes']['square_640']}" alt="{$opera['nome']}">
                <span>{$opera['nome']}</span>

                HTML;

                $this->choices[] = [
                    'text' => $opera['nome'], // $label,
                    'value' => $opera['nome'],
                ];
            }

            return parent::get_checkbox_choices(...func_get_args());
        }


    }

    GF_Fields::register(new GFOpereMuseo_Field());
}

The mysterious thing, is that if I change the plugin type and instead of extending GF_Field_Checkbox I extend GF_Field_Radio, then overwriting the get_radio_choices method instead of get_checkbox_choices, in the exact same way, Gravity Forms works correctly.

When creating a checkbox type field you need to make sure the field inputs property is populated. See the following article:

Hi

Of your solution it is not clear to me how it should be done exclusively from PHP. I’ve studied the GF architecture and found out that GF_Field_Checkbox fields need to be populated by $this->inputs as well as $this->choices, and this must be done in the class constructor by populating the $data vector before anything else.

This is a basic example that illustrates the solution:

<?php

/*
Plugin Name: Espero - Gravity Forms Opere Museo
Plugin URI: https://www.espero.it
Description: Recupera le opere di un post di tipo Museo e le mostra come radio nel form.
Version: 1.0
Author: Federico Liva
Author URI: https://www.espero.it
*/

if (class_exists('GF_Field')) {

    class GFFooBar_Field extends GF_Field_Checkbox
    {
        public $type = 'foobar';

        /**
         * @inheritDoc
         */
        public function __construct($data = array())
        {
            if (!empty($data)) {
                $this->populate_choices_and_inputs($data);
            }

            parent::__construct($data);
        }

        /**
         * @param array $data
         */
        protected function populate_choices_and_inputs(array &$data)
        {
            $data['choices'] = [
                [
                    'text' => 'Apple',
                    'value' => 'apple',
                    'isSelected' => false,
                    'price' => '',
                ],
                [
                    'text' => 'Orange',
                    'value' => 'orange',
                    'isSelected' => false,
                    'price' => '',
                ],
                [
                    'text' => 'Mulberry',
                    'value' => 'mulberry',
                    'isSelected' => false,
                    'price' => '',
                ],
            ];

            $data['inputs'] = [
                [
                    'id' => $data['id'] . '.0',
                    'label' => 'Apple',
                    'name' => '',
                ],
                [
                    'id' => $data['id'] . '.1',
                    'label' => 'Orange',
                    'name' => '',
                ],
                [
                    'id' => $data['id'] . '.2',
                    'label' => 'Mulberry',
                    'name' => '',
                ],
            ];
        }
    }

    GF_Fields::register(new GFFooBar_Field());
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.