How to create custom form in WordPress and handle submission?

Form

There are cool plugins available that create forms without any programming effort but still many times we need to create custom forms in our WordPress website.

So where to start with? What should be the form action? And where do we handle form submission? How WordPress will detect our custom form is submitted?

These questions comes in mind when you set to go with development of custom form plugin. In this post I will answer all those questions and make you able to create custom form.

Plugin constructor:
First line of constructor method is to hook WordPress’s init function. This is useful for intercepting $_GET or $_POST triggers because init() runs after WordPress has finished loading but before any headers are sent. Hence this is where we will be processing our form submissions.

On second line we are registering a shortcode that we will be putting in pages to render our form. In this example the shortcode is ‘custom_form’. You will be putting [custom_form] wherever you want to put your custom form.

    public function __construct()
    {
        add_action('init', array($this, 'init'));
        add_shortcode('custom_form', array($this, 'shortcode_handler'));
    }

Inside the plugins init() we check if $_POST['nonce_custom_form'] is present? Presence of this field in $_POST data means our custom form is being submitted. So no need to put ‘action’ for our custom form, just put some hidden field with unique name and check it inside init function to intercept form submission. Next we verify the nonce for security purpose. After nonce verification we validate the form fields and process them.

    public function init()
    {
        if (!empty($_POST['nonce_custom_form']))
        {
            if (!wp_verify_nonce($_POST['nonce_custom_form'], 'handle_custom_form'))
            {
                die('You are not authorized to perform this action.');
            } else
            {
                $error = null;
                if (empty($_POST['name']))
                {
                    $error = new WP_Error('empty_error', __('Please enter name.', 'tahiryasin'));
                    wp_die($error->get_error_message(), __('CustomForm Error', 'tahiryasin'));
                }
                else
                    die('Its safe to do further processing on submitted data.');
            }
        }
    }

Lastly there is shortcode handler function that renders our form.

    function shortcode_handler($atts)
    {
        return "<form method='post' action=''>
    <input name='name' type='text' value='' />
    " . wp_nonce_field('handle_custom_form', 'nonce_custom_form') . "
        <input type='submit' value='Submit'/>
    </form>";
    }

Complete code:

<?php

/**
 * Plugin Name: Custom Form
 * Plugin URI: http://www.scriptbaker.com/
 * Description: Creates a custom form through shortcode and handles the submit event.
 * Version: 1.0
 * Author: Tahir Yasin
 * Author URI: http://www.scriptbaker.com/author/tahir/
 * License: GPL2
 */

class CustomForm
{

    public function __construct()
    {
        add_action('init', array($this, 'init'));
        add_shortcode('custom_form', array($this, 'shortcode_handler'));
    }

    public function init()
    {
        if (!empty($_POST['nonce_custom_form']))
        {
            if (!wp_verify_nonce($_POST['nonce_custom_form'], 'handle_custom_form'))
            {
                die('You are not authorized to perform this action.');
            } else
            {
                $error = null;
                if (empty($_POST['name']))
                {
                    $error = new WP_Error('empty_error', __('Please enter name.', 'tahiryasin'));
                    wp_die($error->get_error_message(), __('CustomForm Error', 'tahiryasin'));
                }
                else
                    die('Its safe to do further processing on submitted data.');
            }
        }
    }

    function shortcode_handler($atts)
    {
        return "<form method='post' action=''>
    <input name='name' type='text' value='' />
    " . wp_nonce_field('handle_custom_form', 'nonce_custom_form') . "
        <input type='submit' value='Submit'/>
    </form>";
    }

}

$CustomForm = new CustomForm();
?>

How to create custom form in WordPress? What should be the form action? And how to intercept form submission? This post will answer all these questions…

Author: Tahir Yasin

Tahir is a Passionate Web Developer from Lahore, Pakistan and a guy with NEVER-STOP-LEARNING attitude who keeps an eye on emerging technologies and customer trends.

3 thoughts on “How to create custom form in WordPress and handle submission?”

  1. Is there a way to create a processing file inside the plugin that creates a query and displays the results?

    i have the query and results setup, I’d like to make the user able to add shortcode like [display_results] in their theme.

    What do I set as the custom form action to send the results to the plugin file, not look for a file at the URL?

    1. Josh,
      First step is to store your data in database. You may create a custom post type, lets says “Inquiries” and each time the form is submitted you insert a new inquiry in database and store its meta data in wp_postmeta table.
      Second step is to fetch and display the Inquiries, lets say your custom post type name is “inquiry” you can fetch inquiries with below query

      $args = array(
          'post_type' => 'inquiry',
          'order' => 'ASC',
          'posts_per_page' => -1, // this will fetch all inquiries, removed it if you want pagination
      );
      
      $the_query = new WP_Query($args);
      if ($the_query->have_posts()) {
          while ($the_query->have_posts()) {
              $the_query->the_post();
              //display post data
          }
      }
      wp_reset_postdata();
      

      You can create shortcode and display results of above query inside the shortcode, remember you always return html from shortcode handler function and never output/echo html directly.

      I hope this will help you. Feel free to contact if you got any more questions.
      Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *