Email Routing in Gravity Forms Notifications

Email Routing in Gravity Forms Notifications

IntroductionConfigurationTroubleshooting

Introduction

Within each Gravity Forms notification, you have the option of configuring additional routing. This is similar to conditional logic, in that different events can cause the notification to go to a different recipient. But unlike conditional logic, Routing can』t prevent the notification processing, it only provides the email address to be used for the Send To setting, therefore it』s important to make sure your routing rules will cover all the possible user choices to prevent scenarios where your routing setup doesn』t provide any email address and therefore the notification is processed with an empty value for the Send To.

In this article, we will show you how to configure routing options within your notification.

Configuration

This short animation shows how to access and modify Notifications for a form.

First, start by accessing the notification that you want to configure additional routing for. This can be done by accessing the form associated with the notification, hovering over Settings, clicking on Notifications, and then accessing the notification you want to manage. If you want to create a new notification, simply click the Add New button. Within the settings for your notification, you will see an option labeled Send To. If you select Configure Routing, additional options similar to conditional logic will appear. Inside the routing configuration, the first thing you will need to do is determine where the notification will be sent if the routing condition is met. Simply enter the email address of the user that you want to send the notification. Next, you』ll need to configure the field that the routing condition will use. To do so, use the dropdown box to select the field that the condition will be based on. Now that the field is selected, you』ll need to set the operator used to compare the field and value. For example, if you only want to send this notification if a particular radio button is checked, you would select is within the operator dropdown. Conversely, if you do not want a notification to be sent when that radio button field is selected, you would use is not. Finally, you』ll need to set the value that will be used to compare against the field submission result. If using pre-selected options, this will appear as a dropdown. If the field is something like a text field where the user will enter their own value, the condition value will appear as a text box. Within the condition value, enter the value to compare with the submission. If you want to add additional conditions or remove a condition, use the + and – icons to the right of the condition item to either add or remove it.

You can now continue configuring your notification as seen fit.

Troubleshooting

If Routing rules are not working as you expected there is a high likelihood that you』re facing one of the following:

You added or modified field values after configuring Routing. Routing rules are based on existing values when you saved them, if you use a choices field like a Drop Down for your Routing rules, and you change any of these field choices after configuring Routing, you need to update your Routing rules to select the new or modified choice(s) and save your notification settings. It doesn』t matter if you just changed a single character, any change done to choices used in your Routing rules matters. The following screenshot shows an example of an outdated Routing rule, when it was configured the choice selected was Jim, but currently, that choice no longer exists, the Drop Down was edited and Jim was replaced by Samuel, therefore, the Routing rule will not work. Your routing rules are not covering all the possible user selection. If your Routing rules are based on a drop down that has three choices, but you only have Routing rules added for two of the choices, the notification will fail when the user selects the third choice without a matching Routing rule.

Enable Editing of the Entry Payment Details

Enable Editing of the Entry Payment Details

The payment details panel on the entry detail page is usually only displayed when the entry was processed by a payment add-on. The ability to edit the payment details on this panel is usually only available when the entry was processed by the PayPal Standard add-on and the current payment status is set to Processing or Pending.
The following will allow you to enable the display of the payment details panel on the entry detail page and allow editing of those details for entries which were not processed by a payment add-on. Editing of Payment Details for entries already processed by a payment add-on is not supported.
For Gravity Forms 2.0 and newer you can use the Enable Gravity Forms Payment Details plugin.
For Gravity Forms versions older than 2.0, use the snippet below:
class RW_GF_Edit_Payment_Details {

public function __construct( $form_ids = array() ) {
if ( ! empty( $form_ids ) ) {
$this->_form_ids = $form_ids;
add_action( 'gform_loaded', array( $this, 'init' ) );
}
}

function init() {
if ( ! property_exists( 'GFForms', 'version' ) || ! version_compare( GFForms::$version, '1.9', '>=' ) ) {
return;
}

//add actions to allow the payment details to be modified
add_action( 'gform_payment_status', array( $this, 'admin_edit_payment_status' ), 10, 3 );
add_action( 'gform_payment_date', array( $this, 'admin_edit_payment_date' ), 10, 3 );
add_action( 'gform_payment_transaction_id', array( $this, 'admin_edit_payment_transaction_id' ), 10, 3 );
add_action( 'gform_payment_amount', array( $this, 'admin_edit_payment_amount' ), 10, 3 );
add_action( 'gform_after_update_entry', array( $this, 'admin_update_payment' ), 10, 2 );
add_action( 'gform_entries_first_column_actions', array( $this, 'maybe_set_payment_status' ), 10, 4 );

add_filter( 'gform_enable_entry_info_payment_details', '__return_false' );
}

public function maybe_set_payment_status( $form_id, $field_id, $value, $entry ) {
// payment details panel won't be displayed unless payment_status has a value
// only set the payment status when the entry is listed on the entries list page
// only set the payment status if its not already set and if it is the form we want
if ( rgempty( 'payment_status', $entry ) && in_array( $form_id, $this->_form_ids ) ) {
GFAPI::update_entry_property( $entry['id'], 'payment_status', 'Processing' );
}
}

public function admin_edit_payment_status( $payment_status, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_status;
}

//create drop down for payment status
$payment_string = '';

return $payment_string;
}

public function admin_edit_payment_date( $payment_date, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_date;
}

$payment_date = $entry['payment_date'];
if ( empty( $payment_date ) ) {
$payment_date = gmdate( 'y-m-d H:i:s' );
}

$input = '';

return $input;
}

public function admin_edit_payment_transaction_id( $transaction_id, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $transaction_id;
}

$input = '';

return $input;
}

public function admin_edit_payment_amount( $payment_amount, $form, $entry ) {
if ( $this->payment_details_editing_disabled( $entry ) ) {
return $payment_amount;
}

if ( empty( $payment_amount ) ) {
$payment_amount = GFCommon::get_order_total( $form, $entry );
}

$input = '';

return $input;
}

public function admin_update_payment( $form, $entry_id ) {
check_admin_referer( 'gforms_save_entry', 'gforms_save_entry' );

//update payment information in admin, need to use this function so the lead data is updated before displayed in the sidebar info section
$entry = GFFormsModel::get_lead( $entry_id );

if ( $this->payment_details_editing_disabled( $entry, 'update' ) ) {
return;
}

//get payment fields to update
$payment_status = rgpost( 'payment_status' );
//when updating, payment status may not be editable, if no value in post, set to lead payment status
if ( empty( $payment_status ) ) {
$payment_status = $entry['payment_status'];
}

$payment_amount = GFCommon::to_number( rgpost( 'payment_amount' ) );
$payment_transaction = rgpost( 'custom_transaction_id' );
$payment_date = rgpost( 'payment_date' );
if ( empty( $payment_date ) ) {
$payment_date = gmdate( 'y-m-d H:i:s' );
} else {
//format date entered by user
$payment_date = date( 'Y-m-d H:i:s', strtotime( $payment_date ) );
}

global $current_user;
$user_id = 0;
$user_name = 'System';
if ( $current_user && $user_data = get_userdata( $current_user->ID ) ) {
$user_id = $current_user->ID;
$user_name = $user_data->display_name;
}

$entry['payment_status'] = $payment_status;
$entry['payment_amount'] = $payment_amount;
$entry['payment_date'] = $payment_date;
$entry['transaction_id'] = $payment_transaction;

//update lead, add a note
GFAPI::update_entry( $entry );
GFFormsModel::add_note( $entry['id'], $user_id, $user_name, sprintf( __( 'Payment information was manually updated. Status: %s. Amount: %s. Transaction Id: %s. Date: %s', 'gravityformspaypal' ), $entry['payment_status'], GFCommon::to_money( $entry['payment_amount'], $entry['currency'] ), $payment_transaction, $entry['payment_date'] ) );
}

public function payment_details_editing_disabled( $entry, $action = 'edit' ) {
$gateway = gform_get_meta( $entry['id'], 'payment_gateway' );

if ( ! empty( $gateway ) ) {
// Entry was processed by a payment add-on, don't allow editing.
return true;
}

if ( rgar( $entry, 'payment_status' ) != 'Processing' ) {
// Editing not allowed for this entry.
return true;
}

if ( $action == 'edit' && rgpost( 'screen_mode' ) == 'edit' ) {
// Editing is allowed for this entry.
return false;
}

if ( $action == 'update' && rgpost( 'screen_mode' ) == 'view' && rgpost( 'action' ) == 'update' ) {
// Updating the payment details for this entry is allowed.
return false;
}

// In all other cases editing is not allowed.

return true;
}

}

// pass in an array of form ids you want to allow editing the payment details for
new RW_GF_Edit_Payment_Details( array( 11, 407, 48 ) );

The code snippet would go in your theme functions.php file or a custom functionality plugin.

Dynamic Field Map Field

Dynamic Field Map Field

IntroductionParametersExampleValidationHelpersget_dynamic_field_map_fields()Uses

Introduction

The dynamic_field_map type field, part of the Settings API, allows the user to map their form fields to custom keys (fields), e.g. fields you will be sending to a third-party service such as a CRM.

Parameters

name string Required. Name of the field. Use it to retrieve saved data.label string Required. Field label. Will be displayed in the UItype string Required. Field type. Must be set to dynamic_field_map for the Dynamic Field Map field.tooltip string Optional. Defaults to blank (no tooltip). Displays a question mark icon and a tooltip next to the field label.field_types arrayOptional. Defaults to empty (no filtering). Array of form field types to be available as options when mapping to this field. Only form fields of the specified types will be included in the list of fields.Example: array( 『text』, 『name』 )exclude_field_types arrayOptional. Defaults to empty (no filtering). Array of form field types to be excluded when mapping to this field.Example: array( 『creditcard』 )field_map arrayOptional. Defaults to empty.By default, the Dynamic Field Map allows users to enter a custom key and map that key to a form field (using the associated form field drop down).The field_map property allows the Key field to be presented as a drop down list, where users can select from a set of predefined choices.Each item in the field_map array has the following propertieslabel stringRequired. Choice label to be displayed in the key drop down.value stringOptional. Defaults to the Label value. Value that will be saved.

choices arrayOptional. Defaults to empty.Creates an option group in the drop down. The label property becomes the Option Group label and the choices defined here become the options under the new group.Each item in the choices array has the following propertieslabel stringRequired. Choice label that is displayed in the drop down.value stringOptional. Defaults to the Label text. Value that is saved.limit int Optional. Defaults to no limit. Defines the number of fields that can be mapped by the user.enable_custom_key boolOptional. Defaults to false. Possible values are true or false. When set to true, allows users to enter a custom value in addition to the options in the drop down field.validation_callback (function)Optional. Defaults to nothing (no callback). Calls a function during validation allow for custom validation logic. The example in the existing documentation page is good.allow_duplicate boolOptional. Defaults to false. Controls whether or not the same option in the key field can be mapped multiple times.Note: This only prevents options from being selected multiple times in the drop down. If custom keys are enabled, users won』t be prevented from typing the same custom option multiple times.

Example

The following example shows how you can allow the user to define a number of custom keys and map them to their form fields, which in this case is limited to twenty. We are also excluding the creditcard field from the drop downs which contain the form fields as choices.

array(
'title' => esc_html__( 'This is the title for Section 1', 'sometextdomain' ),
'fields' => array(
array(
'name' => 'metaData',
'label' => esc_html__( 'Metadata', 'sometextdomain' ),
'type' => 'dynamic_field_map',
'limit' => 20,
'exclude_field_types' => 'creditcard',
'tooltip' => '

' . esc_html__( 'Metadata', 'sometextdomain' ) . '

' . esc_html__( 'You may send custom meta information to [...]. A maximum of 20 custom keys may be sent. The key name must be 40 characters or less, and the mapped data will be truncated to 500 characters per requirements by [...]. ', 'sometextdomain' ),
'validation_callback' => array( $this, 'validate_custom_meta' ),
),
),
),

The above code would render a field like the following:

Validation

In the above example a validation callback is also specified to ensure that the limit is not exceeded and that the custom keys don』t exceed the character limit defined by the third-party service.

public function validate_custom_meta( $field ) {
//Number of keys is limited to 20 - interface should control this, validating just in case
//key names can only be max of 40 characters

$settings = $this->get_posted_settings();
$metaData = $settings['metaData'];

if ( empty( $metaData ) ) {
return;
}

//check the number of items in metadata array
$metaCount = count( $metaData );
if ( $metaCount > 20 ) {
$this->set_field_error( array( esc_html__( 'You may only have 20 custom keys.' ), 'sometextdomain' ) );

return;
}

//loop through metaData and check the key name length (custom_key)
foreach ( $metaData as $meta ) {
if ( empty( $meta['custom_key'] ) && ! empty( $meta['value'] ) ) {
$this->set_field_error( array( 'name' => 'metaData' ), esc_html__( "A field has been mapped to a custom key without a name. Please enter a name for the custom key, remove the metadata item, or return the corresponding drop down to 'Select a Field'.", 'sometextdomain' ) );
break;
} elseif ( strlen( $meta['custom_key'] ) > 40 ) {
$this->set_field_error( array( 'name' => 'metaData' ), sprintf( esc_html__( 'The name of custom key %s is too long. Please shorten this to 40 characters or less.', 'sometextdomain' ), $meta['custom_key'] ) );
break;
}
}
}

Helpers

The following functions may come in helpful when interacting with the dynamic_field_map field type during feed processing.

get_dynamic_field_map_fields()

Retrieves the individual field_map fields from the meta property of the Feed Object for the supplied field name.

$metaData = $this->get_dynamic_field_map_fields( $feed, 'metaData' );

$feed Feed Object
The Entry Object to be checked.

$name string
The name property of the dynamic_field_map field to retrieve the mapped fields for.

Returns array
An array containing the field names or custom keys as the keys to the mapped form field ID or entry meta key.

Uses

settings_dynamic_field_map()

Setting Up the Emma Add-On

Setting Up the Emma Add-On

Pre-RequisitesSetup

Pre-Requisites

Download and install the add-on
An Emma account

Setup

Log into your WordPress admin dashboard.
On the left side navigation menu, hover over Forms and click on Settings.
From this page, click the Emma tab.
Enter your Public API Key, Private API Key, and Account ID. Your Emma API account information can be found by logging into your Emma account. Go to your Account Settings page and access your API key information. Please be aware that the Private API Key will only be displayed the first time it is generated by Emma, so be sure to copy-n-paste the Private API Key as soon as it is displayed.
Click Update Settings. If you』ve entered your account information correctly, you will be notified by green check marks beside each box. If you do not see green check marks, please double check this information and try again.

Once you have entered your API key, you』re ready to begin creating a feed for the Emma Add-On.

Email Tracking with Mailgun

Email Tracking with Mailgun

In addition to being able to send your notifications using Mailgun, the Mailgun Add-On also includes the ability to integrate with Mailgun』s email tracking. With email tracking, you』ll be able to see if the notification was opened or links were clicked, allowing for better management of your notifications. In this article, we』ll show you how to enable email tracking in the Mailgun add-on for Gravity Forms.

Access the form notification that is configured to use Mailgun. If you don』t already have a notification that is using Mailgun, see our article on sending form notifications with Mailgun.Scroll down in the settings until you see an option labeled Email Tracking.To enable tracking of link clicks, check the checkbox labeled Enable click tracking for this notification.To enable tracking of who has opened your form notifications, check the checkbox labeled Enable open tracking for this notification.Once complete, save your notification settings.

That』s all there is to it! With tracking settings enabled, you will be able to better track if a form notification is opened or a link within the notification is clicked.

Dynamically Populating Drop Down, Radio Buttons or Multi-Select Fields

Dynamically Populating Drop Down, Radio Buttons or Multi-Select Fields

IntroductionThird Party OptionsCustom Code ApproachThe CodeThe HooksCustom Filter FunctionLooping Through the FieldsGet the PostsCreating an Array of ChoicesAdd a Placeholder ChoiceWhat about Checkboxes?Conclusion

Introduction

Being able to dynamically populate the values in a select (aka drop down) field is fairly common requirement for product selection forms, product option forms, or any form that requires earlier submissions to drive choices in a latter collection field.

This walkthrough will teach you how to configure a specific example of this population, using custom code to present a list of existing posts as options in the drop down.

Third Party Options

If you are not keen on custom code, or require more complex capabilities, check for third party solutions across popular WordPress Plug-In repositories, and in our very own Community Add-On Library.

Make sure you don』t miss the Add-On Populate Anything, a fully-featured offering from one of our Certified Developers, GravityWiz.

Custom Code Approach

The premise for this walkthrough is that we want to populate the options in a Gravity Form select field with all of the posts currently published on the site. There are a variety of reasons for wanting to do this, but in this example, we just want to know what the user』s favorite post is.

IMPORTANT: For obvious reasons, dynamic population can』t run when the page where your form is embedded is cached. This is not a Gravity Forms limitation but a consequence of using caching.

The Code

123456789101112131415161718192021222324252627282930add_filter( 'gform_pre_render_51', 'populate_posts' );add_filter( 'gform_pre_validation_51', 'populate_posts' );add_filter( 'gform_pre_submission_filter_51', 'populate_posts' );add_filter( 'gform_admin_pre_render_51', 'populate_posts' );function populate_posts( $form ) {     foreach ( $form['fields'] as &$field ) {         if ( $field->type != 'select' || strpos( $field->cssClass, 'populate-posts' ) === false ) {            continue;        }         // you can add additional parameters here to alter the posts that are retrieved        // more info: http://codex.wordpress.org/Template_Tags/get_posts        $posts = get_posts( 'numberposts=-1&post_status=publish' );         $choices = array();         foreach ( $posts as $post ) {            $choices[] = array( 'text' => $post->post_title, 'value' => $post->post_title );        }         // update 'Select a Post' to whatever you'd like the instructive option to be        $field->placeholder = 'Select a Post';        $field->choices = $choices;     }     return $form;}

This code should be pasted in your theme』s functions.php file.

The Hooks

Using the gform_pre_render filter allows us to modify the form right before it is displayed. This is really useful, especially when you are looking to display content that will be constantly changing. In our case, this saves us the time and hassle of having to update our drop down of posts every time we add a new post. In addition you should use the gform_pre_validation, gform_pre_submission_filter and gform_admin_pre_render filters as well.

1234add_filter( 'gform_pre_render_51', 'populate_posts' );add_filter( 'gform_pre_validation_51', 'populate_posts' );add_filter( 'gform_pre_submission_filter_51', 'populate_posts' );add_filter( 'gform_admin_pre_render_51', 'populate_posts' );

This line tells Gravity Forms to filter the $form object through the populate_posts function every time the form with ID of 51 is displayed. You should update the 51 here to the ID of your form.

Please note: A form-specific version of the gform_pre_validation filter was added in Gravity Forms version 1.9.

Next, let』s create a populate_posts function to modify our form.

Custom Filter Function

In this example, our custom filter function is titled 「populate_posts」. Since we told Gravity Forms to call this function from the gform_pre_render filter, Gravity Forms will also send the $form object as a parameter to this function. This means we can modify the $form object with this function and then return our changes at the end of the function.

Looping Through the Fields

1foreach ( $form['fields'] as $field ) { ... }

Since we have the $form object, let』s loop through the fields in the form and find the field(s) that we』d like to modify.

123if ( $field->type != 'select' || strpos( $field->cssClass, 'populate-posts' ) === false ) {    continue;}

Given our premise, we only want to modify fields that are select (drop down) fields AND have a CSS class titled 「populate-posts」. We could check for the field ID instead of a CSS class; however, if we ever change our form we』d have to update the code to match the new field ID. Using a CSS class to identify our desired field allows us to manage which field should be targeted right from the Gravity Forms admin.

If the current field we are at in the loop is not a select OR does not have our designated CSS class, we simply skip that field and move on to the next.

Get the Posts

Now it』s time to get an array of all the posts to display in our drop down.

1$posts = get_posts( 'numberposts=-1' );

get_posts() is a WordPress function that returns an array of posts based on the parameters you provide it. For more information on how to modify which posts are returned, read here.

Quick Tip: You can retrieve any kind of post type here; even custom post types. Just pass the name of your post type with the 「post_type」 parameter:

1$posts = get_posts( 'post_type=event&numberposts=-1' );

Creating an Array of Choices

The way Gravity Forms handles fields with multiple options (such as a select field) is with a 「choices」 property for the field which contains an array of 「options」. Each option consists of:

a 「text」 property (which is what the user will see in the drop down)a 「value」 property (which is what will be recorded by Gravity Forms)an 「isSelected」 property (which is used to indicate whether the option is currently selected or not)and a 「price」 property (which only applies to pricing fields)

In our scenario, we are only concerned with the 「text」 and 「value」 properties.

1$choices = array();

The first thing we do is create an array to store all of our options.

123foreach ( $posts as $post ) {    $choices[] = array( 'text' => $post->post_title, 'value' => $post->post_title );}

Next, we』re going to loop through the posts we retrieved using the get_posts() function and create an option array for each post. For the 「text」 property we will use the Post Title and for the 「value」 property we will use the same. In some cases you may want to collect the ID of the selected post. If so you』d use $post->ID instead of $post->post_title; however, for our goal of recording the users favorite post, the post title is sufficient.

1$field->choices = $choices;

Once we』ve looped through all of the posts and created all of our options, we assign the $choices array (which has all of our new options) to the $field choices property.

Add a Placeholder Choice

1$field->placeholder = 'Select a Post';

We also want to make the first option in the drop down a 「placeholder」 choice. It let』s the user know what they are supposed to do with this drop down (ie 「Select a Post」). We do this by assigning the choice text to the fields placeholder property.

When the drop down is rendered on the form the placeholder choice will have an empty value for the 「value」 property. This ensures that if this is a required field, that the user must select an option other than the placeholder option. Failing to do so will generate a validation error.

What about Checkboxes?

Checkbox fields can also be dynamically populated, but they require additional handling since their structure is created by a fieldset of inputs and choices. See this example code for Dynamically Populating a Checkbox as included in our gform_pre_render documentation.

Conclusion

That』s all there is to it! When you view your form on the front end you should now see that your select field is populated with a list of all your current posts.

Emma Change Log

Emma Change Log

1.5 | 2021-05-071.4 | 2020-09-211.3 | 2020-03-171.2 | 2017-04-281.1 | 2015-08-261.0 | 2015-04-29

1.5 | 2021-05-07

Fixed a deprecation notice with PHP 8.

1.4 | 2020-09-21

Added support for Gravity Forms 2.5.

1.3 | 2020-03-17

Added translations for Hebrew, Hindi, Japanese, and Turkish.
Added additional logging statements.
Updated the order of the API settings on the Forms > Settings > Emma page.
Updated API library to public property in support of Emma block.
Fixed PHP 7.4 notices which occur when the API is initializing and the settings are empty.
Fixed a PHP 7.4 notice which occurs on the feed configuration page when saving a new feed.
Fixed a fatal error which can occur if the Emma class is included by another plugin.

1.2 | 2017-04-28

Added security enhancements.
Added translations.
Added feed duplication support.
Fixed strings for translations

1.1 | 2015-08-26

Added support for delaying feed processing until payment by PayPal Standard is successfully completed.
Added gf_emma() for easily getting an Emma instance.
Added Spanish (es_ES) translation.
Updated 'Opt-In Condition' setting label to 'Conditional Logic'.
Updated feed processing to use get_field_value() when retrieving mapped field values, enabling support for GF_Field::get_value_export with GF 1.9.12.4 and later.
Updated feed processing to abort if email is empty or invalid.
Fixed PHP notice caused by Add-On Framework change in Gravity Forms 1.9.10.19.

1.0 | 2015-04-29

It's all new!

Drop Down Field CSS Selectors

Drop Down Field CSS Selectors

ContainerSelect BoxItems

If you』ve enabled the Enhanced UI option, you will need to target 「.chosen-container」 CSS class rather than 「.ginput_container_select」 in the selectors below.
Container
example: standard drop-down container (div) – applies to all forms
body .gform_wrapper .gform_body .gform_fields .gfield .ginput_container_select {border: 1px solid red}
example: standard drop-down container (div) – applies just to form ID #1
body #gform_wrapper_1 .gform_body .gform_fields .gfield .ginput_container_select {border: 1px solid red}
example: standard drop-down container (div) – applies just to specific drop-down field (based on the unique parent element ID – replace 「XX_X」 with your actual element ID)
body .gform_wrapper .gform_body .gform_fields #field_XX_X.gfield .ginput_container_select {border: 1px solid red}
Select Box
example: standard drop-down field (select) – applies to all forms
body .gform_wrapper .gform_body .gform_fields .gfield select {border: 1px solid red}
example: standard drop-down field (select) – applies just to form ID #1
body #gform_wrapper_1 .gform_body .gform_fields .gfield select {border: 1px solid red}
example: standard drop-down field (select) – applies just to specific drop-down field (based on the unique parent element ID – replace 「XX_X」 with your actual element ID)
body .gform_wrapper .gform_body .gform_fields #field_XX_X.gfield select {border: 1px solid red}
Items
example: standard drop-down item (option) – applies to all forms
body .gform_wrapper .gform_body .gform_fields .gfield select option {color: red}
example: standard drop-down item (option) – applies just to form ID #1
body #gform_wrapper_1 .gform_body .gform_fields .gfield select option {color:red}
example: standard drop-down item (option) – applies just to specific drop-down field (based on the unique parent element ID – replace 「XX_X」 with your actual element ID)
body .gform_wrapper .gform_body .gform_fields #field_XX_X.gfield select option {color: red}

Does Gravity Forms Support ….

Does Gravity Forms Support ….

You can embed the Gravity Forms shortcode anywhere within your WordPress site, independently from other plugins. But to talk effectively and get closer integration between Gravity Forms and a third party service, we recommend:

Our library of community supported third-party plug-ins, which contains hundreds of solutions for enhancing and extending Gravity Forms.
Using Zapier to link with other services

Examples:
– does Gravity Forms support WooCommerce?
– does Gravity Forms support SalesForce?
– does Gravity Forms support my payment gateway?

Disabling Automatic Scrolling On Form Confirmations

Disabling Automatic Scrolling On Form Confirmations

Use the gform_confirmation_anchor FilterDisabling Automatic Scrolling On a Specific FormDisabling Automatic Scrolling On All Forms

When a form is submitted, the default behavior of Gravity Forms is to scroll to the confirmation message. In the vast majority of cases, this is the desired behavior, but in a few scenarios, you may want to disable this functionality.
Use the gform_confirmation_anchor Filter
Gravity Forms makes it incredibly easy to remove this functionality by providing an easy to use filter.
This filter will be used either within its own plugin (ideally) or within your theme』s functions.php file.
Note: Placing modifications within your own plugin is recommended simply because it makes your changes immune to theme updates. If placed within your theme, your changes could be overwritten by theme updates.
Disabling Automatic Scrolling On a Specific Form
To disable automatic scrolling on a specific form, use the gform_confirmation_anchor filter like so, replacing # with the form ID:
add_filter( 'gform_confirmation_anchor_#', '__return_false' );

Disabling Automatic Scrolling On All Forms
Disabling automatic scrolling on all forms is just as easy as disabling it on a specific form. Use the filter like the following:
add_filter( 'gform_confirmation_anchor', '__return_false' );