Sending e-mail form using PHP and AJAX

17,843

Solution 1

Ok, first when you make an AJAX call, you must have a way to know if your PHP returns you something (useful for debugging).

Then, when submitting a form with AJAX, the tag action="" is not needed.

Finally, to prevent a form from being sent when making an AJAX call, add e.preventDefault() with the event called e here, like in my example.

I have improved your code to be more realistic about the latest standards.

HTML :

<form name="freeCall" method="post" class="popover-form" id="free-call-form">  
  <label for="name1">Name</label><span class="pull-right close">&times;</span><input placeholder="Name" name="call-name" type="text" id="name1" >  
  <label for="phone">Phonenumber</label><input name="phone" type="text" value="" placeholder="+375" id="phone" >    
  <input type="submit" value="Call me back" >       

JS :

$(function () {    
  $("#free-call-form").submit(function (e) {
    e.preventDefault();
    var form_data = $(this).serialize(); 
    $.ajax({
      type: "POST", 
      url: "call-form.php",
      dataType: "json", // Add datatype
      data: form_data
    }).done(function (data) {
        console.log(data);
        alert("It's OK!");
    }).fail(function (data) {
        console.log(data);
    });
  }); 
});

And PHP :

if((isset($_POST['call-name']))&&(isset($_POST['phone'])&&$_POST['phone']!="")){ 
  $to = '[email protected]';
  $subject = 'Callback';
  $message = '
        <html>
            <head>
                <title>Call me back</title>
            </head>
            <body>
                <p><b>Name:</b> '.$_POST['call-name'].'</p>
                <p><b>Phonenum:</b> '.$_POST['phone'].'</p>                        
            </body>
        </html>'; 
  $headers  = "Content-type: text/html; charset=utf-8 \r\n"; 
$headers .= "From: Site <[email protected]>\r\n"; 
mail($to, $subject, $message, $headers);

  echo json_encode(array('status' => 'success'));
} else {
  echo json_encode(array('status' => 'error'));
}

With echo json_encode, you know what is the return of your AJAX call. It is better

Solution 2

Returning false or preventing the default behavior of the event should work for you.

Example with old .submit(), that now is an alias of .on('eventName'); and using return false to avoid form submission.;

 $("#free-call-form").submit(function () { 
    var form_data = $(this).serialize(); 
    $.ajax({
        type: "POST", 
        url: "call-form.php", 
        data: form_data,
        success: function () {
          alert("It's OK!");
      }
    });
    return false;
}); 

Example using .on('eventName') and using e.preventDefault() to avoid form submission.

$("#free-call-form").on('submit', function (e) { 
    e.preventDefault();
    var form_data = $(this).serialize(); 
    $.ajax({
        type: "POST", 
        url: "call-form.php", 
        data: form_data,
        success: function () {
          alert("It's OK!");
      }
    });
}); 

From Jquery .submit() Documentation: This method is a shortcut for .on( "submit", handler ) in the first variation, > and .trigger( "submit" ) in the third.

Also, you would consider not using EVER the user input directly, it would not cause problems in this exact context (or maybe yes) but with your actual approach they can change the mail markup or adding some weirds things there, even scripts, you would consider escape, validate or limit it.

Also as zLen pointed out in the comments:

the action in the form markup is not necessary because you are not using it, you can remove it:

action="<?php bloginfo(template_url); ?>/mail/call-form.php"

Solution 3

You're not preventing the default submit action -

$("#free-call-form").submit(function (event) { // capture the event
    event.preventDefault();  // prevent the event's default action

Solution 4

What is happening is your form is being submitted, it's not actually the AJAX call which is doing it. To fix it, add

return false;

at the end of the submit function so that the browser doesn't submit the form and the AJAX call happens properly.

Share:
17,843
Maryja Piaredryj
Author by

Maryja Piaredryj

Software developer, dumb questions asker, stackoverflow lover =)

Updated on June 07, 2022

Comments

  • Maryja Piaredryj
    Maryja Piaredryj almost 2 years

    I have contact form on my site. It sends message to email. I try to do it without page reload using AJAX, but it seems that AJAX doesn't work: messages are sent but the page still redirecting to call-form.php. What is incorrect in my code? (jQuery is included)

    HTML

    <form name="freeCall" action="<?php bloginfo(template_url); ?>/mail/call-form.php" method="post" class="popover-form" id="free-call-form">  
        <label for="name1">Name</label><span class="pull-right close">&times;</span><input placeholder="Name" name="call-name" type="text" id="name1" >  
        <label for="phone">Phonenumber</label><input name="phone" type="text" value="" placeholder="+375" id="phone" >    
        <input type="submit" value="Call me back" >       
    </form>
    

    PHP - call-form.php

    <?
    if((isset($_POST['call-name']))&&(isset($_POST['phone'])&&$_POST['phone']!="")){ 
            $to = '[email protected]';
            $subject = 'Callback';
            $message = '
                    <html>
                        <head>
                            <title>Call me back</title>
                        </head>
                        <body>
                            <p><b>Name:</b> '.$_POST['call-name'].'</p>
                            <p><b>Phonenum:</b> '.$_POST['phone'].'</p>                        
                        </body>
                    </html>'; 
            $headers  = "Content-type: text/html; charset=utf-8 \r\n"; 
            $headers .= "From: Site <[email protected]>\r\n"; 
            mail($to, $subject, $message, $headers); 
    }
    ?>
    

    JS

    $(function () {    
          $("#free-call-form").submit(function () { 
            var form_data = $(this).serialize(); 
            $.ajax({
              type: "POST", 
              url: "call-form.php", 
              data: form_data,
              success: function () {
                alert("It's OK!");
              }
            });
          }); 
    });
    
  • Maryja Piaredryj
    Maryja Piaredryj almost 9 years
    Please explain why you describe submit twice?
  • ecarrizo
    ecarrizo almost 9 years
    Sure. In the first example i copied your exact same code and added return false statement; that should work. In my second example i use another way of binding the submit button, as pointed out in my comment that way you avoid Jquery calling on in the background. Also in the second example i use a different way to avoid form submission, i use e.preventDefault(); that avoid the default behavior 'submit' on the submit event.
  • Maryja Piaredryj
    Maryja Piaredryj almost 9 years
    Ah, I thought that it was not two different examples) Thanks!