Custom field IDs for Gravity Forms

If you haven’t had the chance to work with it before, Gravity Forms is pretty fantastic. I was first turned onto it a few years ago while I was at Buckeye Interactive, where it was a mainstay across most of our client sites. Besides presenting an easy-to-manage interface for building forms, the plugin also makes good use of the WordPress Plugin API (thus making my life way easier) and has a vibrant ecosystem of official and unofficial add-ons.

One area where Gravity Forms could stand to improve, however, is making it easier to identify fields. Let’s say, for example, we have a form where we’re collecting a name and an email address; outside of assuming that the regular text field is the name and the input[type="email"] is the email address, Gravity Forms doesn’t really have a straight-forward way to identify fields when you’re doing extra work with submissions (like sending them to a newsletter or a CRM system).

In my new role as Director of Technology at Growella, one of the first things I needed to figure out was how we could reliably map Gravity Forms submissions into third-party tools.

Assigning custom IDs to fields

Fortunately, Gravity Forms lets us add custom properties to our fields; knowing this, we can easily add a “Field ID” input, which lets us reference a field by this ID:

/**
 * Render the "Field ID" property for Gravity Form fields under the "Advanced" tab.
 *
 * @param int $position The current property position.
 */
function growella_render_field_id_setting( $position ) {
	if ( 50 !== $position ) {
		return;
	}
?>

	<li class="field_id_setting field_setting">
		<label for="field_field_id" class="section_label">
			<?php echo esc_html_x( 'Field ID', 'label for Gravity Forms field ID input', 'growella' ); ?>
		</label>
		<input id="field_field_id" type="text" onchange="SetFieldProperty('fieldID', this.value);" />
	</li>

<?php
}
add_action( 'gform_field_advanced_settings', 'growella_render_field_id_setting' );

This function will generate the Field ID input markup on the gform_field_advanced_settings action, calling Gravity Forms’ setFieldProperty() function whenever the input changes.

Next, we need to tell Gravity Forms that fieldID is a valid property:

/**
 * Print custom scripting for the "Field ID" property.
 */
function growella_editor_script() {
?>

	<script type="text/javascript">

		// Add .field_id_setting onto the end of each field type's properties.
		jQuery.map(fieldSettings, function (el, i) {
			fieldSettings[i] += ', .field_id_setting';
		});

		// Populate field settings on initialization.
		jQuery(document).on('gform_load_field_settings', function(ev, field){
			jQuery(document.getElementById('field_field_id')).val(field.fieldID || '');
		});
	</script>

<?php
}
add_action( 'gform_editor_js', 'growella_editor_script' );

This will also pre-populate the input’s value with a field ID, if one has previously been saved.

A Gravity Forms field with a custom "Field ID" input

That’s it! With these two functions, we’re able to assign custom field IDs, removing a lot of the headache of mapping to third-party services.

Mapping Gravity Forms fields to third-party services

Having the custom field IDs is great, but the icing on the cake is being able to easily get any fields with custom IDs to send to your third-party services. Thanks to your friends at Growella, now you can:

/**
 * Given a form entry, build an array of entry data keyed with its field IDs.
 *
 * The resulting array will include any value from $entry on a $form field with an assigned fieldID
 * property. Complex fields are handled as long as the field IDs are passed as a comma-separated
 * list _and_ we have enough IDs for each non-hidden input within a field.
 *
 * For example, if $form has a GF_Field_Name field containing a first and last name, but we only
 * provide a single field ID (e.g. "name"), only the first name would be saved. Instead, we want to
 * be sure we're using field IDs like "firstname, lastname" to ensure that all data gets mapped.
 *
 * @param array $entry The Gravity Forms entry object.
 * @param array $form  The Gravity Forms form object.
 * @return array An array of entry values from fields with IDs attached.
 */
function growella_get_mapped_fields( $entry, $form ) {
	$mapping = array();

	foreach ( $form['fields'] as $field ) {
		if ( ! isset( $field['fieldID'] ) || ! $field['fieldID'] ) {
			continue;
		}

		// Explode field IDs.
		$field_ids = array_map( 'trim', explode( ',', $field['fieldID'] ) );

		// We have a complex field, with multiple inputs.
		if ( ! empty( $field['inputs'] ) ) {
			foreach ( $field['inputs'] as $input ) {
				if ( isset( $input['isHidden'] ) && $input['isHidden'] ) {
					continue;
				}

				$field_id = array_shift( $field_ids );

				// If $field_id is empty, don't map this input.
				if ( ! $field_id ) {
					continue;
				}

				// Finally, map this value based on the $field_id and $input['id'].
				$mapping[ $field_id ] = $entry[ $input['id'] ];
			}
		} else {
			$mapping[ $field_ids[0] ] = $entry[ $field['id'] ];
		}
	}

	return $mapping;
}

In almost any Gravity Forms callback (for example, gform_after_submission), we receive two arrays: $entry and $form. By passing these directly to growella_get_mapped_fields(), we can quickly retrieve non-empty values for fields we’ve assigned IDs to. For example:

/**
 * Integrate with some third-party service.
 *
 * @param array $entry The Gravity Forms entry.
 * @param array $form  The Gravity Forms form.
 */
function do_some_cool_integration( $entry, $form ) {
	$mapped_fields = growella_get_mapped_fields( $entry, $form );

	// Post $mapped_fields to your third-party service.
}
add_action( 'gform_after_submission', 'do_some_cool_integration', 10, 2 );

Now, go forth and integrate Gravity Forms with :allthethings:!

3 comments on "Custom field IDs for Gravity Forms"

  1. Andy 3 days ago

    Great post, thanks for sharing your code; I was having the very same problems pulling out and sharing data collected from forms and this code looks like a great starting point!

    Many thanks!

    • studio4 4 hours ago

      Just in case anyone else is interested in this if you want to add the fieldID to the front-end form as a class you can use the gform_field_css_class hook:

      /**
      * Show mapped field ID in front-end forms for CSS and JS manipulation
      * @param [type] $classes existing classes string
      * @param [type] $field field object
      * @param [type] $form form object
      * @return [type] new classes string
      */
      function growella_gform_custom_class( $classes, $field, $form ) {

      if ( $field->fieldID ) {
      $classes .= ‘ ‘.$field->fieldID;
      }
      return $classes;
      }
      add_filter( ‘gform_field_css_class’, ‘growella_gform_custom_class’, 10, 3 );

  2. Mike 3 days ago

    Perfect – just what I needed! Cheers :)

Leave a Reply