How to Display Form Entries

Overview

Would you like to display the form entries on your site so that your visitors can easily see them? WPForms is set up with security in mind, so by default, only WordPress admin users will be able to see entry data. This tutorial will walk you through how to use PHP to create a shortcode to display your form entries on a page for non-admin users.

Setup

This code doesn’t require any changes, and is ready to be added to your site.

1) Creating the shortcode

First, you’ll need to create the shortcode so that it can be used on any page, post or widget area on your site.

/**
 * Custom shortcode to display WPForms form entries.
 *
 * Basic usage: [wpforms_entries_table id="FORMID"].
 * 
 * Possible shortcode attributes:
 * id (required)  Form ID of which to show entries.
 * user           User ID, or "current" to default to current logged in user.
 * fields         Comma seperated list of form field IDs.
 * number         Number of entries to show, defaults to 30.
 * 
 * @link https://wpforms.com/developers/how-to-display-form-entries/
 *
 * @param array $atts Shortcode attributes.
 * 
 * @return string
 */
function wpf_entries_table( $atts ) {

	// Pull ID shortcode attributes.
	$atts = shortcode_atts(
		[
			'id'     => '',
			'user'   => '',
			'fields' => '',
			'number' => '',
		],
		$atts
	);

	// Check for an ID attribute (required) and that WPForms is in fact
	// installed and activated.
	if ( empty( $atts['id'] ) || ! function_exists( 'wpforms' ) ) {
		return;
	}

	// Get the form, from the ID provided in the shortcode.
	$form = wpforms()->form->get( absint( $atts['id'] ) );

	// If the form doesn't exists, abort.
	if ( empty( $form ) ) {
		return;
	}

	// Pull and format the form data out of the form object.
	$form_data = ! empty( $form->post_content ) ? wpforms_decode( $form->post_content ) : '';

	// Check to see if we are showing all allowed fields, or only specific ones.
	$form_field_ids = ! empty( $atts['fields'] ) ? explode( ',', str_replace( ' ', '', $atts['fields'] ) ) : [];

	// Setup the form fields.
	if ( empty( $form_field_ids ) ) {
		$form_fields = $form_data['fields'];
	} else {
		$form_fields = [];
		foreach ( $form_field_ids as $field_id ) {
			if ( isset( $form_data['fields'][ $field_id ] ) ) {
				$form_fields[ $field_id ] = $form_data['fields'][ $field_id ];
			}
		}
	}

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

	// Here we define what the types of form fields we do NOT want to include,
	// instead they should be ignored entirely.
	$form_fields_disallow = apply_filters( 'wpforms_frontend_entries_table_disallow', [ 'divider', 'html', 'pagebreak', 'captcha' ] );

	// Loop through all form fields and remove any field types not allowed.
	foreach ( $form_fields as $field_id => $form_field ) {
		if ( in_array( $form_field['type'], $form_fields_disallow, true ) ) {
			unset( $form_fields[ $field_id ] );
		}
	}

	$entries_args = [
		'form_id' => absint( $atts['id'] ),
	];

	// Narrow entries by user if user_id shortcode attribute was used.
	if ( ! empty( $atts['user'] ) ) {
		if ( $atts['user'] === 'current' && is_user_logged_in() ) {
			$entries_args['user_id'] = get_current_user_id();
		} else {
			$entries_args['user_id'] = absint( $atts['user'] );
		}
	}

	// Number of entries to show. If empty, defaults to 30.
	if ( ! empty( $atts['number'] ) ) {
		$entries_args['number'] = absint( $atts['number'] );
	}

	// Get all entries for the form, according to arguments defined.
	// There are many options available to query entries. To see more, check out
	// the get_entries() function inside class-entry.php (https://a.cl.ly/bLuGnkGx).
	$entries = wpforms()->entry->get_entries( $entries_args );

	if ( empty( $entries ) ) {
		return '<p>No entries found.</p>';
	}

	ob_start();

	echo '<table class="wpforms-frontend-entries">';

		echo '<thead><tr>';

			// Loop through the form data so we can output form field names in
			// the table header.
			foreach ( $form_fields as $form_field ) {

				// Output the form field name/label.
				echo '<th>';
					echo esc_html( sanitize_text_field( $form_field['label'] ) );
				echo '</th>';
			}

		echo '</tr></thead>';

		echo '<tbody>';

			// Now, loop through all the form entries.
			foreach ( $entries as $entry ) {

				echo '<tr>';

				// Entry field values are in JSON, so we need to decode.
				$entry_fields = json_decode( $entry->fields, true );

				foreach ( $form_fields as $form_field ) {

					echo '<td>';

						foreach ( $entry_fields as $entry_field ) {
							if ( absint( $entry_field['id'] ) === absint( $form_field['id'] ) ) {
								echo apply_filters( 'wpforms_html_field_value', wp_strip_all_tags( $entry_field['value'] ), $entry_field, $form_data, 'entry-frontend-table' );
								break;
							}
						}

					echo '</td>';
				}

				echo '</tr>';
			}

		echo '</tbody>';

	echo '</table>';

	$output = ob_get_clean();

	return $output;
}
add_shortcode( 'wpforms_entries_table', 'wpf_entries_table' );

2) Using the shortcode

To display entries in a page or post, you’ll need to use the following shortcode, where FORMID is replaced with the form’s ID number:

[wpforms_entries_table id="FORMID" number="20"]

A form’s ID number can be found by going to WPForms » All Forms and looking to the number in the shortcode for each form.

How to locate your form ID

For this example, we’ll modify the shortcode to use the form with an ID of 51:

[wpforms_entries_table id="51" number="20"]

The number="20" will show the first 20 entries. If you want to show all entries, change the 20 to 9999.

The styling of your entry table will vary depending on the default styling your theme may or may not have for tables.

And that’s it, you’ve now created a shortcode that can be added in various places on your site so that you can display your form entries to non-admin users. Would you also like to display how many entries are left on your form when using the Form Locker addon? Try out our code snippet for How to Display Remaining Entry Limit Number.

Filter Reference: wpforms_html_field_value

FAQ

Q: Is there any way to make the table look better?

A: By default, the styling will come from your theme. You can add some additional CSS if you’d like to make the form look a little nicer.

table {
    border-collapse: collapse;
}

thead tr {
    height: 60px;
}

table, th, td {
    border: 1px solid #000000;
}

td {
    white-space: normal;
    max-width: 33%;
    width: 33%;
    word-break: break-all;
    height: 60px;
    padding: 10px;
}
tr:nth-child(even) {
    background: #ccc
}

tr:nth-child(odd) {
    background: #fff
}

Add stying to your form entries table

Q: How would I pass through the User ID?

A: In order to show only the entries for a particular user ID, the user would first need to be logged in.

[wpforms_entries_table id="FORMID" user="USERID"]

Just remember to make sure the FORMID and USERID be changed to match the correct ID numbers.