Add custom form to theme

There are few ways how to make you’r form visible on your site:

  • crate shortcode/widget with form
  • create page template

There are few ways how to process your form in php:

  • adding processing directly to php file of page template
  • adding processing in init/wp or any other action
  • adding processing in ajax actions

How i would do these:

  • create page template
  • insert form into it
  • enqueue scripts and styles for these page template only
  • point forms action attribute to <?php echo admin_url( 'admin-ajax.php' ); ?>
  • add hidden input with name="action" and value="my_form_action"
  • create ajax actions add_action( 'wp_ajax_my_form_action', 'my_form_function' ); and add_action( 'wp_ajax_nopriv_my_form_action', 'my_form_function' ); _nopriv is for not logged in users
  • create form processing function my_form_function

Example:
template-my-form.php

<?php
/* Template Name: My Form Template */
get_header();
// here goes form..
// you can copy index.php, rename it and insert your form
// where starts if( have_posts() )
?><form action="<?php echo admin_url( 'admin-ajax.php' ); ?>">...</form><?php
get_footer();

functions.php

add_action( 'wp_ajax_my_form_action', 'my_form_function' );
add_action( 'wp_ajax_nopriv_my_form_action', 'my_form_function' );
function my_form_function() {
    $form_element = sanitize_text_field( $_REQUEST['form_name'] );
    // here you do what you'r form should do
    // remember that you'r now in admin-ajax.php
    // so you need to redirect back to your page
    // check wp_referer_field and wp_nonce_field

    // if you want to make js ajax calls you should do wp_send_json_success( array );
}
add_action( 'wp_enqueue_scripts', 'my_form_scripts' );
function my_form_scripts() {
    if( is_page_template( 'template-my-form.php' ) ) {
        wp_enqueue_scripts('my_file', get_stylesheet_directory_uri() . '/js/my_script.js', array( 'jquery' ) );
    }
}

my_script.js

$(document).on( 'submit', 'form', function( event ) {
    var $ajax = $(this).find( 'input[name="ajax"]' );
    if( $ajax.length < 1 || parseInt( $ajax.val() ) < 1 )
        return;
    $.ajax( {
        action: $(this).attr( 'action' ),
        data: $(this).serialize(),
        success: function( res ) {
            if( res.success ) {
                // do on success form proccessing
                // res.data holds array passed to wp_send_json_success
            } else {
                // do on error form proccessing
                // res.data holds array passed to wp_send_json_error
            }
        }
    } );

} );

Leave a Comment