新手Ajax(jquery)问题

I'm pretty strong with PHP, but javascript is totally new to me.

I need to add various ajax functionality to my projects, for example for form validation etc.

I've done some searching, watched some tutorials, and come up with a basic working example as follows:

index.php:

<!DOCTYPE html>
<html lang="en">
<head>

<title>Ajax form test</title>

<style>
    form input, form textarea {
        display:block;
        margin:1em;
    }

    form label {
        display:inline;
    }

    form button {
        padding:1em;
    }
</style>
</head>
<body>

<h2>CONTACT FORM</h2>

<div id="form_content">
    <form method="post" action="server.php" class="ajax">

            <label for="name" value="name">name:</label>
            <input type="text" name="name" placeholder="name" />

            <label for="email" value="email">email:</label>
            <input type="email" name="email" placeholder="email" />

            <label for="message" value="message">message:</label>
            <textarea name="message" placeholder="message"></textarea>

            <input type="submit" value="send">

    </form>
</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="main.js"></script>

</body>
</html>

main.js:

$('form.ajax').on('submit', function() {

console.log('trigger');

var that = $(this),
    url = that.attr('action'),
    type = that.attr('method'),
    data = {};

    that.find('[name]').each(function(index, value) {
        var that = $(this),
            name = that.attr('name'),
            value = that.val();

        data[name] = value;
    });

$.ajax ({

    url:    url,
    type:   type,
    data:   data,
    success: function(response) {
        console.log(response);
        $('#form_content').load('server.php', data);
    }

});

return false;
});

and finally, server.php:

<?php

if (isset($_POST) AND $_POST['name'] !='' AND $_POST['email'] !='' AND $_POST['message'] !='')
{
?>
<h4>Your data was submitted as follows</h4>

<br />name: <?=$_POST['name']?>
<br />email: <?=$_POST['email']?>
<br />message: <?=$_POST['message']?>

<?php
} else {
?>
<h3>please fill in all form data correctly:</h3>

<form method="post" action="server.php" class="ajax">

        <label for="name" value="name">name:</label>
        <input type="text" name="name" placeholder="name" />

        <label for="email" value="email">email:</label>
        <input type="email" name="email" placeholder="email" />

        <label for="message" value="message">message:</label>
        <textarea name="message" placeholder="message"></textarea>

        <input type="submit" value="send">

</form>

<?php
}

This all works fine, in that if I enter all form data and click submit, the ajax magic happens and I get a confirmation of the data. Also if not all data is loaded, the form is re-presented on the page. The problem is that in such a case, continuing to fill out the form data and then submit it loads the server.php page instead of repeating the ajax call until the form data is valid..

I'm sure there's a better way to do this as it's my first attempt, but I haven't been able to find any solution by searching either here or on google, but that's probably mostly because I don't really know what to search for. how can I make the behaviour in the first instance repeatable until the form is submitted correctly ?

This happens because you are removing your form element during your load() call and overwrite it with a new version of the form. Therefore all attached event handlers will vanish along with it.

You will need to use a delegate on an element that does not change:

$('#form_content').on('submit', 'form.ajax', function() {...});

Explanation:

In the above example, you attach the event listener to the #form_content element. However, it only listens to events that bubble up from the form.ajax submit event. Now, if you replace the form with a new version, the existing handler is attached higher up in the chain (on an element that doesn't get replaced) and continues to listen to events from lower elements, no matter if they change or not... therefore it will continue to work.

Your primary problem is that you are validating the form on the PHP side, when you should really validate it on the client side - THEN, instead of returning an appropriate response and continuing processing on the client side, you are finishing processing on the PHP side. Steve's answer (above) applies to what you are seeing.

As to the approach you have taken, it might be better to not use a <form> construction at all, because with AJAX you often don't need to. In my opinion, <form> is an archaic structure, not often needed in the age of AJAX. Notice how you had to add return false following the AJAX block to abort the default form functionality -- to stop it from sending the user over to server.php? That should tell you something.

Here is another way to structure it:

HTML:

<body>

<h2>CONTACT FORM</h2>

<div id="form_content">
    <label for="name" value="name">name:</label>
    <input type="text" name="name" placeholder="name" />

    <label for="email" value="email">email:</label>
    <input type="email" name="email" placeholder="email" />

    <label for="message" value="message">message:</label>
    <textarea name="message" placeholder="message"></textarea>

    <input type="button" id="mybutt" value="send">
</div>
<div id="responseDiv"></div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="main.js"></script>

</body>

JAVASCRIPT/JQUERY:

$(document).ready(function() {

    //Next line's construction only necessary if button is injected HTML
    //$(document).on('click', '#mybutt', function() {

    //Otherwise, use this one:
    $('#mybutt').click(function() {
        console.log('trigger');

        var valid = "yes";

        var that = $(this),
            url = "server.php",
            type = "POST",
            data = {};

        that.find('[name]').each(function(index, value) {
            var that = $(this),
                name = that.attr('name'),
                value = that.val();
                if (value=="") valid = "no";

            data[name] = value;
        });

        if (valid == "yes") {
            $.ajax ({
                url:    url,
                type:   type,
                data:   data,
                success: function(response) {
                    console.log(response);

                    $('#responseDiv').html(response);

                    /* OPTIONALLY, depending on what you make the PHP side echo out, something like:

                    if (response == "allgood") {
                        window.location.href = "http://www.google.com";
                    }else{
                        //this is how you would handle server-side validation
                        alert('Please complete all fields');
                    }

                    */
                }
            }); //END AJAX
        }else{
            alert('Please complete all fields');
        }

    }); //END button.click


}); //END document.ready

PHP Side: server.php

<?php

    if (isset($_POST) AND $_POST['name'] !='' AND $_POST['email'] !='' AND $_POST['message'] !='') {
        $r = '';
        $r .= "<h4>Your data was submitted as follows</h4>";
        $r .= "<br />name: " . $_POST['name'];
        $r .= "<br />name: " . $_POST['email'];
        $r .= "<br />name: " . $_POST['message'];

    } else {

        $r = "Please complete all form fields";

    }

    echo $r;