Custom Multiple Input Form for Gravity Fields

Web
Men working in office

We recently undertook a new challenge in customising the excellent Gravity Form WordPress plugin that taught me something new, and required venturing into undocumented, or certainly non-obvious, waters. And that’s coming from someone who has done more hacking of Gravity Forms than one person should healthily undertake.

The requirement for the client was to collect Google tracking cookie data when a form is completed. This included 6 pieces of data:

  • Traffic Source
  • Google Click ID
  • Campaign
  • Traffic Medium
  • Traffic Search Term (Keyword)
  • Ad Content

The method to capture this data was with a JQuery script that extracted the data from the cookie and populated the values of some hidden input fields on the form.

Now, we could have set-up 6 hidden fields on each form on the site, but we chose to try to setup a single, custom Gravity Form field, that would allow us to add this tracking to a form with one click, well, two, you have to save the form after adding the field…

Setting-up your own input field on a Gravity Form

To enable us to do this required us to define a custom field type for Gravity Forms to then use.

Travis Smith’s article How to Create a Custom Form Field in Gravity Forms with a Terms of Service Form Field Example got us 90% of the way there.

In it he outlines the steps required to setup a custom form field in Gravity Forms:

  • Add a Button to the form editor interface so you can insert your own custom input field
  • Add the Field Title to allow setting it by default when inserting your field
  • Add the Input Field which allows you to output your actual input field when the form is displayed to a visitor
  • Add the Editor Form JS should you need to use custom properties or advanced field options in the editor interface
  • Add a Placement Custom Setting
  • Add a ToolTip to the form field editing interface
  • Add Custom External JS that may be required to manipulate your form input on the front-end of the site
  • Optional: Add the Appropriate CSS Classes

The Next 5% – Multiple Input Fields

Following these steps will easily get you set single-up with a custom input field. What if you want 6?

To do this you need to know how Gravity Forms handles multiple inputs per field, here is the HTML for a checkbox field output:

<div>
<ul class="gfield_checkbox" id="input_2_21">
<li>
<input name="input_21.1" type="checkbox" value="First Choice" id="choice_21_1" tabindex="12">
<label for="choice_21_1">First Choice</label>
</li>
<li>
<input name="input_21.2" type="checkbox" value="Second Choice" id="choice_21_2" tabindex="13">
<label for="choice_21_2">Second Choice</label>
</li>
<li>
<input name="input_21.3" type="checkbox" value="Third Choice" id="choice_21_3" tabindex="14">
<label for="choice_21_3">Third Choice</label>
</li>
</ul>
</div>

And look at how it saves input from a field with multiple checkboxes into the database, to table wp_rg_lead_detail:

01

The format is “{field id}.{input index}” e.g. 21.1, 21.2, 21.3

Therefore you need to set your field ID’s up in a similar way. This is best done using gform_editor_js_set_default_values action hook, and this is how we did it:

// set label of field(s), and define inputs
add_action("gform_editor_js_set_default_values", "gravity_form_custom_field_labels");

function gravity_form_custom_field_labels(){
// this hook is fired in the middle of a switch statement, so we need to add a case for our new field type ?>
case "track_cookie" :
field.label = "<?php _e("Tracking Cookie", "gravityforms"); ?>"; // setting the default field label
field.inputs = [
new Input( field.id + 0.1, '<?php echo esc_js(__("csr", "gravityforms")); ?>'),
new Input( field.id + 0.2, '<?php echo esc_js(__("gclid", "gravityforms")); ?>'),
new Input( field.id + 0.3, '<?php echo esc_js(__("ccn", "gravityforms")); ?>'),
new Input( field.id + 0.4, '<?php echo esc_js(__("cmd", "gravityforms")); ?>'),
new Input( field.id + 0.5, '<?php echo esc_js(__("ctr", "gravityforms")); ?>'),
new Input( field.id + 0.6, '<?php echo esc_js(__("cct", "gravityforms")); ?>'),
];
break;
<?php
}

The Last 5% – Outputting the Field Inputs

So, let’s see if our fields are being output when we view the form on the front-end of the website. As they’re hidden fields we’ll use the Inspect Element tool in Chrome:

02

Fantastic, we are now outputting our multiple input fields.

Now, if you populate your form and submit, you’ll see that the data is stored in the database:

03

But if you view the entry our Tracking Cookie field is empty:

04

Why is this happening?

Gravity Forms doesn’t know that we’re trying to output data for a field that has its data stored in an unusual way.

You can see the handling for a form entry output in the lead_detail_grid() function in Gravity Form plugin’s entry_detail.php file.

Fortunately we can make use of the gform_entry_field_value filter hook to take the lead entry and manipulate it for a custom output. Using this approach we can also provide friendly labels for each of our input fields, defined in $GLOBALS[‘track_cookie_field_names_array’]:

// set any custom handling for output of our custom field(s) entry
add_filter("gform_entry_field_value", "gravity_form_custom_field_entry_output", 10, 4);

function gravity_form_custom_field_entry_output($value, $field, $lead, $form){
if ($field["type"] == "track_cookie"){
    $value = '';
    foreach($GLOBALS['track_cookie_field_array'] AS $id => $entry){
        $value .= $GLOBALS['track_cookie_field_names_array'][$entry].': '.$lead[$field["id"].'.'.$id]."<br />";
    }
}
return $value;
}

You just need to make sure you call the appropriate lead value array ID, as before this is of the form “{field id}.{input index}”.

For our example as our field id is 20, the lead entry values are stored in $lead[‘20.1’], $lead[‘20.2’], $lead[‘20.3’], etc.

There you go, hopefully you now have the tools to build all kinds of weird and wonderful custom fields for Gravity Forms.