.ajax() Data Passed to PHP is the PHP script?

Hi all,

My form submission script sends the PHP script as the captured data instead of the form data (e-mail address). I have debugged this as I set an alert to show me the data being sent to the PHP script, and it is the PHP script. Maybe the .ajax() query needs to be re-written, but I don’t know why since this e-mail collection script works just fine on my landing pages (bottom of page).

This is the current JS I have (emailbox.js):
$(document).ready(function(){

    generateEquation();
    
    $("#form1").submit(function(e){
      startTime = jQuery.now();
    
      e.preventDefault();
      $.ajax({
        type: $(this).attr('method'),
        dataType: 'html',
        cache: false,
        url: "Scripts/emailtester.php",
        data: $(this).serialize(),
        success: function(data){
            alert(data);
          testFirstResults(data);
        }
      });
    });
  //this is the function called by the success value of the first .ajax() call
  function testFirstResults(response){
    if (response.indexOf("Submission Successful") != -1){
      $("#signupstep1").css("display", "none");
      $("#signupstep2").show('slow');
    } else if (response.indexOf("Invalid E-mail") != -1){
      $("#invalidemail").fadeIn(700);
    }
  }
  
  function testSecondResults(data){
    if (data['validation'] == "pass"){
        $("#signupstep2").css("display", "none");
        $("#signupstep3").show('slow');
        $("#successfulsubmit h3").append("Submission Successful");        
        $("#emailbox input").each(function(){
          $(this).prop("disabled", "disabled");
        });
        $("#submit").val('Thanks!');
    } else {
        $("#errormessage").empty().append(data['message']);
    }
  }
  
  var mathAnswer = 0;
  var startTime = 0;
  var endTime = 0;
  var submissionTime;
  
  function generateEquation(){
      var num1 = Math.floor(Math.random() * 5) + 1;
    var num2 = Math.floor(Math.random() * 5) + 1;
    mathAnswer = num1 + num2;
    $("#math").append("What is " + num1 + " + " + num2 + "?");
  }

This is the page the script should perform properly on. As you’ll see, the JS alert that pops up contains the PHP language as the data.

Thanks for your suggestions. I’m trying to find my way through this newbie IT jungle.

-Tyler

Weird. I just tried this on the live site version, and it seems to be passing in the submitted value okay. Has anyone used the local testing environment, XAMPP?

Hmm… It seems that the .show() and .hide() methods are not working to change the form content.

Can someone respond here? I’m quite lost (but finding my way a little bit more).

You expect HTML in your success() callback but receive PHP source code of emailtester.php instead, right?

All the PHP returns is HTML - a p> tag that contains one of these messages:

Submission Successful
Invalid e-mail
Submission Failure - Default Value in box
etc.

I’ll post the PHP script here if you’d like to see it.

However, the PHP script appears to be running A-okay at this point. I can re-add the JS alert that displays that PHP is running appropriately from the success callback. I’ll go ahead and do that so you can see what is occurring on the page and what PHP is returning.

Where I find myself stuck is that the JS .hide() and .show() functions are not making the form content change on the test page. More specifically, I want to hide .signupstep1 div (line 339) and show .signupstep2 content when the submission is successful. Nothing happens after submitting in the e-mail field.

-ty

The problem is in the selector. You’re trying to find #signupstep2 and there is no element with that id on the page.
But there is one with class instead:

<div class="signupstep2">
1 Like

Awesome! I could have figured, but thanks to you, it’s working! Check it out! I should be able to finish the rest of it all.

One other thing:
For the invalid e-mail case, the height of the sign up box “jumps” without smooth transition… which is driving my perfectionist side crazy. Is that a CSS issue or can JS be used to ease that transition?
You can see what I’m describing on the page.

Because you’re using .fadeIn()
That block doesn’t have any height initially but when you call .fadeIn() it instantly appears
To avoid that you can use slideDown() instead
or hide block with visibility:hidden instead of display:none

AWESOME!! It looks great on the test page. I’ve been able to do a lot of stuff on my own right now, and I’m feeling good. I love SitePoint!

Okay, I’m stuck again. I’m trying to return error messages and display the success/failure result to the user, but it doesn’t seem the second PHP script is running as I was unable to echo any of the script validation results into the console.

Is something wrong with my second .ajax() call?

Current script:

            $("#form2").submit(function(e){
            var origEmail = $('#go').val();
            var confirmEmail = $("#confirmemail").val();
            var name = $("#name").val();
            var age = $("#age").val();
            var gender = $("#gender").val();
            var country = $("#country").val();
            var catcher = $("#aicatcher").val();
            var addition = $("#addition").val();
            endTime = jQuery.now();
            submissionTime = endTime - startTime;
            
            e.preventDefault();
        
     $.ajax({
         type: "POST",
         dataType: 'json',
         cache: false,
         url: "Scripts/confirmform.php",
         data: { 
            origEmail: origEmail,
            confirmEmail: confirmEmail,
            name: name,
            age: age,
            gender: gender,
            country: country,
            catcher: catcher,
            addition: addition,
            mathAnswer: mathAnswer,
            submissionTime: submissionTime 
          },
          success: function(data) {
             testSecondResults(data);
          },
       });
    });

Do you want to see the PHP script as well?

The markup for the 2nd form begins at line 352 in the HTML on the linked page.

Your confirmform.php returns:

Array{"validation":"fail","errors":["Age must be numeric."],"database":" ","name":" ","email":" "}

This is not a correct JSON because of “Array” in beginning.
Looks like you forgot to remove temporary echo call or something like that
How your PHP script outputs result?

Current PHP, confirmform.php:

<?php $instance = new CheckForm; $instance -> checkSubmission(); class CheckForm { public function checkSubmission() { $origEmail = filter_input(INPUT_POST, 'origEmail', FILTER_SANITIZE_EMAIL); $confirmEmail = filter_input(INPUT_POST, 'confirmEmail', FILTER_SANITIZE_EMAIL); $name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING); $age = filter_input(INPUT_POST, 'age', FILTER_SANITIZE_NUMBER_INT); $gender = filter_input(INPUT_POST, 'gender', FILTER_SANITIZE_STRING); $country = filter_input(INPUT_POST, 'country', FILTER_SANITIZE_STRING); $catcher = filter_input(INPUT_POST, 'catcher', FILTER_SANITIZE_STRING); $mathAnswer = filter_input(INPUT_POST, 'addition', FILTER_SANITIZE_NUMBER_INT); $rightAnswer = filter_input(INPUT_POST, 'mathAnswer', FILTER_SANITIZE_NUMBER_INT); $submissionTime = filter_input(INPUT_POST, 'submissionTime'); $status = 1; $response = array("validation" => "fail", "errors" => array(), "database" => " ", "name" => " ", "email" => " "); if ($origEmail != $confirmEmail || empty($confirmEmail)) { $response['errors'][] = 'E-mail addresses don\'t match.'; $status = 0; } if (empty($name) || preg_match('/[^A-Za-z ]/', $name)) { $response['errors'][] = 'No name entered (name can only have letters).'; $status = 0; } if (!ctype_digit($age)) { $response['errors'][] = 'Age must be numeric.'; $status = 0; } if ($country == "Select Location") { $response['errors'][] = 'No location selected.'; $status = 0; } if ($mathAnswer != $rightAnswer) { $response['errors'][] = 'Math answer incorrect.'; $status = 0; } if (!empty($catcher)){ $response['errors'][] = 'Bot submission.'; $status = 0; } if ($submissionTime < 9000){ $response['errors'][] = 'Form submitted too quickly.'; $status = 0; } echo $response['errors']; if ($status == 1) { require_once("categoryfinder.php"); $categoryFinder = new CategoryFinder; $category = $categoryFinder -> getCategory(); $response['validation'] = "pass"; $response['name'] = $name; $response['email'] = $confirmEmail; require_once('databasewriter.php'); $dbWriter = new DatabaseWriter; $dbCode = $dbWriter -> writeUserToDatabase($confirmEmail, $name, $age, $gender, $country, $category); if ($gender == "Male") $gender = "M"; elseif ($gender == "Female") $gender = "F"; else $gender = NULL; if ($dbCode == 1) { $response['database'] = "pass"; require_once('emailsender.php'); $emailSender = new EmailSender; $emailSender -> sendWelcomeEmail($confirmEmail, $name); } else { $response['database'] = "fail"; $response['validation'] = "fail"; } if ($dbCode == 2) { $response['errors'] = "Server error. Please try again later or let us know about the issue."; } elseif ($dbCode == 3) { $response['errorMessage'] = "That e-mail address already exists!"; } echo ("Database code entry: " + $dbCode); } echo json_encode($response); } } ?>

I alerted all those values in JS to ensure null values weren’t being passed in, but it seems there is still an issue of communication of data between the JS and PHP.

I think this line is causing the problem
remove it and check is it works

Hmm… The form still just sits there when submit button is hit and after I removed that line.
I just updated the files on the test page.

First of all, your PHP script always returns error “Age must be numeric” but i don’t see a possibility to make it numeric.

Then, this code is not working:

$("#errormessage ul").slideDown(300).css("display", "list-item");
var fragment = document.createDocumentFragment();
$.each(data['errors'], function (i, e) {
    var item = document.createElement('li');
    if (typeof item.textContent === "string") {
            item.textContent = e;
        } else {
            item.innerText = e;
        }
        fragment.appendChild(item);
    });
    $("#errormessage ul").empty().append(fragment.childNodes);

This is how you react on the errors. The problems is:

  1. You’re trying to find #errormessage ul while there is no such element. It should be ul#errormessage.
  2. Why don’t you use jQuery to create list items? Your approach with fragment doesn’t work anyway.

How i would rewrite this part of code:

$("ul#errormessage").html('');

for (var i in data.errors){
	var li = $('<li></li>');
	li.html(data.errors[i]);
	$("ul#errormessage").append(li);
}

$("ul#errormessage").slideDown(300);

Yes, you are correct, and it seems to be working now!!

I took out the conditional statement to test for the age to be numeric.
I see that the target I was using for the unordered list was not right.

Okay, last problem occurring is really strange. I seem to be all finished, but there is a glitch when the same e-mail address is supplied in the forms twice. My script is set up to catch duplicate entries in the database table. It is caught in the conditional statement:

          if ($dbCode == 1) { 
            $response['database'] = "pass"; 
            require_once('emailsender.php');
            $emailSender = new EmailSender;
            $emailSender -> sendWelcomeEmail($confirmEmail, $name);
          } else {
            $response['database'] = "fail"; 
            $response['validation'] = "fail"; 
          } 
          if ($dbCode == 2) { 
            $response['errors'] = "Server error. Please try again later or <a href=\"mailto:admin@worldreviewgroup.com\">let us know</a> about the issue."; 
          } elseif ($dbCode == 3) { 
            $response['errors'] = "That e-mail address already exists!"; 
          } 

When the error message, “That e-mail address already exists!”, is thrown, the JS displays each and every character as a separate list item, and it breaks the layout by taking up a crazy amount of vertical space. Weird! :expressionless:

Does it have to do with this code?

        for (var i in data.errors){
            var li = $('<li></li>');
            li.html(data.errors[i]);
            $("ul#errormessage").append(li);
        }

Thanks

-Ty

edit: Check it out on the linked test site. This is weird!

Not weird at all considering errors is a string. Can there be multiple error messages displayed or only one.

More than one error can be lumped in to the same #errormessage ul element.