views:

34

answers:

1

Hi guys,

I'm trying to add a new method to jQuery validation plugin with the codes below. My goal is to check whether the email address has already existed in the database(MySQL). If it is, it will inform the user to register for another email address. Somehow, the result that always returns is "Email is already taken".

These are the codes in validate.js:

$(document).ready(function(){
 $.validator.addMethod("uniqueEmail", function(value, element) {
   $.ajax({
      type: "POST",
      url: "availability.php",
      data: value,
      success: function(exist)
      {
       if(exist>0) {
         return true;
       } return false;
      }
  });
 } ,"Email is already taken");
 $('#signup form').validate({
  rules: {
   firstname: {
    required: true,
    minlength:3
   },
   lastname: {
    required: true,
    minlength: 3
   },
   affiliation: {
    required: true,
   },
   occupation: {
    required: true,
   },
   email: {
    required: true,
    email: true,
    uniqueEmail: true
   },
   password: {
    minlength: 6,
    required: true
   },
   repassword: {
    equalTo: "#password"
   }
  },
  messages: {
   firstname: {
    minlength: "Your first name should be more than 3 characters"
   },
   lastname: {
    minlength: "Your last name should be more than 3 characters"
   },
  }, 
  success: function(label) {
   label.text('OK!').addClass('valid');
  }
 });
});

And these are the codes in my php file:

<?php

include_once $_SERVER['DOCUMENT_ROOT'] . '/braddclient/includes/magicquotes.inc.php';
include $_SERVER['DOCUMENT_ROOT'] . '/braddclient/includes/db.inc.php';

$email = strtolower($_POST['email']);
$email = mysqli_real_escape_string($link, $email);
$sql = "SELECT * FROM bradduser WHERE email='$email'";
$result = mysqli_query($link, $sql);
$num = mysqli_num_rows($result);

echo $num;

?>
+3  A: 

You can't quite do this here with a custom method because you need the validation plugin to know this is a remote (or more importantly, an asynchronous) request.

Luckily it has built-in functionality to help. Instead of a custom method you can use remote here, so leave of the custom method altogether and change out this:

uniqueEmail: true

for this:

remote: { url: "availability.php", type: "post" }

Then add the error message to messages like this:

email: { remote: "Email is already taken" }

Also change your PHP side to match, returning true or false, like this:

<?php
  include_once $_SERVER['DOCUMENT_ROOT'] . '/braddclient/includes/magicquotes.inc.php';
  include $_SERVER['DOCUMENT_ROOT'] . '/braddclient/includes/db.inc.php';

  $email = strtolower($_POST['email']);
  $email = mysqli_real_escape_string($link, $email);
  $sql = "SELECT * FROM bradduser WHERE email='$email'";
  $result = mysqli_query($link, $sql);
  if(mysqli_num_rows($result) > 0) {
    echo "false";  //validation fails, email in use
  } else {
    echo "true";   //validation passes
  }
?>
Nick Craver
Nice answer. I didn't know about `remote:`. Should have figured that they had something available for this type of situation. +1
patrick dw
Hi Nick, I have changed my codes according to your method but it didn't work for me. Somehow the error msg "Please enter a valid email address" keeps appearing. The rules of my email are as follow: email: { required: true, email: true, remote: { url: "availability.php", type: "post" } },Did I make any mistake?
dave
@dave -Is your PHP code getting hit at all? It sounds like it's failing on the `email: true` rule before hitting the remote one...which should be showing a different error message if you added it to `messages` like I have above.
Nick Craver
I found the error. I typed mysqli_num_row instead of mysqli_num_rows! I hate it when I make mistakes like this. Thanks Nick!
dave
@dave - Welcome :) Are you all set now?
Nick Craver
@nick yeah the validation process is working great! I would like to make it a bit more aesthetically pleasing though. Do you know how I could include a spinner image or loading text while the codes are checking for an existing email?
dave
You can use the [`.ajaxStart()`](http://api.jquery.com/ajaxStart/) and [`.ajaxStop()`](http://api.jquery.com/ajaxStop/) events if nothing else, just bind them to the image and ``$(this).show()` and `$(this).hide()` respectively, will that work?
Nick Craver
@nick I'm not too sure. I will have to try them. Thanks for the tip.
dave
@nick Thanks for the tips. I managed to track the progress with the following codes: $('#ajaxInProgress') .ajaxStart(function() { $(this).addClass('progress'); }) .ajaxStop(function() { $(this).removeClass('progress'); });
dave