简体   繁体   中英

jQuery Post via Ajax to PHP Validation Script

I know I can use the form validation plugin with jQuery UI but for the sake of teaching myself some new tricks I'm taking this approach.

I have a jQuery script that posts a form to a PHP script via Ajax. The script then validates the input and sends a JSON encoded string back to the script. At this point, based on the status a validation message should be placed into a modal dialog and then opened to tell the user what happened.

Issue

It seems the script is returning a "null" status. In Chrome's JavaScript console the following line appears after clicking on the submit button of the form:

Uncaught TypeError: Cannot read property 'status' of null 

Here's my validate_form.js

$(document).ready(function() {
    $("#contact_submit").on("click", function(e){
        e.preventDefault();
        var dataString = $("#frm_contact").serialize();
        console.log(dataString);
        $.ajax({
            type: "POST",
            url: "contact.php",
            data: dataString,
            dataType: "json",
            cache: false,
            success: function(data){
                console.log(data);
                if(!data){
                    alert("null value returned");
                }else if(data.status > 0){
                    $("#response").dialog({
                        autoOpen: false,
                        modal: true,
                        height: 240,
                        width: 320
                    });

                    $("#response").dialog("open");
                };
            }
        });
    });
});

And here is contact.php

<?php
    if(isset($_POST['contact_submit'])){
        $name = trim($_POST['contact_name']);
        $name = ucwords($name);
        $email = trim($_POST['contact_email']);
        $email = strtolower($email);
        $dept = trim($_POST['contact_dept']);
        $dept = ucwords($dept);
        $notes = trim($_POST['contact_notes']);

        // Patterns and Comparison Qualifiers
            $name_pattern = "/^[a-z][a-z ]*$/i";
            $email_pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/";
            $avail_depts = array("General", "Sales", "Support");
            $notes_minlength = 25;
            $notes_maxlength = 500;

        if(!preg_match($name_pattern, $name)){
            $resp = array("status"=>1, "message"=>"Names may only contain letters and spaces");
        }else{
            if(!preg_match($name_pattern, $name)){
                $resp = array("status"=>2, "message"=>"Invalid e-mail address");
            }else{
                if(!in_array($dept, $avail_depts)){
                    $resp = array("status"=>3, "message"=>"Please select a department");
                }else{
                    if(strlen($notes) < $notes_minlength || strlen($notes) > $notes_maxlength){
                        $resp = array("status"=>4, "message"=>"Comments must be between 25 and 500 characters");
                    }else{
                        // Build the message and e-mail it
                            $to = "info@mydomain.com";
                            $headers = "From: ".$name." <".$email.">";
                            $message .= "Contact Form Submission\n";
                            $message .= "==========================\n\n";
                            $message .= "Contact Name: ".ucwords($name)."\n\n";
                            $message .= "Contact E-mail: ".$email."\n\n";
                            $message .= "Category: ".$dept."\n\n";
                            $message .= "Comments: ".$notes."\n\n";
                            $message .= "\n";

                            if(mail($to, $subject, $message, $headers)){
                                $resp = array("status"=>5, "message"=>"Thanks! We'll be in touch soon!");
                            }else{
                                $resp = array("status"=>6, "message"=>"Something went wrong, please try again");
                            }
                    }
                }
            }
        }
    }

    echo json_encode($resp);
?>

UPDATE 1

Adding console.log(dataString); yields the following in the console:

contact_name=Test&contact_email=testaccount%40mydomain.com&contact_dept=general&contact_notes=this+is+a+test+

As you can see it should've failed on the notes not being between 25 and 500 characters and returned the proper error message. Instead I still see the "cannot read property 'status' of (null)"

UPDATE 2

Here is exactly what I see in the JavaScript Console JavaScript控制台

UPDATE 3

I decided to remove the prevent default and actually post directly to the contact page through a traditional <form> statement that includes the method="post" action="contact.php" to see if the script itself was properly generating the JSON string and it is; here's what it generated on my most recent test:

{"status":4,"message":"Comments must be between 25 and 500 characters"}

So either it's not sending it back to the ajax handler or something else is missing.

UPDATE 4

I modified the script to handle a null value and alert me if no value was passed. So it's obvious now that the script isn't passing a json string back to the ajax call even though in update 3 I've verified that it's echoing one to the screen. I'm at a loss... (Update script above)

UPDATE 5

So I've made some progress. It turns out that the null was being returned because in my PHP script I was checking if the submit button was set and part of the $_POST array. But, because I'm preventing the default action of the form through jQuery it's not being passed. Only the form values that are serialized are being sent in the dataString . So now I'm getting the errors back in the console that I expect but I'm not getting the modal dialog to show up. The drama continues.

Most browsers support JSON.parse(), which is defined in ECMA-262 5th Edition (the specification that JS is based on). Its usage is simple:

var json = '{"result":true,"count":1}', obj = JSON.parse(json);

alert(obj.count);

For the browsers that don't you can implement it using json2.js.

As noted you're already using jQuery, there is a $.parseJSON function that maps to JSON.parse if available or a form of eval in older browsers. However, this performs additional, unnecessary checks that are also performed by JSON.parse, so for the best all round performance I'd recommend using it like so:

var json = '{"result":true,"count":1}', obj = JSON && JSON.parse(json) || $.parseJSON(json);

This will ensure you use native JSON.parse immediately, rather than having jQuery perform sanity checks on the string before passing it to the native parsing function.

Below i've mentioned some points try this to sort out your problem 1.change your method to get and try.

2.put die() after last echo and check what the exactly output.

So after more hours tweaking, testing, and pulling my hair out, here's the working script.

jQuery

$(document).ready(function() {
    $("#contact_submit").on("click", function(e){
        e.preventDefault();
        var dataString = $("#frm_contact").serialize();
        console.log(dataString);
        $.ajax({
            type: "POST",
            url: "contact.php",
            data: dataString,
            dataType: "json",
            cache: false,
            success: function(data){
                console.log(data);
                if(!data){
                    alert("null value returned");
                }else if(data.err > 0){
                    var $response = $("<div></div>")
                    .dialog({
                        resizable: false,
                        autoOpen: false,
                        modal: true,
                        height: "auto",
                        width: "auto",
                        buttons: { "ok": function() { $(this).dialog("close"); } }
                    });
                    $response.html("Error:");
                    $response.html(data.message);
                    $response.dialog("open");
                    $(".ui-dialog-titlebar").hide();
                };
            }
        });
    });
});

And for the PHP script I had to tweak it slightly as well to process it properly.

<?php
        $name = trim(urldecode($_POST['contact_name']));
        $name = ucwords($name);
        $email = trim(urldecode($_POST['contact_email']));
        $email = strtolower($email);
        $dept = trim($_POST['contact_dept']);
        $dept = ucwords($dept);
        $notes = trim(urldecode($_POST['contact_notes']));

        // Patterns and Comparison Qualifiers
            $name_pattern = "/^[a-z][a-z ]*$/i";
            $email_pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/";
            $avail_depts = array("General", "Sales", "Support");
            $notes_minlength = 25;
            $notes_maxlength = 500;

        if(!preg_match($name_pattern, $name)){
            $resp = array("err"=>1, "message"=>"Names may only contain letters and spaces");
        }else{
            if(!preg_match($email_pattern, $email)){
                $resp = array("err"=>2, "message"=>"Invalid e-mail address");
            }else{
                if(!in_array($dept, $avail_depts)){
                    $resp = array("err"=>3, "message"=>"Please select a department");
                }else{
                    if(strlen($notes) < $notes_minlength || strlen($notes) > $notes_maxlength){
                        $resp = array("err"=>4, "message"=>"Comments must be between 25 and 500 characters");
                    }else{
                        // Build the message and e-mail it
                            $headers = "From: ".$name." <".$email.">";
                            $message .= "Contact Form Submission\n";
                            $message .= "==========================\n\n";
                            $message .= "Contact Name: ".ucwords($name)."\n\n";
                            $message .= "Contact E-mail: ".$email."\n\n";
                            $message .= "Category: ".$dept."\n\n";
                            $message .= "Comments: ".$notes."\n\n";
                            $message .= "\n";

                            if(mail($to, $subject, $message, $headers)){
                                $resp = array("err"=>5, "message"=>"Thanks! We'll be in touch soon!");
                            }else{
                                $resp = array("err"=>6, "message"=>"Something went wrong, please try again");
                            }
                    }
                }
            }
        }
    echo json_encode($resp);
?>

Everything works perfectly, modal alerts and all to the user. Thanks to those who attempted to help!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM