Solved

PHP and jQuery

Posted on 2016-07-19
12
56 Views
Last Modified: 2016-08-09
I have a form that when submitted, if it is successful I want to show a certain div and hide another div.  It works on success but then reverts back to the original once the page resets.  I'm not sure how to do this.  Where I am trying to implement the jQuery is on line: 43 - 51

 <?php
                if (isset($_POST['submitted'])) { // Handle the form.
                    // Trim all the incoming data:
                    $trimmed = array_map('trim', $_POST);


                    $errors = array(); // Initialize an error array.
                    // Check for a first name:
                    if (preg_match('/^[A-Z \'.-]{2,20}$/i', $trimmed['full_name'])) {
                        $fn = mysqli_real_escape_string($dbc, $trimmed['full_name']);
                    } else {
                        $errors[] = 'You forgot to enter your name.';
                    }

                    // Check for an email address:
                    if (preg_match('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
                        $e = mysqli_real_escape_string($dbc, $trimmed['email']);
                    } else {
                        $errors[] = 'You forgot to enter a valid email address.';
                    }



                    if (empty($errors)) {
                        // Make sure the email address is available:
                        $q = "SELECT user_id FROM jmc_cal_users WHERE email='$e'";
                        $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

                        if (mysqli_num_rows($r) == 0) { // Available.
                            // Create the activation code:
                            $a = md5(uniqid(rand(), true));

                            // Add the user to the database:
                            $q = "INSERT INTO jmc_cal_users (email, full_name, active, registration_date) VALUES ('$e', '$fn', '$a', NOW() )";
                            $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

                            if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
                                // Send the email:
                                $body = "Thank you for registering your email  please click on this link:\n\n";
                                $body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
                                mail($trimmed['email'], 'Email Confirmation', $body, 'From: admin@sitename.com');
                                ?>
                                <script>
                                    $(function () {
                                        $("#calc_submit").click(function () {

                                            $(".submit-cont").hide("slow");
                                            $(".calculator-statement").show("slow");
                                        });
                                    });
                                </script>
                                <?php
                                
                            } else { // If it did not run OK.
                                echo '<p class="error">Your email could not be registered due to a system error. We apologize for any inconvenience.</p>';
                            }
                        } else { // The email address is not available.
                            echo '<p class="error">That email address has already been registered.</p>';
                        }
                    } else { // Report the errors.
                        echo '<h1>Error!</h1>
		<p class="error">The following error(s) occurred:<br />';
                        foreach ($errors as $msg) { // Print each error.
                            echo " - $msg<br />\n";
                        }
                        echo '</p><p>Please try again.</p><p><br /></p>';
                    } // End of if (empty($errors)) IF.
                    mysqli_close($dbc);
                } // End of the main Submit conditional.
                ?>


<html>
 <form action="?" method="post">
                    <div class="calculator-submit">
                        <p>
                            <input type="text" name="full_name" size="25" maxlength="120" value="<?php if (isset($trimmed['full_name'])) echo $trimmed['full_name']; ?>" placeholder="Name"/>
                            <br />
                            <input type="email" name="email" size="25" maxlength="65" value="<?php if (isset($trimmed['email'])) echo $trimmed['email']; ?>" placeholder="Email"/>
                        </p>
                        <p>

                        </p>
                    </div>
                    <div class="submit-cont">
                        <input type="submit" name="submit" id="calc_submit" value="Submit" />
                        <input type="hidden" name="submitted" value="TRUE" />
                    </div>
                </form>
                <div>

                    <!--  END Calculator Submit Form  -->

                    <div class="calculator-statement" style="display:none;">
                        <h2>Check your email</h2><br />
                    </div>

</html>

Open in new window

0
Comment
Question by:rgranlund
  • 5
  • 2
  • 2
  • +2
12 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41719876
reverts back to the original once the page resets
Pages don't "reset" but there must be another word that captures what you're going for.  Do you mean "after the client reloads the page?"  Or am I missing the point here?

Maybe the best design would be one that has both divs in the HTML.  The jQuery script could have a success function that changes the visibility.  So rather than sending some JavaScript after the PHP action script has taken control of the process, you could send just a signal from the PHP action script, and the jQuery success function could change the visibility of the divs based on the information gotten from the server-side script.  Just a thought.
0
 
LVL 7

Author Comment

by:rgranlund
ID: 41719975
How would I send a "signal" to the jQuery upon success?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41720005
jQuery has HTTP request methods that invoke success or failure functions.  But that aside, it might be simpler to just work with the server-side response, as shown in this article.
https://www.experts-exchange.com/articles/10712/The-Hello-World-Exercise-with-jQuery-and-PHP.html

Your jQuery code could look for information in the AJAX response and decide what to do.  A good response format is JSON because it's a nearly universal language in information processing today.
0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 41720009
This is typically what you use ajax for.  So instead of submitting the page the traditional way, you submit behind the scenes asynchronously.

This is untested but demonstrates the use of ajax:

 <?php
                if (isset($_POST['submitted'])) { // Handle the form.
                    // Trim all the incoming data:
                    $trimmed = array_map('trim', $_POST);


                    $errors = array(); // Initialize an error array.
                    // Check for a first name:
                    if (preg_match('/^[A-Z \'.-]{2,20}$/i', $trimmed['full_name'])) {
                        $fn = mysqli_real_escape_string($dbc, $trimmed['full_name']);
                    } else {
                        $errors[] = 'You forgot to enter your name.';
                    }

                    // Check for an email address:
                    if (preg_match('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
                        $e = mysqli_real_escape_string($dbc, $trimmed['email']);
                    } else {
                        $errors[] = 'You forgot to enter a valid email address.';
                    }



                    if (empty($errors)) {
                        // Make sure the email address is available:
                        $q = "SELECT user_id FROM jmc_cal_users WHERE email='$e'";
                        $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

                        if (mysqli_num_rows($r) == 0) { // Available.
                            // Create the activation code:
                            $a = md5(uniqid(rand(), true));

                            // Add the user to the database:
                            $q = "INSERT INTO jmc_cal_users (email, full_name, active, registration_date) VALUES ('$e', '$fn', '$a', NOW() )";
                            $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

                            if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
                                // Send the email:
                                $body = "Thank you for registering your email  please click on this link:\n\n";
                                $body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
                                mail($trimmed['email'], 'Email Confirmation', $body, 'From: admin@sitename.com')                                
                            } else { // If it did not run OK.
                                $errors[] = 'Your email could not be registered due to a system error. We apologize for any inconvenience.';
                            }
                        } else { // The email address is not available.
                            $errors[]= 'That email address has already been registered.';
                        }
                    } else { // Report the errors.
                        echo json_encode($errors);
                    } // End of if (empty($errors)) IF.
                    mysqli_close($dbc);
                } // End of the main Submit conditional.
                ?>


<html>
<body>
 <form action="?" method="post" id="calc" on>
                    <div class="calculator-submit">
                        <p>
                            <input type="text" name="full_name" size="25" maxlength="120" value="<?php if (isset($trimmed['full_name'])) echo $trimmed['full_name']; ?>" placeholder="Name"/>
                            <br />
                            <input type="email" name="email" size="25" maxlength="65" value="<?php if (isset($trimmed['email'])) echo $trimmed['email']; ?>" placeholder="Email"/>
                        </p>
                        <p>

                        </p>
                    </div>
                    <div class="submit-cont">
                        <input type="submit" name="submit" id="calc_submit" value="Submit" />
                        <input type="hidden" name="submitted" value="TRUE" />
                    </div>
                </form>
                <div>

                    <!--  END Calculator Submit Form  -->

                    <div class="calculator-statement" style="display:none;">
                        <h2>Check your email</h2><br />
                    </div>
                                <script>
                                    $(function () {
                                    	$("#calc").on('submit', function(e) {
                                    		e.preventDefault();
                                    	});
                                        $("#calc_submit").click(function () {
											$.ajax({
												url: '',
												data: $("#calc").serialize(),
												method: 'post',
												success: function(d) {
													// d will hold the json representation of $errors
													if (d.length) {
													    // there are errors
														console.dir(d);// output to he console to see what they are
													}
													else {
														// success!
														$(".submit-cont").hide("slow");
														$(".calculator-statement").show("slow");
													}
												}
											});
                                        });
                                    });
                                </script>
</body>
</html>

Open in new window

0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 41720011
Ray, sorry I hadn't seen your post when I submitted mine.  AJAX definitely the way to go here :)
0
 
LVL 7

Author Comment

by:rgranlund
ID: 41721424
@rob, thanks for this example.  This is the way to go.  Thanks to you and Ray.  Two final questions from the example you sent,
1.  how do I get the error messages to do a for each?
2. The error message returned is in brackets.  How do I remove them?  It looks like this when returned:
["You forgot to enter your name.","You forgot to enter a valid email address."]
 $("#calc_submit").click(function () {
                                $.ajax({
                                    url: 'http://jaymillerconsulting.com/ltv_email_ajax.php',
                                    data: $("#calc").serialize(),
                                    method: 'post',
                                    success: function (d) {
                                        // d will hold the json representation of $errors
                                        if (d.length) {
                                            // there are errors

                                            $( "div.errors").html(function() {
  var errormessage = d;
  return errormessage;
});
                                        } else {
                                            // success!
                                            $(".submit-cont").hide("slow");
                                            $(".calculator-statement").show("slow");
                                        }
                                    }

Open in new window

0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 33

Accepted Solution

by:
Slick812 earned 500 total points
ID: 41723394
greetings  rgranlund, , I looked at your original PHP code in your question, It looks like you used someone else's  code to do the PHP work in testing the POST strings like -
   if (preg_match('/^[A-Z \'.-]{2,20}$/i', $trimmed['full_name'])) {

But that does not matter, It looks like it will do the job you need done here, But I really do not see that the extra work and processes of an AJAX roundabout will be of any help to you in this. . In your original code work you seem to think that the PHP sever operations and the browser Javascript operations, happen at the same time, but they DO NOT, they happen at different times on two different computers, and are NOT related to each other except for text information that they may or may NOT send to each other in the HTTP request.  As you have seen, if you attempt to set a javascript show( ) or hide( ) , for a form submit, the page will change to update on the <form> submit, so you lose all of the show( ) and hide( ) you did on the previous page show.

BUT you can set a variable like -
    $complete = false;
in the PHP at first , and ONLY when the PHP database is successfully UPDATE , you set the $complete to true, and then in the <body> HTML code you use
    <?php if (!$complete) { ?>
to show or hide HTML sections that will be DIFFERENT according to if the <form> submit in the server was complete or Not.

please consider this code -
<?php
$errors = "";
$complete = false;

if (isset($_POST['submit'])) { // test for the Submit button NAME
// Trim all the incoming data:
$trimmed = array_map('trim', $_POST);
$errors = array(); // Initialize an error array.
// Check for a first name:
if (preg_match('/^[A-Z \'.-]{2,20}$/i', $trimmed['full_name'])) {
  $fn = mysqli_real_escape_string($dbc, $trimmed['full_name']);
  } else {
  $errors .= "- You forgot to enter your name.<br />\n";
  }

// Check for an email address:
if (preg_match('/^[\w.-]+@[\w.-]+\.[A-Za-z]{2,6}$/', $trimmed['email'])) {
  $e = mysqli_real_escape_string($dbc, $trimmed['email']);
  } else {
  $errors .= "- You forgot to enter a valid email address.<br />\n";
  }

if (!$errors) {
// Make sure the email address is available:
  $q = "SELECT user_id FROM jmc_cal_users WHERE email='$e'";
  $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

  if (mysqli_num_rows($r) == 0) { // Available.
// Create the activation code:
    $a = md5(uniqid(rand(), true));

// Add the user to the database:
    $q = "INSERT INTO jmc_cal_users (email, full_name, active, registration_date) VALUES ('$e', '$fn', '$a', NOW() )";
    $r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));

    if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
// Send the email:
    $body = "Thank you for registering your email  please click on this link:\n\n";
    $body .= BASE_URL . 'activate.php?x=' . urlencode($e) . "&y=$a";
    mail($trimmed['email'], 'Email Confirmation', $body, 'From: admin@sitename.com');
                                
    } else { // If it did not run OK.
    $errors .= '- Your email could not be registered due to a system error. We apologize for any inconvenience.';
    }
    } else { // The email address is not available.
    $errors .= '- That email address has already been registered.</p>';
    }
  }
  mysqli_close($dbc);
  
  if($errors)  { // Report the errors.
   $errors = '<h1>Error!</h1><p class="error">The following error(s) occurred:<br />'.$errors.
     '</p><p>Please try again.</p><p><br /></p>';
    } else { // End of if errors
    $complete = true;	
    }

} // End of the main Submit conditional.
?>


<html>
<body>
<?php if (!$complete) { 
  if ($errors) echo $errors; ?>

 <form action="?" method="post">
  <div class="calculator-submit">
    <p>
    <input type="text" name="full_name" size="25" maxlength="120" value="<?php if (isset($trimmed['full_name'])) echo $trimmed['full_name']; ?>" placeholder="Name"/>
    <br />
    <input type="email" name="email" size="25" maxlength="65" value="<?php if (isset($trimmed['email'])) echo $trimmed['email']; ?>" placeholder="Email"/>
    </p>
    <p></p>
  </div>

  <input type="submit" name="submit" value="Submit" />

  </form>
<?php } else { ?>

<h2>SUCCESS! now you need to Check your email</h2><br />

<?php } ?>

</body></html>

Open in new window


I have changed your $errors from an array to a string, and just ADD the different error messages to that string, THEN I test if the $errors has any length (I.E there are errors reported) ith -
   if (!$errors) {
which will be TRUE if there are No Errors.
Then down below the <body> tag I use -
       if ($errors) echo $errors;
so the user can see what errors there were.

I use -
    <?php if (!$complete) {
to display the entire <form> only IF the POST was NOT successful

and then use -
    <?php } else { ?>
    <h2>Check your email</h2><br />
   <?php } ?>

To display the check email SUCCESS message

There is NO Javascript used in this, because it is all server side PHP, , the javascript AJAX can be very useful, but can also be difficult to understand and use, just like your question as -
     "The error message returned is in brackets.  How do I remove them? "

it is because the AJAX return is in a JSON text string format, which you really do not need for the way your AJAX success( ) method is assembled there.
0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 41723903
Note that AJAX is never needed.  It's purely for improving the user experience (by not reloading the page) as you could always post all the data to the server and recreate the page.

I'm inclined to agree with Slick on this after chewing on it for a bit if I'm correct in saying that the "state" of your page can be recreated easily from the PHP.  By "state", I mean the logic behind why you are showing a form and what the user can or should do next and also the way the page looks because of the previous user interactions.

AJAX is useful when you want to stay on the same page and retain the visual state of that page (e.g. scroll position).  This can get quite complex to do via PHP when you have a lot going on in your front end.   This forms part of the methodology of Model, Views and Controllers.  Separating your elements makes for easier coding, readability, SEO and performance.

With the example of a simple contact form, the user is only going to fill it out once and submit so it doesn't really make sense to use AJAX in that case.

On the other hand, take this question thread, if it didn't use AJAX and the page refreshed it wouldn't retain the simple scroll position (state) and you'd have to navigate back to where you were when you posted the comment; not a good user experience.

Another example is filling out a form and halfway through due to the user selecting say a category, you need to show them the contents of that category (from your database) then using AJAX will not affect the selections they've already made on the page.  The flipside is refreshing the page gives you the opportunity to save the selections they've already made in their session.

There's a lot to consider and I would think about how important it is to separate the way your front end works from your backend.  Too much front end control from PHP (controlling classes or showing/hiding elements) IMO isn't going to do you any favours.

Side note: Remember that all validation needs to happen in your PHP.  Some basic parsing can happen in JavaScript but the validation MUST happen server side.
0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 41723909
As for getting the errors, they're all in a simple array so assuming you have an element you want to show the errors:

success: function(d) {
	// d will hold the json representation of $errors
	if (d.length) {
		// there are errors
		for (err in d) {
			$("#errors").append("<p class='error'>"+err+"</p>");
		}
	}
	else {
		// success!
		$(".submit-cont").hide("slow");
		$(".calculator-statement").show("slow");
	}
}

Open in new window

0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41724507
2. The error message returned is in brackets.  How do I remove them?  It looks like this when returned:
["You forgot to enter your name.","You forgot to enter a valid email address."]

This looks like a JSON return - you can simply add the

dataType: "JSON"

To your AJAX request and the return in your success - should then be a javascript array.

In other words
$("#calc_submit").click(function () {
  $.ajax({
    url: 'http://jaymillerconsulting.com/ltv_email_ajax.php',
    data: $("#calc").serialize(),
    method: 'post',
    dataType: 'JSON', /ADD THIS
    success: function (d) {
      // d will hold the json representation of $errors
      if (d.length) {
        // there are errors
        $.each(d, function(index, item) {
          // DO SOMETHING WITH ERROR MESSAGE HERE
        });
      } else {
        // success!
        $(".submit-cont").hide("slow");
        $(".calculator-statement").show("slow");
      }
    }
  });
});

Open in new window

Also take a look at the docs for JQuery .ajax . The success call back is being deprecated in favour of then
0
 
LVL 42

Expert Comment

by:Rob Jurd, EE MVE
ID: 41724520
Yeah it was only showing brackets because I had you outputting it to the console. JQuery's Ajax function will automatically recognise the returned data as json so it's not needed but probably good practice as an error is thrown if json format isn't returned.  The way I had it, a string, xml etc could be returned and it wouldn't throw an error. Not something you want, I suspect.
0
 
LVL 33

Expert Comment

by:Slick812
ID: 41724967
@rgranlund    ? ? , you still here?

In my view, It takes time and effort to learn to Correctly use any server-browser Exchange as AJAX processes, especially for someone that is not familiar with using JavaScript and-or Jquery, it is not easy to understand, even if you just copy and paste code as you did here, and hope that the code works for you.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

PROBLEM: The other day I was working on adding an ajax request to a webpage that already had a dialog box on the page.  The dialog box was using relative positioning to be positioned next to a form field I had on the page.  Everything was working…
Introduction JSON is an acronym for JavaScript Object Notation.  It is a text-string data transport mechanism, capable of representing simple or complex data structures in a consistent and easy-to-read manner.  Similar in concept to XML, but more e…
The viewer will learn how to dynamically set the form action using jQuery.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now