Search for keywords, like "PayPal", "Recurring Donations", and more.

Documentation / Developer Docs / How to Create Custom Form Fields

How to Create Custom Form Fields

GiveWP has a built-in Fields API for programmatically adding fields with just a few lines of code. This article walks developers through that process, and outlines how the Fields API simplifies the process of customizing Donation forms on your WordPress site. 

Note: Looking for a non-code method to add form fields? Check out the Form Field Manager Add-on for a quick and easy way to add custom form fields. This document is for developers. The code snippets below can be added using any method outlined in the documentation about adding custom PHP to your WordPress website.

Why add custom fields?

By default, GiveWP collects name, email, and donation amount on each donation, and that information is stored in a combination of Donor and Donation meta within the WordPress database.

The ability to add custom fields programmatically opens up new functionality for developers looking to extend GiveWP. 

For example, at the time of this writing, if you want to gather custom data on a donation form that is mapped to the Donor meta (as opposed to Donation meta) there’s not a method to do that from within the UI or using an add-on. So, information like “t-shirt size” or “contact phone number” that doesn’t generally change from one donation to the next could be added to the Donor meta using the Fields API.

Any data that’s not gathered by default can be collected using the Fields API, even on a hidden field. 

Groups and Fields

Individual custom fields are grouped into “groups” and then form templates use those groups to display the fields relative to one another. 

Default fields like name, email, and billing address are not currently in defined groups, and that may change as GiveWP moves toward a more modular form building interface. Development priority is to maintain backward compatibility for existing form templates as we move in a more modular direction.

To use the Fields API, you need to specify a group (or create a new one) and then define the characteristics of the field you want to add to it. Then the API passes that along to the Form Template for display on the front end of the site.

Form Locations

When you add a field, you first pick a location on the form, defined by the following hooks. Essentially you are saying to the API “create a group on one of these hooks” and you can either append to an existing collection that is already defined on that hook, or add a new one.

Note: while all of these hooks will work for the foreseeable future, there are some that are too vague and will likely be deprecated in future versions of the plugin. Pay attention to deprecation notices in PHP error logs, and also this documentation will be updated.

  • give_fields_before_donation_levels
  • give_fields_after_donation_amount
  • give_fields_after_donation_levels
  • give_fields_payment_mode_top
  • give_fields_payment_mode_before_gateways
  • give_fields_payment_mode_after_gateways
  • give_fields_payment_mode_after_gateways_wrap
  • give_fields_payment_mode_bottom
  • give_fields_donation_form
  • give_fields_donation_form_top
  • give_fields_purchase_form_top
  • give_fields_donation_form_register_login_fields
  • give_fields_donation_form_before_cc_form
  • give_fields_cc_form
  • give_fields_before_cc_fields
  • give_fields_before_cc_expiration
  • give_fields_after_cc_expiration
  • give_fields_after_cc_fields
  • give_fields_donation_form_after_cc_form
  • give_fields_purchase_form_bottom
  • give_fields_donation_form_before_personal_info
  • give_fields_donation_form_after_personal_info

Note: while all of these hooks will work for the foreseeable future, there are some that too vague and will likely be deprecated in future versions of the plugin.

Example One: Simple Text Field

The code in this example will demonstrate how to add a simple text field.

Adding a simple text field

add_action( 'give_fields_after_donation_amount', function( $group ) {
    $group->append(
        give_field( 'text', 'mothersName' )
            ->showInReceipt()
            ->minLength(2)
            ->label( __( 'Mother\'s Name' ))
            ->maxLength(30)
            ->placeholder('Mother\'s name') 
            ->storeAsDonorMeta()
            ->required() // Could instead be marked as readOnly() (optional)
            ->helpText( __( 'This is a field used to add your mother\'s name' ) ) //how this is displayed is up to the template, but if the template has help text displayed, this is how to set it.
    );
});

The field added has the following characteristics:

  • Its label is What’s your mother’s name?
  • It should appear in the donation receipt
  • Its minimum length is 2 characters
  • Its maximum length is 30 characters
  • The placeholder for the field is Mother’s name
  • It should be stored as donor meta
  • It’s a required field
  • Its help text is This is a field used to add your mother\’s name

This code will generate a field for your donation form that will look like the following:

Example Two: Select Field

The following code snippet adds a select (dropdown) field to all forms on the site:

Adding a select (dropdown) field

add_action( 'give_fields_after_donation_levels', function( $collection ) {
    $collection->append(
        // Select field with options.
        give_field( 'select', 'myConference' )
            ->options(
                [ 'east', __( 'Eastern Conference' ) ],
                [ 'west', __( 'Western Conference' ) ],
                [ 'north', __( 'Northern Conference' ) ],
            )
            ->label( __('conference'))
    );
});

This code generates the following form:

Example Three: A custom field added to donor meta

The following code snippet creates a field where the data is stored to Donor meta, as opposed to Donation meta.

Custom field added to donor meta

add_action( 'give_fields_after_donation_amount', function( $collection ) {
    $collection->append(
        give_field( 'text', 'Birth City' )
            ->showInReceipt()
            ->label( __('Birth City') )
            ->minLength(2)
            ->maxLength(30)
            ->placeholder('Your birth city')
            ->storeAsDonorMeta()
            ->required() // Could instead be marked as readOnly() (optional)
            ->helpText( __( 'This is a field used to add your birth city.' ) )
    );
});

Example Four: A hidden field populated from a URL parameter

The following example adds a hidden field:

Add a hidden field

add_action( 'give_fields_after_donation_amount', function( $collection ) {
    $collection->append(
        give_field( 'hidden', 'donationSource' )
    );
});

You can populate that field with anything, programmatically based on donor behavior, device, etc. 

One way to programmatically populate that field would be with a query parameter on the URL itself, so that if a donor visits the form on a URL like https://example.com/?donationSource=springSocialCampaign, the hidden field would be populated with “springSocialCampaign.” 

Here’s a sample snippet for that:

Add query parameter to hidden field

add_action( 'give_donation_form_after_submit', function() { ?>
	//add script tag here
		let searchParams = new URLSearchParams(window.location.search);
		// Change the parameter name here
		let donationSource = searchParams.has('donationSource') ? searchParams.get('donationSource') : '';
		// Change the target variable here
		jQuery("input[name='donationSource']").prop("value", donationSource);
	//close script tag here
<?php } );

To wrap things up, let’s take a look at another example of how to create a custom field, display the field on the donation details page, and add the field to the donation history export page.

Display a Custom Field on the Donation Details Page and Add Field to Donation History Export

append(
        give_field( 'text', 'guestName' )
            ->showInReceipt()
            ->minLength(2)
            ->label( __( 'Donation on behalf of...' ))
            ->maxLength(30)
	    ->emailtag( 'guestName' )
            ->placeholder('Name of guest')
            ->required() // Could instead be marked as readOnly() (optional)
            ->helpText( __( 'This is a field used to add the guest name on behalf of whom you are donating' ) ) //how this is displayed is up to the template, but if the template has help text displayed, this is how to set it.
    );
});

/**
* This function displays custom field in the Donation details page in the backend. Add an if statement for each aditional field.
*/

function render_givewp_field_api_fields( $payment_id ) {

	$field_name = give_get_meta( $payment_id, 'guestName', true );

	if ( $field_name ) : ?>

		<div id="" class="postbox">
			<!--Replace 'Field Label' with a relevant label. -->
			<h3 class="handle"></h3>
			<div class="inside" style="padding-bottom:10px">
				
			</div>
		</div>

	<?php endif;

}

add_action( 'give_view_donation_details_billing_after', 'render_givewp_field_api_fields', 10, 1 );

/**
* This function adds the custom field as checkbox option in the Donation History Export page. Add a <li> element for each aditional field
*/
function export_option_givewp_field_api_fields() {
	?>
	<li>
		<label for="give-guestName">
			
		</label>
	</li>
	get_meta( 'guestName' );
		$data['guestName'] = isset( $guestName ) ? wp_kses_post( $guestName ) : '';
	}

	return $data;
}

add_filter( 'give_export_donation_data', 'export_givewp_field_api_fields', 10, 3 );

Conclusion

The Fields API is a step toward the future with GiveWP, enabling you and other third-party developers to extend GiveWP Donation forms in functionality without having to be concerned with markup or display. The Fields API is also documented with additional field types, options, and methods in the public GitHub repository

Last updated 1 year ago

Start Fundraising Better Today!

Get GiveWP Today
GiveWP Plans

Give Fundraising Newsletter

The Give Fundraising Newsletter will help you navigate the world of online fundraising like a pro. Each week we send out fundraising advice, Give LIVE announcements, and exclusive offers to our newsletter subscribers.