Custom AJAX WordPress user registration form

It’s been a while since last post, shame on me.
Don’t know why, but I do many things with AJAX, so I will keep up in the same style.
In this post, I will create custom registration form with few more details then just username, or email.

For simplicity of this post I will not handle validation of the fields, this is something that is fairly common so I will skip it to keep post shorter and to keep focus on how to.

1. The form

First things first, create a registration form.
I will do this is a php function, so you can re-use this same form to create maybe a widget or a shortcode so you can place form anywhere on the site.

function vb_registration_form() { ?>

<div class="vb-registration-form">
  <form class="form-horizontal registraion-form" role="form">

  	<div class="form-group">
      <label for="vb_name" class="sr-only">Your Name</label>
      <input type="text" name="vb_name" id="vb_name" value="" placeholder="Your Name" class="form-control" />
    </div>

    <div class="form-group">
      <label for="vb_email" class="sr-only">Your Email</label>
      <input type="email" name="vb_email" id="vb_email" value="" placeholder="Your Email" class="form-control" />
    </div>

    <div class="form-group">
      <label for="vb_nick" class="sr-only">Your Nickname</label>
      <input type="text" name="vb_nick" id="vb_nick" value="" placeholder="Your Nickname" class="form-control" />
    </div>

    <div class="form-group">
      <label for="vb_username" class="sr-only">Choose Username</label>
      <input type="text" name="vb_username" id="vb_username" value="" placeholder="Choose Username" class="form-control" />
      <span class="help-block">Please use only a-z,A-Z,0-9,dash and underscores, minimum 5 characters</span>
    </div>

    <div class="form-group">
      <label for="vb_pass" class="sr-only">Choose Password</label>
      <input type="password" name="vb_pass" id="vb_pass" value="" placeholder="Choose Password" class="form-control" />
      <span class="help-block">Minimum 8 characters</span>
    </div>

    <?php wp_nonce_field('vb_new_user','vb_new_user_nonce', true, true ); ?>

    <input type="submit" class="btn btn-primary" id="btn-new-user" value="Register" />
  </form>

    <div class="indicator">Please wait...</div>
    <div class="alert result-message"></div>
</div>

<?php
}

For the full list of all default fields visit WordPress codex page wp_insert_user

Important

Important thing to notice here is nonce field:

<?php wp_nonce_field('vb_new_user','vb_new_user_nonce', true, true ); ?>

This will generate hidden nonce field which I will use to verify request.
You don’t want some bots to create zilion of accounts on your website, so to make thing secure we need to use nonce in our forms.
More on this is available in WP Codex wp_nonce_field

Important

You should add some jquery validation, there are lots of plugins out there to do that and I will not bother to do it right now, but you should.

2. AJAX scripts

Next thing what I will do is enqueue javascript file:

function vb_register_user_scripts() {
  // Enqueue script
  wp_register_script('vb_reg_script', get_template_directory_uri() . '/js-folder/ajax-registration.js', array('jquery'), null, false);
  wp_enqueue_script('vb_reg_script');

  wp_localize_script( 'vb_reg_script', 'vb_reg_vars', array(
        'vb_ajax_url' => admin_url( 'admin-ajax.php' ),
      )
  );
}
add_action('wp_enqueue_scripts', 'vb_register_user_scripts', 100);

Now when js file is included, we can start to get data and process user request.

jQuery(document).ready(function($) {

  /**
   * When user clicks on button...
   *
   */
  $('#btn-new-user').click( function(event) {

    /**
     * Prevent default action, so when user clicks button he doesn't navigate away from page
     *
     */
    if (event.preventDefault) {
        event.preventDefault();
    } else {
        event.returnValue = false;
    }

    // Show 'Please wait' loader to user, so she/he knows something is going on
    $('.indicator').show();

    // If for some reason result field is visible hide it
    $('.result-message').hide();

    // Collect data from inputs
    var reg_nonce = $('#vb_new_user_nonce').val();
    var reg_user  = $('#vb_username').val();
    var reg_pass  = $('#vb_pass').val();
    var reg_mail  = $('#vb_email').val();
    var reg_name  = $('#vb_name').val();
    var reg_nick  = $('#vb_nick').val();

    /**
     * AJAX URL where to send data
     * (from localize_script)
     */
    var ajax_url = vb_reg_vars.vb_ajax_url;

    // Data to send
    data = {
      action: 'register_user',
      nonce: reg_nonce,
      user: reg_user,
      pass: reg_pass,
      mail: reg_mail,
      name: reg_name,
      nick: reg_nick,
    };

    // Do AJAX request
    $.post( ajax_url, data, function(response) {

      // If we have response
      if( response ) {

        // Hide 'Please wait' indicator
        $('.indicator').hide();

        if( response === '1' ) {
          // If user is created
          $('.result-message').html('Your submission is complete.'); // Add success message to results div
          $('.result-message').addClass('alert-success'); // Add class success to results div
          $('.result-message').show(); // Show results div
        } else {
          $('.result-message').html( response ); // If there was an error, display it in results div
          $('.result-message').addClass('alert-danger'); // Add class failed to results div
          $('.result-message').show(); // Show results div
        }
      }
    });

  });
});

There are inline comments in script but let me explain little bit what is going on in this script:

When user clicks register button, then we start to do things

0. Validate inputs
1. First we disable default action so user doesn’t navigate away
2. There are 2 hidden divs below form, first is ajax-loader which will display loading icon, and second is for our response messages to user.
3. When user clicks ‘Register’ we display loading icon so he knows something is going on
4. Collect all data from input fields and save it in variables
5. Send AJAX request and retrieve data
6. In case of success, we will display some success message to user in ‘reponse messages’ div
7. In case of fail, we will display what went wrong in ‘reponse messages’ div

3. PHP function

The last part of puzzle is php function that will receive data from AJAX, try to create user and return result back.

/**
 * New User registration
 *
 */
function vb_reg_new_user() {

  // Verify nonce
  if( !isset( $_POST['nonce'] ) || !wp_verify_nonce( $_POST['nonce'], 'vb_new_user' ) )
    die( 'Ooops, something went wrong, please try again later.' );

  // Post values
	$username = $_POST['user'];
	$password = $_POST['pass'];
	$email    = $_POST['mail'];
	$name     = $_POST['name'];
	$nick     = $_POST['nick'];

 	/**
 	 * IMPORTANT: You should make server side validation here!
 	 *
 	 */

	$userdata = array(
		'user_login' => $username,
		'user_pass'  => $password,
		'user_email' => $email,
		'first_name' => $name,
		'nickname'   => $nick,
	);

	$user_id = wp_insert_user( $userdata ) ;

	// Return
	if( !is_wp_error($user_id) ) {
		echo '1';
	} else {
		echo $user_id->get_error_message();
	}
  die();

}

add_action('wp_ajax_register_user', 'vb_reg_new_user');
add_action('wp_ajax_nopriv_register_user', 'vb_reg_new_user');

0. First of all we verify nonce, if this fails > die()
0. We get data and make server side validation, if this fails > die()

I have not included server side validation, just to try to make this post shorter, but this is important part.
Don’t follow my example on production site, you will get burned.

After you have checked nonce and validated data once more create user.
– If everything goes well, I return 1, then in js I create some message for user.
– If something goes wrong, default WP display message will be displayed (email exists, username exits..)

That should be it.
There is no working example for obvious reason :)
But there are some download files.
If you include them in your theme it should work, just make sure to update path to javascript file.

Download

AJAX Registration form

28 Comments

    1. Hi,

      i want to show it my home page registration button. Can you please help me. As per your guide I have keep all the 2 files.ajax-registration in inc folder, and also called in function.php require get_parent_theme_file_path( ‘/inc/ajax-registration.php’ ); and also keep in js file asset/js/ajax-registration.js

      How can i show in home page.Please help me. I didn’t understand. I am using in local host.

  1. Thank you for the script.

    How do I retrieve the response in a jqwery variable and redirect a user to a new page based on the response? Currently, I get the results echoed in php after successful execution..But I would like to receive them in a variable and use it further to redirect them. Or, can I redirect in php? I get a whole page embedded in the ajax message div(making it two pages in one).

    Any help is highly appreciated.
    Again, thank you very much.

  2. Hi Bobz,

    Thank you for this amazing piece of code. It works great. Brilliant.
    Though similar to Rozan, I realized the script doesn’t work in Firefox. On line 8 (javascript part above), you need to pass the event property to the click function exclussively for it to work on firefox. i.e.

    $(‘#btn-new-user’).click( function(event) {

    Update the code, that should fix it. Again, thank you.

    1. Same issue ! WP said, no valid plugin.

      It´s a small shame, I wanted to give it a try. The Download zip also refers to other urls, that the written source above. Please refer 2. Ajax scripts refering Line 4 !

      Regards

    1. Sorry for that, I have fixed the link now.
      Have moved to another host, so some of the links obviously were left broken, thanks for pointing out.

    1. Hi Soma,
      Just add another input field and pass it to the function, same like I do for all other fields.
      Eg check the field ‘vb_nick’ and just repeat the same.

Leave a Reply

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