Question

As of right now, I have created a simple contact form.

Currently, I need to reload the page if I want to validate anything with PHP (I already have Client side validation in place).

However, I want to do this without reloading my page. Since I have no experience with ajax I was confused by all the examples I saw on the internet.

I would also like to use jQuery $.post() if possible, but I think ajax does the same.

Here is the simple markup:

<form id="myForm" method="POST" action="">

    <input name="name" class="<? if($errorsArray['email']) {echo "error";} ?>" type="email" required><br>
    <input name="comment" class="<? if($errorsArray['name']) {echo "error";} ?> " type="text" required><br>

    <input name="submit" type="submit" value="Send">

</form>

My PHP:

$requiredFields = array('name', 'comment');
foreach ($requiredFields as $field) {
    $errorsArray[$field] = true;
}

I echo "error" in the class attribute to signify an error. However, this requires me to reload the page, which I do not want to do. (I also do the same way to keep the already submitted values is there is an error).

How would I use ajax to give each field (with errors) the class addition: error?

If you need any more code, I will be more than happy to give it, just give me a comment.

Was it helpful?

Solution

First, I start from the server-side.

Since you want to submit the form via XHR request, the server should return the data as a JSON object.

Using JSON, you could have a structured data containing result and probable errors.

So, in your PHP file to which the form will send the request:

# Check whether the validation was successful
if ($validated === true) {
    # Do your logic...
    # Insert the posted data into database... etc.

    # show success message
    $response = array(
        'error'  => null,
        'result' => array(
            'message' => "Successfully message..."
        )
    );        
} else {
    # Show the error message
    $response = array(
        # In this case, get_readable_errors() method returns an array
        # which contains the 'name' of the invalid fields as key
        # and the validation error as value
        # e.g.
        #
        # 'error' = array(
        #     'name'    => 'Validation error for name field',
        #     'comment' => 'Validation error for comment field'
        # ),
        'error' => $validator->get_readable_errors(),
        'result' => null
    );
}

# send the output as JSON
echo json_encode($response);

Then, at the client-side, you need to prevent the default submission of the form.

Using jQuery, you could use .submit() method to bind a handler to the submit event:

var $form = $('#myForm'),

_updateView = function(data, $form) {
    data.error === null             &&
    _showResult(data.result, $form) ||
    _showError(data.error, $form);
},

// This function triggers if the ouput data has no error
_showResult = function(result, $form) {

    // Clear all error messages
    // Remove the old success message
    // Insert the Success message
    // Reset the form
    $form[0].reset();

    return true;
},

// This function triggers if the output is an error
_showError = function(error, $form) {
    // Clear old success message
    // Clear all old errors

    // Show the error message of each field
    $.each(error, function(field, err) {
        $('input[name="'+ field +'"]')
            .addClass('error')
            // Insert the error message of the relevant field (optional)
            .after('<small class="error">'+ err +'</small>');
    });
};

The AJAX call, using $.ajax():

$form.submit(function(e) {
    /* Prevent the default submission */
    e.preventDefault();

    $.ajax({
        url      : 'PHP/file/URL',
        type     : 'POST',
        dataType : 'json',  /* <-- Parse the response as JSON object */
        data     : $form.serialize(),

        success: function(data) {
            // Update the view
            _updateView(data, $form);
        },

        error: function(jqXHR, textStatus, errorMessage) {
            console.log(errorMessage); // Optional
        }
    });
});

Hope this helps.

Update

I've just noticed your comment states:

I already do that with the client side validation. I want to use php validation as well, if the client side fails (javascript disabled)

First, never rely on the client-side validating. The client can easily disable the JavaScript and POST the harmful data.

Second, since using AJAX is possible only if the JavaScript is enabled, if you need to push the PHP output in HTML format on non-AJAX requests, you could pass a ajax=true key/value pair to the server, and return the output as JSON to the view.

In $.ajax() method:

data : $form.serialize() + '&ajax=true',

Then check the existence and value of $_POST['ajax'] at the server-side and determine whether to send the output as JSON or not.

You could also determine the XHR request by checking the HTTP_X_REQUESTED_WITH in $_SERVER as follows:

function is_xhr_request()
{
    return ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
}

OTHER TIPS

The basic outline is that you need to use jQuery to send a post request (and override the default submit function of the form) which would reload the page. That post request is sent to your php page which will do the validation and send the result back to jQuery. Then you use jQuery to set class=error on the relevant input elements based on what the php script returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top