PMG Digital Made for Humans

Creating a Custom Gravity Forms Field With Multiple Hidden Fields

7 MINUTE READ | September 10, 2015

Creating a Custom Gravity Forms Field With Multiple Hidden Fields

Author's headshot

Emily Fox

Emily Fox has written this article. More details coming soon.

In this blog post I’m going to run through how to add a custom Gravity Forms field that will add multiple hidden fields. This field would easily allow you to add multiple fields that are the same across different forms, saving you time when creating new forms. In my instance, I was hooking DemandBase into Gravity Forms, this required adding 40 additional hidden fields to each form for DemandBase to populate.

This code can go in your functions.php file, however I would strongly recommend adding it as a plugin. This ensures that it is not removed with any theme changes or updates.

Note: I ended up removing the gform_add_field_buttons and gform_field_type_title filters in favor of extending the GF_Fields class instead.

One of the first things you will do when adding a custom field is add the field button to the field toolbox. This can be done by hooking into the gform_add_field_buttons filter. I did not end up using this as it was a lot easier to accomplish what I was trying to do by extending the GF_Fields class.

Once the new field box is added to your toolbox, you will want to assign a title to it. You can add a title using the gform_field_type_title filter. This displays before the Field ID, visible above a field when you hover over it. This is not the field label.


<?phpadd_filter('gform_add_field_buttons', add_field);function add_field(){  foreach ($field_group as &$group) {    if ($group['name'] == 'advanced_fields') {      $group['fields'][] = array (        'class'     => 'button',        'value'     => __('My Custom Field', 'gravityforms'),        'onclick'   => "StartAddField('my_custom_field');",        'data-type' => 'my_custom_field'      );      break;    }  }  return $field_group;}add_filter('gform_field_type_title', add_field_title, 10, 2);funciton add_field_title(){  if ($field_type == 'my_custom_field') {    $title = __('My Custom Hidden Fields', 'gravityforms');  }    return $title;}

The gform_field_input filter allows you to modify the field input. This is triggered before the form input field is created. In the below example, we are first checking that the field is our custom field, we don’t want to modify the input of any other fields. If it is our custom field, we want to render the input fields by looping through an array of all the fields. I called a custom_fields() function which just returned a simple array of fields i.e.

function custom_fields() {     return array('one_field', 'another_field', 'a_third_field'); }

This was needed to match the field names to each field for the DemandBase field mapping. I added the field name as a class on that input and used that to dynamically map each field. We’re rendering each field with the name value of input_{fieldid}.{inputnumber} and an id of input_{fieldid}_{inputnumber}. This allows us to store all the input values for each field under the singular field ID, similar to how checkboxes or other multiple select fields work within Gravity Forms.

One unexpected issue I ran across was that you can’t use 10, 20, 30 etc. for the input number and must start with 1. Gravity Forms will remove the trailing zero, which causes conflicts with inputs 1, 2, and 3. My workaround for this was lines 18 – 20 below. The $i variable starts at 1, each foreach loop increases it by 1. If it is divisible by 10 then it adds another 1 and continues. The first input name is therefore input_{fieldid}.1 when it gets to the 10th item in the array the input name is input_{fieldid}.11 and so on.


<?phpadd_filter('gform_field_input', 'render_fields', 10, 5);function render_fields($input, $field, $value, $entry_id, $form_id){  if ($field->type == 'my_custom_field') {    $input = '<div class="ginput_complex ginput_container">';    $i = 1;    foreach (custom_fields() as $f) {        $input .= sprintf('<input type="hidden" name="input_%1$s.%2$s" class="%3$s gform_hidden" id="input_%1$s_%4$s_%2$s" value="%5$s" />',            $field['id'],            $i,            esc_attr($f),            $form_id,            $value[$field['id'].'.'.$i]        );        $i ++;        if ($i % 10 == 0) {            $i++;        }    }    $input .= '</div>';  }  return $input;}

Once you have rendered the fields you will need hook into the 

 action hook. This field allows you to define default field properties when creating a new field type. It is needed for the form entry submission to register the custom fields created. We are hooking into Gravity Forms’ SetDefaultValues() function, allowing us to inject JavaScript in. Once again, we first want to check that we’re in our new field type, not modifying another field. We then loop through each of our custom fields and create a new Input.


<?phpadd_action('gform_editor_js_set_default_values', set_default_values);function set_default_values(){  ?>  case 'my_custom_field' :    field.label = '<?php _e('My Custom Hidden Fields', 'gravityforms'); ?>';    field.inputs = [        <?php        $i = 1;        foreach (custom_fields() as $f) { ?>            new Input( + 0.<?php echo $i; ?>, '<?php echo esc_js(__($f, 'gravityforms')); ?>'),        <?php            $i++;            if ($i % 10 == 0) {                $i++;            }        } ?>    ];    break;  <?php}

The form fields wasn’t working exactly as I wanted, the stored entry submission was not displaying in the admin area and I had an error on form submission that my custom field data array was being converted to a string. This was caused because the form was trying to save using the default GF_Field class, which works kind of as a catch all for fields not defined. To resolve this I exteded the GF_Field class. This allowed me to remove some of the filters I had setup as they were now managed through my new class.

The functions get_form_editor_button and get_form_editor_field_title are used to create my button and custom field type title, rather than using filters. The get_field_content function allows me to remove the hidden field label from the form, this is taken from the GF_Field_Hidden class (gravityforms/includes/fields/class-gf-field-hidden.php).

The get_value_entry_detail function was needed to fix the error I got when submitting a form, this code was taken from the GF_Field_Checkbox class (gravityforms/includes/fields/class-gf-field-checkbox.php). It treats the entry submission for our custom field as an array of data, which it is, rather than a string. By storing the data correctly, it also allows the data to display correctly in the form entry data when viewing it in the admin area.


<?phpclass My_Custom_Field extends \GF_Field{    public $type = 'my_custom_field';    public function get_form_editor_button()    {        return array(            'group' => 'advanced_fields',            'text'  => __('My Custom Field', 'gravityforms')        );    }    public function get_form_editor_field_title()    {        return __('My Custom Fields', 'gravityforms');    }    public function get_form_editor_field_settings()    {        return array(            'label_setting'        );    }    public function get_field_content($value, $force_frontend_label, $form)    {        $form_id         = $form['id'];        $admin_buttons   = $this->get_admin_buttons();        $field_label     = $this->get_field_label($force_frontend_label, $value);        $field_id        = is_admin() || $form_id == 0 ? "input_{$this->id}" : 'input_' . $form_id . "_{$this->id}";        $field_content   = !is_admin() ? '{FIELD}' : $field_content = sprintf("%s<label class='gfield_label' for='%s'>%s</label>{FIELD}", $admin_buttons, $field_id, esc_html($field_label));        return $field_content;    }    public function get_value_entry_detail($value, $currency = '', $use_text = false, $format = 'html', $media = 'screen')    {        if (is_array($value)) {            $items = '';            foreach ($value as $key => $item) {                if (!empty($item)) {                    switch ($format) {                        case 'text' :                            $items .= \GFCommon::selection_display($item, $this, $currency, $use_text) . ', ';                            break;                        default:                            $items .= '<li>' . \GFCommon::selection_display( $item, $this, $currency, $use_text ) . '</li>';                            break;                    }                }            }            if (empty($items)) {                return '';            } elseif ($format == 'text') {                return substr($items, 0, strlen( $items ) - 2);             } else {                return "<ul class='bulleted'>$items</ul>";            }        } else {            return $value;        }    }}

Hopefully this post helps you add your custom Gravity Forms field and saves you a lot of time!

Stay in touch

Bringing news to you

Subscribe to our newsletter

By clicking and subscribing, you agree to our Terms of Service and Privacy Policy

– Emily Fox

Related Content

thumbnail image

AlliPMG CultureCampaigns & Client WorkCompany NewsDigital MarketingData & Technology

PMG Innovation Challenge Inspires New Alli Technology Solutions

4 MINUTES READ | November 2, 2021

thumbnail image

Applying Function Options to Domain Entities in Go

11 MINUTES READ | October 21, 2019

thumbnail image

My Experience Teaching Through Jupyter Notebooks

4 MINUTES READ | September 21, 2019

thumbnail image

Working with an Automation Mindset

5 MINUTES READ | August 22, 2019

thumbnail image

3 Tips for Showing Value in the Tech You Build

5 MINUTES READ | April 24, 2019

thumbnail image

Testing React

13 MINUTES READ | March 12, 2019

thumbnail image

A Beginner’s Experience with Terraform

4 MINUTES READ | December 20, 2018