GF_Field

Introduction

The GF_Field class provides basic functionality for developers when creating new fields for Gravity Forms. It facilitates the following:

  • Adding a button for the field to the form editor
  • Defining the field title to be used in the form editor
  • Defining which settings should be present when editing the field
  • Registering the field as compatible with conditional logic
  • Outputting field scripts to the form editor and front-end
  • Defining the field appearance on the front-end, in the form editor and on the entry detail page
  • Validating the field during submission
  • Saving the entry value
  • Defining how the entry value is displayed when merge tags are processed, on the entries list and entry detail pages
  • Defining how the entry value should be formatted when used in csv exports and by framework based add-ons

Getting Started

These are the first steps you’ll need to take to create a field using the Field Framework.

  1. Creating a new class which extends GF_Field (Note: If your new field will have similar functionality to an existing field you can save some work by extending that field type instead e.g. GF_Field_Post_Image extends GF_Field_Fileupload)
  2. Add the $type variable
  3. Register the field with Gravity Forms

Example:

class GF_Field_Phone extends GF_Field {

    public $type = 'phone';

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

Main Functionality

Now you have the basic field you can start defining its appearance and behaviour by overriding functions from GF_Field or whichever the class you extended.

The examples shown below are taken from various field types.

get_form_editor_field_title()

The default behaviour of get_form_editor_field_title() is to return the value of the $type variable, however, you may want the field in the form editor to use a different title or have the first letter uppercased in which case you will want to override this method.

public function get_form_editor_field_title() {}

Example:

public function get_form_editor_field_title() {
    return esc_attr__( 'Phone', 'gravityforms' );
}

get_form_editor_button()

The default behaviour of get_form_editor_button() is to return an associative array assigning the field to the standard_fields group using the value returned by get_form_editor_field_title() as the button text.

The built-in groups are standard_fields, advanced_fields, post_fields, and pricing_fields. See the How To Add A Custom Field Group When Using The Field Framework article for an example showing how you can define a new group.

public function get_form_editor_button() {}

Example:

public function get_form_editor_button() {
	return array(
		'group' => 'advanced_fields',
		'text'  => $this->get_form_editor_field_title()
	);
}

get_form_editor_field_settings()

The default behavior of get_form_editor_field_settings() is to return an empty array so you will want to override this method and return an array containing the class names of the settings you want to appear on your field in the form editor.

You can find a list of the available settings in the following articles:

You can also define your own custom settings by using the gform_field_standard_settings, gform_field_appearance_settings, and gform_field_advanced_settings hooks.

function get_form_editor_field_settings() {}

Example:

function get_form_editor_field_settings() {
	return array(
		'conditional_logic_field_setting',
		'prepopulate_field_setting',
		'error_message_setting',
		'label_setting',
		'label_placement_setting',
		'admin_label_setting',
		'size_setting',
		'rules_setting',
		'visibility_setting',
		'duplicate_setting',
		'default_value_setting',
		'placeholder_setting',
		'description_setting',
		'phone_format_setting',
		'css_class_setting',
	);
}

is_conditional_logic_supported()

The default behavior of is_conditional_logic_supported() is to return false meaning the field can’t be used with conditional logic. Override this method by returning true to allow the field to be used when configuring conditional logic rules.

public function is_conditional_logic_supported() {}

Example:

public function is_conditional_logic_supported() {
    return true;
}

get_field_input()

This method is used to define the fields inner markup, including the div with the ginput_container class. The default behavior of get_field_input() is to return an empty string so you will want to override this method.

public function get_field_input( $form, $value = '', $entry = null ) {}

Parameters:

  • $form Form Object
    The form object currently being processed.
  • $value string|array
    The field value from the $_POST or the resumed incomplete submission.
  • $entry null|Entry Object
    Null or the entry object currently being edited.

Return:

The field’s inner markup. string

Example:

public function get_field_input( $form, $value = '', $entry = null ) {
	$form_id         = $form['id'];
	$is_entry_detail = $this->is_entry_detail();
	$id              = (int) $this->id;

	if ( $is_entry_detail ) {
		$input = "<input type='hidden' id='input_{$id}' name='input_{$id}' value='{$value}' />";

		return $input . '<br/>' . esc_html__( 'Coupon fields are not editable', 'gravityformscoupons' );
	}

	$disabled_text         = $this->is_form_editor() ? 'disabled="disabled"' : '';
	$logic_event           = version_compare( GFForms::$version, '2.4.1', '<' ) ? $this->get_conditional_logic_event( 'change' ) : '';
	$placeholder_attribute = $this->get_field_placeholder_attribute();
	$coupons_detail        = rgpost( "gf_coupons_{$form_id}" );
	$coupon_codes          = empty( $coupons_detail ) ? '' : rgpost( "input_{$id}" );

	$input = "<div class='ginput_container' id='gf_coupons_container_{$form_id}'>" .
	         "<input id='gf_coupon_code_{$form_id}' class='gf_coupon_code' onkeyup='DisableApplyButton({$form_id});' onchange='DisableApplyButton({$form_id});' onpaste='setTimeout(function(){DisableApplyButton({$form_id});}, 50);' type='text'  {$disabled_text} {$placeholder_attribute} " . $this->get_tabindex() . '/>' .
	         "<input type='button' disabled='disabled' onclick='ApplyCouponCode({$form_id});' value='" . esc_attr__( 'Apply', 'gravityformscoupons' ) . "' id='gf_coupon_button' class='button' {$disabled_text} " . $this->get_tabindex() . '/> ' .
	         "<img style='display:none;' id='gf_coupon_spinner' src='" . gf_coupons()->get_base_url() . "/images/spinner.gif' alt='" . esc_attr__( 'please wait', 'gravityformscoupons' ) . "'/>" .
	         "<div id='gf_coupon_info'></div>" .
	         "<input type='hidden' id='gf_coupon_codes_{$form_id}' name='input_{$id}' value='" . esc_attr( $coupon_codes ) . "' {$logic_event} />" .
	         "<input type='hidden' id='gf_total_no_discount_{$form_id}'/>" .
	         "<input type='hidden' id='gf_coupons_{$form_id}' name='gf_coupons_{$form_id}' value='" . esc_attr( $coupons_detail ) . "' />" .
	         "</div>";

	return $input;
}

get_field_content()

This method is used to define the fields overall appearance, such as how the admin buttons, field label, description or validation messages are included. Most fields won’t need to override this method, display only types such as Page, Section or HTML are examples of fields which do override the get_field_content() method.

public function get_field_content( $value, $force_frontend_label, $form ) {}

Parameters:

  • $value string|array

    The field value from the $_POST or the resumed incomplete submission.

  • $force_frontend_label boolean

    Should the frontend label be displayed in the admin even if an admin label is configured. Default is false.

  • $form Form Object

    The form object currently being processed.

Return:

The fields markup. string. Note: use the placeholder {FIELD} to define where the markup returned by get_field_input() should be included.

Example:

public function get_field_content( $value, $force_frontend_label, $form ) {
	$form_id         = $form['id'];
	$admin_buttons   = $this->get_admin_buttons();
	$is_entry_detail = $this->is_entry_detail();
	$is_form_editor  = $this->is_form_editor();
	$is_admin        = $is_entry_detail || $is_form_editor;
	$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;
}

validate()

Override this method to perform custom validation logic. This method is only used if the field passes the required validation (field is not empty), and any no duplicates validation.

public function validate( $value, $form ) {}

Parameters:

  • $value string|array

    The field value from the $_POST.

  • $form Form Object

    The form object currently being processed.

Return:

This method does not return a value via a return statement. Return the validation result and message by setting the fields failed_validation and validation_message properties.

Example:

public function validate( $value, $form ) {
	$regex = '/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/';
	if ( $this->phoneFormat == 'standard' && $value !== '' && $value !== 0 && ! preg_match( $regex, $value ) ) {
		$this->failed_validation = true;
		if ( ! empty( $this->errorMessage ) ) {
			$this->validation_message = $this->errorMessage;
		}
	}
}

set_input_validation_state()

This method is used on fields which have multiple inputs in order to update the aria-invalid attribute if a single input is invalid. When using gform_field_validation developers should mark a field’s inputs as valid/invalid using this method. When the field is rendered, this context value is used in order to determine what the aria-invalid value should be.

public function set_input_validation_state( $input_id, $is_valid ) {}

Parameters:

  • $input_id string

    The input ID within the field.

  • $is_valid boolean

    The input validation state. true if is valid.

Return:

This method does not return a value via a return statement.

get_form_inline_script_on_page_render()

Override this method to include scripts with the form init scripts on page render. The init scripts are usually included immediately after the form in the page body.

Note: <script> tags should not be included as they will automatically be added.

public function get_form_inline_script_on_page_render( $form ) {}

Parameters:

  • $form Form Object

    The form object currently being processed.

Return:

A string containing the script to be included on page render.

Example:

public function get_form_inline_script_on_page_render( $form ) {
	$script = '';
	if ( $this->phoneFormat == 'standard' ) {
		$script = "if(!/(android)/i.test(navigator.userAgent)){jQuery('#input_{$form['id']}_{$this->id}').mask('(999) 999-9999').on('keypress', function(e){if(e.which == 13){jQuery(this).blur();} } );}";
	}
	return $script;
}

get_form_editor_inline_script_on_page_render()

Override this method to include scripts for this field type in the form editor.

Note: <script> tags should not be included as they will automatically be added.

public function get_form_editor_inline_script_on_page_render() {}

Example:

public function get_form_editor_inline_script_on_page_render() {
	return "
	gform.addFilter('gform_form_editor_can_field_be_added', function (canFieldBeAdded, type) {
		if (type == 'coupon') {
			if (GetFieldsByType(['product']).length <= 0) {
				alert(" . json_encode( esc_html__( 'You must add a Product field to the form', 'gravityformscoupons' ) ) . ");
				return false;
			} else if (GetFieldsByType(['total']).length  <= 0) {
				alert(" . json_encode( esc_html__( 'You must add a Total field to the form', 'gravityformscoupons' ) ) . ");
				return false;
			} else if (GetFieldsByType(['coupon']).length) {
				alert(" . json_encode( esc_html__( 'Only one Coupon field can be added to the form', 'gravityformscoupons' ) ) . ");
				return false;
			}
		}
		return canFieldBeAdded;
	});";
}

get_value_save_entry()

Override this method to save the entry value in a custom format.

public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {}

Parameters:

  • $value string|array

    The input value to be saved.

  • $form Form Object

    The form object currently being processed.

  • $input_name string

    The name attribute for the input being saved e.g. input_1

  • $lead_id integer

    The ID of the entry currently being processed.

  • $lead Entry Object

    The entry object currently being processed.

Return:

The input value to be saved. string|array

Example:

public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {

	if ( $this->phoneFormat == 'standard' && preg_match( '/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/', $value, $matches ) ) {
		$value = sprintf( '(%s) %s-%s', $matches[1], $matches[2], $matches[3] );
	}

	return $value;
}

get_value_merge_tag()

This method is used to define the value returned when the field merge tags are processed. The default behavior of get_value_merge_tag() is to return the entry value so you will want to override this method if the value needs formatting before being returned.

public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {}

Parameters:

  • $value string|array

    The field value. Depending on the location the merge tag is being used the following functions may have been applied to the value: esc_html, nl2br, and urlencode.

  • $input_id string

    The field or input ID from the merge tag currently being processed.

  • $entry Entry Object

    The entry object currently being processed.

  • $form Form Object

    The form object currently being processed.

  • $modifier string

    The merge tag modifier.

  • $raw_value string|array

    The raw field value from before any of the functions mentioned in the description of $value above may have been applied.

  • $url_encode boolean

    Indicates if the urlencode function was applied to the $value.

  • $esc_html boolean

    Indicates if the esc_html function was applied to the $value.

  • $format string

    The format requested for the location the merge is being used. Possible values: html, text or url.

  • $nl2br boolean

    Indicates if the nl2br function was applied to the $value.

Return:

The formatted entry value.

Example:

public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
	$format_modifier = empty( $modifier ) ? $this->dateFormat : $modifier;

	return GFCommon::date_display( $value, $format_modifier );
}

get_value_entry_detail()

This method is used to define the value returned when the {all_fields} merge tag is processed and when the entry detail page is displayed.

public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {}

Parameters:

  • $value string|array

    The field value.

  • $currency string

    The currency code from the Entry Object, if available.

  • $use_text boolean

    When processing choice based fields should the choice text be returned instead of the value.

  • $format string

    The format requested for the location the merge is being used. Possible values: html, text or url.

  • $media string

    The location where the value will be displayed. Possible values: screen or email.

Return:

The formatted entry value.

Example:

public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
	if ( is_array( $value ) && ! empty( $value ) ) {
		$product_name = trim( $value[ $this->id . '.1' ] );
		$price        = trim( $value[ $this->id . '.2' ] );
		$quantity     = trim( $value[ $this->id . '.3' ] );

		$product = $product_name . ', ' . esc_html__( 'Qty: ', 'gravityforms' ) . $quantity . ', ' . esc_html__( 'Price: ', 'gravityforms' ) . $price;

		return $product;
	} else {
		return '';
	}
}

Sanitization

Because each field type handles data in different ways, sanitization is the responsibility of each individual field type. When we talk about sanitization for Gravity Forms fields, one must think about two aspects of it. Input sanitization ( making sure values submitted by users are safe ), and Output sanitization ( making sure values displayed to the user or exported are properly encoded and/or sanitized ).

It is also important to keep field validation in mind and implement an appropriate validation when needed. For more information about validation, see the validate() section above.

Input Sanitization

Because of all the different types and uses of data submitted by users, Gravity Forms by default doesn’t “destroy” or encode submitted data. It is the responsibility of each field type to make a judgment on which types of data are allowed and perform an appropriate sanitization. To sanitize field data, simply override the sanitize_entry_value() function. The following code snippet shows how to sanitize a field type that only accepts positive integers.

//Sanitizes the submitted value so that only positive integers are allowed
public function sanitize_entry_value( $value, $form_id ) {

   //makes sure submitted value is a positive integer
   $value = absint( $value );

   //return sanitized value
   return $value;
}

HTML tag support

For field types that need to support unencoded HTML tags, override the allow_html() function:

//Allows most HTML tags. Script tags and other unsafe tags will still be stripped out.
public function allow_html(){
    return true;
}

If you want to support some HTML tags but not all, override the get_allowable_tags() function:

//Allows <b> and <i> tags. All other HTML tags will be stripped out.
public function get_allowable_tags( form_id = null ){
    return '<b><i>';
}

Output Sanitization

When displaying field data to users (i.e. merge tags and entry pages ), fields must take care of encoding its data properly. For fields that do not support HTML tags (i.e. Text Field), Gravity Forms will encode the output and no extra sanitization by the field is required. However, fields that support HTML must encode its data appropriately before being displayed to the screen. Output sanitization is done via the available get_value_XXX() functions.

To sanitize values before being output by merge tags, override the get_value_merge_tag() function. Note: For the {all_fields} merge tag, use the get_value_entry_detail() function instead.


/**
* Format the entry value for when the field/input merge tag is processed. Not called for the {all_fields} merge tag.
 * Return a value that is safe for the context specified by $format.
* */

public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
       if ( $format === 'html' ) {

          //Escapes value so that it is safe to be displayed in HTML context.
          //$value could have already been encoded, so we use $raw_value to ensure it is not double encoded
          $return = esc_html( $raw_value );

          //Run nl2br() to preserve line breaks when auto-formatting is disabled on notifications/confirmations.
          $return = nl2br( $return );


	} else {
           //Text context does not require encoding
           $return = $value;
	}



       return $return;

}




To sanitize values before being output in the entry list page, override the get_value_entry_list() function.

/**
* Format the entry value for display on the entries list page.
* Return a value that's safe to display on the page.
*/

public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
	


      //Escapes value so that it is safe to be displayed on the entry list page
      return = esc_html( $value );


}

To sanitize values before being output in the entry detail page or by the {all_fields} merge tag, override the get_value_entry_detail() function.

/**
* Format the entry value for display on the entry detail page and for the {all_fields} merge tag.
* Return a value that's safe to display for the context of the given $format.
*/
public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
     if ( $format === 'html' ) {
	  //Escapes value so that it is safe to be displayed on the entry detail page or via the {all_fields} merge tag
          $return = esc_html( $value )

	} else {
		//Text context does not require encoding
		$return = $value;
	}
     return $return;

}

To manipulate or format values before being exported, override the get_value_export() function.


/**
* Format the entry value before it is used in entry exports and by framework add-ons using GFAddOn::get_field_value().
*/

public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
     //Export doesn’t require encoding, but field data may require some manipulation or formatting before it is exported
     $value = rgar( $entry, $input_id );
     return $value;
}


Helpers

get_input_type()

You can use the get_input_type() method to retrieve the fields input type. If set, the inputType property will be returned, otherwise, it will return the type property.

public function get_input_type() {}

Example:

Some fields have a ‘field type’ setting allowing the user to choose the type of input to use e.g. text or checkbox. This setting will save the user’s selection under the inputType property in the Field Object.

If you needed to loop through the fields in the form object and only perform actions for a specific input type you would need to check both the type and inputType properties. The get_input_type() method makes this easier, so instead of doing something like this:

if ( $field->type == 'checkbox' || $field->inputType == 'checkbox' ) {}

You can simply do this:

if ( $field->get_input_type() == 'checkbox' ) {}

get_tabindex()

get_tabindex() returns a string containing the tabindex attribute and value which can then be added to the field input.

public function get_tabindex() {}

Example:

See get_field_input above for a usage example.

get_conditional_logic_event()

The get_conditional_logic_event() method returns the input attribute and value which will trigger the evaluation of conditional logic rules which depend on this field. Note: This function has been deprecated in Gravity Forms 2.4. No replacement for it is needed, Conditional Logic is now triggered based on .gfield class name.

public function get_conditional_logic_event( $event ) {}

Parameters:

  • $event string

    The event attribute which should be returned. Possible values: keyup, click, or change.

Return:

A string containing the attribute and value.

Example:

$logic_event = $this->get_conditional_logic_event( 'keyup' );

get_field_placeholder_attribute()

The get_field_placeholder_attribute() method returns a string containing the field placeholder attribute and value.

public function get_field_placeholder_attribute() {}

Example:

See get_field_input above for a usage example.

get_input_placeholder_attribute()

The get_input_placeholder_attribute() method returns a string containing the placeholder attribute and value for an input belonging to a multi-input field.

public function get_input_placeholder_attribute( $input ) {}

Parameters:

  • $input array

    An array containing the properties of a specific input from the Field Object *inputs* property.

Return:

A string containing the attribute and value.

Example:

$address_street_field_input   = GFFormsModel::get_input( $this, $this->id . '.1' );
$street_placeholder_attribute = $this->get_input_placeholder_attribute( $address_street_field_input );

Core Field Classes

Below is a list of the classes, included with Gravity Forms, which extend the GF_Field class.

Add-On Field Classes

Below is a list of the classes, included with Gravity Forms Add-Ons, which extend the GF_Field class.