-4

I have this basic PHP form and I'd like to prevent the page from refreshing after pressing the submit button. Or more like, I would like to have a confirmation paragraph created after the form is sent.

I'm very close, but the paragraph is not getting displayed I think because the page is getting refreshed.

if($_POST["submit"]) {
$recipient="contact@d.com";
$subject="Form to email message";
$sender=$_POST["sender"];
$senderEmail=$_POST["senderEmail"];
$message=$_POST["message"];

$mailBody="Name: $sender\nEmail: $senderEmail\n\n$message";

mail($recipient, $subject, $mailBody, "From: $sender <$senderEmail>");

$thankYou="<div class='thanksDiv'><p>Thank you! Your message has been sent. I'll get back to you ASAP. <i class='as fa-smile-beam'></i></p><a style='cursor:pointer' class='thanksExit'><i class='fas fa-times fa-2x'></i></a></div>";
}

<form id="myForm" name="myemailform" method="post" action="index.php">
   <div class="inline">
      <label>Name</label>
      <input id="firstName" required placeholder="e.g: Emma" type="text" size="32" name="sender" value="">
   </div>
   <div class="inline">
      <label>Email</label>
      <input autocomplete="off" required id="email" type="email" placeholder="e.g: EmmaSmith@example.com" name="senderEmail">
    </div>
    <div class="inline">
       <label>How can I help?</label>
       <textarea id="textarea" required placeholder="Type a message here..." name="message"></textarea>
    </div>
    <input type="submit" name="submit" value="Submit">
    <?=$thankYou ?>
</form>

Note: I've tried the preventDefault function and Ajax and they didn't work.

Thank you!

bensiu
  • 24,660
  • 56
  • 77
  • 117
ergoProxy
  • 93
  • 9
  • This will be done with javascript, and ajax. And "didnt work" is not very helpful to go on to help you fix the problem. – IncredibleHat Jun 25 '20 at 13:52
  • 2
    please include your ajax code – apple apple Jun 25 '20 at 13:52
  • I am sure, that and AJAX post call to the php file, will work if it is written correctly – Stender Jun 25 '20 at 13:57
  • My bad! I have used this: $("#myForm").submit(function(){ $.post($(this).attr("action"), $(this).serialize()); return false; }); – ergoProxy Jun 25 '20 at 13:59
  • one error in your "AJAX" above, is that it is not AJAX .. missing `$.ajax({` etc. – Stender Jun 25 '20 at 14:05
  • @Stender post is used there. . That is almost the same – Ingus Jun 25 '20 at 14:07
  • Right, then that's probably why it's not working. How can I write that ajax properly? Sorry, I'm new to this server side coding. – ergoProxy Jun 25 '20 at 14:11
  • @ingus very close to the same – Stender Jun 25 '20 at 14:11
  • but that will still need preventDefault to not reload - and a success callback to actually put the return text into the element – Stender Jun 25 '20 at 14:17
  • the example furthest to the bottom in the jquery docs does exactly what you are trying to do : https://api.jquery.com/jquery.post/ – Stender Jun 25 '20 at 14:18
  • @DianaCristina your `$.post()`, looks correct. If it's failing, there may be other JavaScript that is failing and this is why the code is not executing as expected. Please provide a Minimal, Reproducible Example: https://stackoverflow.com/help/minimal-reproducible-example – Twisty Jun 25 '20 at 14:21
  • @Stender I see what's going on, but I have no clue how to actually make it work for me. Could you help me out on that? if not, thank you anyway – ergoProxy Jun 25 '20 at 14:26

3 Answers3

0

They are different ways and approaches to resolve that issue.

How I do it: I have a processing php that will receive the post and send the email then I redirect the user to a thanks page.

header("location: thanks.php);
exit();

You can also use ajax, and disable the button once it is pressed. It depends on the developer, framework and programming preferences.

Vidal
  • 2,605
  • 2
  • 16
  • 32
  • Yep, that'd be a fast way to do it, but I would prefer to not redirect the user. - bad UX – ergoProxy Jun 25 '20 at 14:15
  • why is bad UX? that change is on the server side, the user does not know anything on where the code get executed or redirected.. – Vidal Jun 25 '20 at 15:43
  • What do you mean? It's annoying for the user to get redirected to another page after submitting a form. Simple. – ergoProxy Jun 26 '20 at 13:46
  • Does the user care about how your write your php code ? this is transparent to the user, no page have been rendered is not a load one page and redirect to another one.. You do the processing and then send it to the thanks page. This approach is very normal. – Vidal Jun 26 '20 at 14:05
  • btw is also the cleanest method of eliminating resubmission's on refresh or double clicks on ajax. No complex session handling, no extra code that can also bring more issues than solutions. – Vidal Jun 26 '20 at 14:07
  • What your code does is 1. The user sends the form 2. The user is redirected to a thank you page. Correct? So yes, it is bad UX because the user would have to go back to the main page. In any case, it's not what I asked for. – ergoProxy Jun 26 '20 at 14:10
  • ***I have this basic PHP form and I'd like to prevent the page from refreshing after pressing the submit button. Or more like, I would like to have a confirmation paragraph created after the form is sent.*** I don't see any comment that you want to do this with ajax, I don't saw any javascript code to do an ajax request. If that's the case I think you have to update your question, because is not clear then. My suggestions perform everything you asked, the only issue is that you don't like it. – Vidal Jun 26 '20 at 14:14
  • first result on google on how to prevent form re submission. https://stackoverflow.com/questions/6320113/how-to-prevent-form-resubmission-when-page-is-refreshed-f5-ctrlr Read the answers 70% use and recommend **header("location:page.php");** – Vidal Jun 26 '20 at 14:19
  • I said I wanted the page to not be refreshed - being redirected is the same but worse. whatevs – ergoProxy Jun 26 '20 at 14:21
  • Then update your question and add the ajax part that is missing, and also mention that you want the user to stay on the same page, because refresh and redirect are two very different things. You mention you want to **prevent page from refresh** and then said **confirmation paragraph created after form is sent** no where you explain you want the user to stay on the same page. Please be clear and post the relevant code to answer your question. – Vidal Jun 26 '20 at 14:25
  • It seems everyone else understood what I meant. Thank you for your help anyway. – ergoProxy Jun 26 '20 at 14:30
  • I saw other people asking for the the ajax code.. and you post it as a comment. So yes, the ajax is missing. good luck with your project. – Vidal Jun 26 '20 at 14:32
0

You will first need to send some data back to your AJAX from PHP.

session_start();
if(isset($_POST["submit"])) {
  $recipient="contact@d.com";
  $subject="Form to email message";
  $sender=$_POST["sender"];
  $senderEmail=$_POST["senderEmail"];
  $message=$_POST["message"];

  $mailBody="Name: $sender\nEmail: $senderEmail\n\n$message";

  mail($recipient, $subject, $mailBody, "From: $sender <$senderEmail>");

  $thankYou="<div class='thanksDiv'><p>Thank you! Your message has been sent. I'll get back to you ASAP. <i class='as fa-smile-beam'></i></p><a style='cursor:pointer' class='thanksExit'><i class='fas fa-times fa-2x'></i></a></div>";
    
  echo $thankYou;
}

Now your PHP will send the HTML back to the AJAX Call.

$(function() {
  $("#myForm").submit(function(e) {
    e.preventDefault();
    $.post($(this).attr("action"), $(this).serialize(), function(result) {
      $(this).append(result);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm" name="myemailform" method="post" action="index.php">
  <div class="inline">
    <label>Name</label>
    <input id="firstName" required placeholder="e.g: Emma" type="text" size="32" name="sender" value="">
  </div>
  <div class="inline">
    <label>Email</label>
    <input autocomplete="off" required id="email" type="email" placeholder="e.g: EmmaSmith@example.com" name="senderEmail">
  </div>
  <div class="inline">
    <label>How can I help?</label>
    <textarea id="textarea" required placeholder="Type a message here..." name="message"></textarea>
  </div>
  <input type="submit" name="submit" value="Submit">
</form>

In this JavaScript, you will notice, I make use of the Event object for the Submit Callback. This allows me to use .preventDefault() properly.

Trying to put the message into your Session is fine, yet it requires loading another page to call up a session. PHP is only executed before the web server sends the HTML to the Web Browser. With AJAX, the Post request is being performed "in the background", so data can be sent back in HTML, Text, JSON, or XML without the need to reload or redirect. The JavaScript can then work with that data on the same page, no "flicker".

In this case, we append the HTML to the Form, so once the message has been sent via PHP mail(), the User will see the Thank You message.

Update

Consider the following PHP alternate code.

<?php
if(isset($_POST["submit"])) {
  $recipient = "contact@d.com";
  $subject = "Form to email message";
  $sender = $_POST["sender"];
  $senderEmail = $_POST["senderEmail"];
  $message = wordwrap($_POST["message"], 70, "\r\n");
  $headers = "From: $sender <$senderEmail>\r\n";
  $headers .= "Reply-To: $senderEmail\r\n";
  $headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
  $headers .= "X-Originating-IP: " . $_SERVER['REMOTE_ADDR']

  $mailBody="Name: $sender\r\nEmail: $senderEmail\r\n\r\n$message";

  var $res = mail($recipient, $subject, $mailBody, $headers);

  if($res){
    echo "<div class='thanksDiv'><p>Thank you! Your message has been sent. I'll get back to you ASAP. <i class='as fa-smile-beam'></i></p><a style='cursor:pointer' class='thanksExit'><i class='fas fa-times fa-2x'></i></a></div>";
  } else {
    echo "<div class='mailError'><p>Sorry, there was an error sending your message. Please check the details and try submitting it again.</p></div>";
  }
}
Twisty
  • 30,304
  • 2
  • 26
  • 45
  • Made these changes, now I get an eror when loading the page This page isn’t working HTTP ERROR 500 >.> thank you for explaining though – ergoProxy Jun 25 '20 at 14:47
  • @DianaCristina this would suggest an error in your PHP or with your Web Server. Check your PHP / Web Logs. – Twisty Jun 25 '20 at 14:54
  • yep it seems like when I replace if($_POST["submit"]) with if(issset($_POST["submit"])) I get that error. Although, when I leave it with if($_POST["submit"]) it still reloads the page. the rest is the same as you wrote it. – ergoProxy Jun 25 '20 at 15:09
  • @DianaCristina the `isset()` function should work, see: https://www.php.net/manual/en/function.isset.php If it is not, and generating an error, this suggests an issue with your PHP. – Twisty Jun 25 '20 at 15:35
  • Found what the problem was. Just an annoying typo. It was issset instead of isset. It still doesnt work. Now I click the submit button and nothing happens - which is good because it doesnt reload the page, but the mail isnt sending. Do you know what I can do about that? – ergoProxy Jun 25 '20 at 17:08
  • - because of this e.preventDefault(); - so yea it stops the page from reloading but it also stops the form from being submitted – ergoProxy Jun 25 '20 at 17:17
  • @DianaCristina again, this is an issue in your PHP. If `mail()` is failing, you need to check PHP / Web Server logs to determine why. You can check web console Network Tab to see what the result of the Post Request shows. – Twisty Jun 25 '20 at 17:49
-1

Some solutions:

If the user does not need to stay on the same page then as Vidal posted, redirect to a success/thank you page.

If the user needs to stay on the same page then you have a few options:

Method A:

  1. Set session with a form identifier (anything) if nothing is posted (i.e. initial page load). e.g. if(!isset($_POST['field'])){ $_SESSION['....
  2. When form is submitted, check that session exists with the form identifier and process then destroy session.
  3. Now if it's refreshed, the session won't exist, you can inform user that it's already submitted

Problem with this is that if session has timed out and the refresh is done, it will go through.

Method B:

Disable refresh: https://stackoverflow.com/a/7997282/1384889

Method C:

Check database for repeat entry

Method D: (I don't like this but it's used plenty)

Reload same page with '&t='.time() appended to URL by php header() or javascript depending on where your script is executed.

Onimusha
  • 3,348
  • 2
  • 26
  • 32