1
\$\begingroup\$

I am trying to use the back end validation for front end validation and this is what I got. Maybe there is a better way to do this? If someone knows please share the knowledge.

HTML:

<form id="post-store-form" action="posts/store" method="POST">
    <div class="form">
        <input id="post-title" type="text" name="title" class="form-control" placeholder="Title">
        <br>
        <textarea id="post-content" name="content"></textarea>
        <hr>
        <input type="submit" value="Save" class="btn btn-primary btn-block">
    </div>
</form>
<p id="ajax-response"></p>

JS:

$('#post-store-form').submit( function(e) {

    if (!isValid()) {
        e.preventDefault();
    }
});

function isValid() {

    var formIsValid = false;
    var fields = jQuery.param({
        title: $('#post-title').val(),
        content: $('#post-content').val()
    });

    $.ajax({
        async: false,
        type: "POST",
        url: "/posts/store",
        data: fields,
        dataType: 'json',
        success: function(){
            formIsValid = true;
        },
        error: function(result) {
            var messages = [];

            $.each(result.responseJSON.errors, function( index, value ) {
                messages.push('<br>' + value);
            });

            bootbox.alert("<strong class='text-danger'>" + messages + "</strong>");
        }
    });

    return formIsValid;
}

PHP Controller:

public function postStore()
{
    $headers = apache_request_headers();
    $is_ajax = (isset($headers['X-Requested-With']) && $headers['X-Requested-With'] == 'XMLHttpRequest');

    $parameters = $this->formParams;
    $validationRules = [
        'title'     => 'required|alnum',
        'content'   => 'required',
    ];

    // if validation fails return back with error messages
    if ($this->validatorFails($parameters, $validationRules)) {
        if ($is_ajax) {
            $errors = $this->getValidatorErrors($validationRules);
            http_response_code(422);
            echo json_encode(['errors' => $errors]);
            die;
        }
    }

    // if no errors and ajax, return 200
    if ($is_ajax) {
        http_response_code(200);
        echo json_encode([]);
        die;
    }

    // create new user in DB
    $this->createPostFromParams($parameters);

    Session::put('success', 'Successfully created a post.');

    return redirect('posts');
}

Is there a better way to integrate the backend validation to be also the front end validation?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You should separate it in different functions. Here is how you can have validation in different functions and use it in both places - for creating posts and for front-end validation. Besides you should extract this validation logic elsewhere, it's bad to put such logic in your controller.

public function postValidateStore()
{

    $requestValidation = $this->validateStore();

    if($requestValidation !== true){

       die($requestValidation);
    }

    die(json_encode(['success' => 1]));

}


/**
 * @return mixed
 */
public function postStore()
{

    $requestValidation = $this->validateStore();

    if($requestValidation === true){

        // create new user in DB
        $this->createPostFromParams($this->formParams);

        Session::put('success', 'Successfully created a post.');

    } else {

        Session::put('failure', 'Error creating post.');
    }

    return redirect('posts');
}

/**
 * @return bool|false|string
 */
private function validateStore()
{

    $parameters = $this->formParams;
    $validationRules = [
        'title'     => 'required|alnum',
        'content'   => 'required',
    ];

    // if validation fails return back with error messages
    if ($this->validatorFails($parameters, $validationRules)) {

        return json_encode(['errors' => $this->getValidatorErrors($validationRules)]);
    }

    return true;
}

function isValid() {

var formIsValid = false;
var fields = jQuery.param({
title: $('#post-title').val(),
content: $('#post-content').val()
});

$.ajax({
    async: false,
    type: "POST",
    url: "/posts/ValidateStore",
    data: fields,
    dataType: 'json',
    success: function(result){


        if(typeof result.success == "undefined"){

            var messages = [];

            $.each(result.errors, function( index, value ) {
                messages.push('<br>' + value);
            });

            bootbox.alert("<strong class='text-danger'>" + messages + "</strong>");

        } else {

            formIsValid = true;
        }

    }

});

return formIsValid;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.