How to validate input data using ajax in laravel

28,216

Solution 1

Your approach is actually not wrong, it's just, you need to catch the error response on your ajax request. Whereas, when Laravel validation fails, it throws an Error 422 (Unprocessable Entity) with corresponding error messages.

/**Ajax code**/
$.ajax({
    type: "post",
    url: "{{ url('/verifydata') }}",
    data: {name: name,  _token: token},
    dataType: 'json',              // let's set the expected response format
    success: function(data){
         //console.log(data);
         $('#success_message').fadeIn().html(data.message);
    },
    error: function (err) {
        if (err.status == 422) { // when status code is 422, it's a validation issue
            console.log(err.responseJSON);
            $('#success_message').fadeIn().html(err.responseJSON.message);
            
            // you can loop through the errors object and show it to the user
            console.warn(err.responseJSON.errors);
            // display errors on each form field
            $.each(err.responseJSON.errors, function (i, error) {
                var el = $(document).find('[name="'+i+'"]');
                el.after($('<span style="color: red;">'+error[0]+'</span>'));
            });
        }
    }
});
/**Ajax code ends**/   

On your controller

public function testAjax(Request $request)
{
    // this will automatically return a 422 error response when request is invalid
    $this->validate($request, ['name' => 'required']);

    // below is executed when request is valid
    $name = $request->name;

    return response()->json([
         'message' => "Welcome $name"
    ]);

  }

Solution 2

Here's a better approach to validation:

In your controller:

public function testAjax(Request $request)
{
   $this->validate($request, [ 'name' => 'required' ]);
   return response("welcome ". $request->input('name'));
}

The framework then will create a validator for you and validate the request. It will throw a ValidationException if it fails validation.

Assuming you have not overriden how the validation exception is rendered here's the default code the built-in exception handler will run

protected function convertValidationExceptionToResponse(ValidationException $e, $request)
{
        if ($e->response) {
            return $e->response;
        }
        $errors = $e->validator->errors()->getMessages();
        if ($request->expectsJson()) {
            return response()->json($errors, 422);
        }
        return redirect()->back()->withInput($request->input())->withErrors($errors);
}

Again this is handled for you by the framework.

On the client side you should be able to do:

<script>
  $(document).ready(function(){
      $("#submit").click(function(){
        var name = $("#name").val();
        var token = $("#token").val();
        /**Ajax code**/
        $.ajax({
           type: "post",
           url:"{{URL::to('/verifydata')}}",
           data:{name:name,  _token: token},
           success:function(data){
              //console.log(data);
              $('#success_message').fadeIn().html(data);
           },
           error: function (xhr) {
               if (xhr.status == 422) {
                   var errors = JSON.parse(xhr.responseText);
                   if (errors.name) {
                       alert('Name is required'); // and so on
                   }
               }
           }
        });
          /**Ajax code ends**/    
      });
  });
</script>
Share:
28,216

Related videos on Youtube

RajB009
Author by

RajB009

Updated on July 09, 2022

Comments

  • RajB009
    RajB009 almost 2 years

    testAjax function inside PostsController class:

    public function testAjax(Request $request)
      {
        $name = $request->input('name');
        $validator = Validator::make($request->all(), ['name' => 'required']);
    
        if ($validator->fails()){
            $errors = $validator->errors();
            echo $errors;
        }
        else{
          echo "welcome ". $name;
        }
    
      }
    

    inside web.php file:

    Route::get('/home' , function(){
      return view('ajaxForm');
    });
    
    Route::post('/verifydata', 'PostsController@testAjax');
    

    ajaxForm.blade.php:

    <script src="{{ asset('public/js/jquery.js') }}"></script>
    
      <input type="hidden" id="token" value="{{ csrf_token() }}">
      Name<input type="text" name="name" id="name">
      <input type="button" id="submit" class="btn btn-info" value="Submit" />
    <script>
      $(document).ready(function(){
          $("#submit").click(function(){
            var name = $("#name").val();
            var token = $("#token").val();
            /**Ajax code**/
            $.ajax({
            type: "post",
            url:"{{URL::to('/verifydata')}}",
            data:{name:name,  _token: token},
            success:function(data){
                    //console.log(data);
                    $('#success_message').fadeIn().html(data);
                }
              });
              /**Ajax code ends**/    
          });
      });
    </script>
    

    So when click on submit button by entering some data then the output message(echo "welcome ". $name;) is printing. But when I click on submit button with empty text box then it does not print the error message from the controller and it throws a 422 (Unprocessable Entity) error in console. Why my approach is wrong here and how can I print the error message then. Please help. Thank you in advance. enter image description here enter image description here

  • Luis Rodriguez
    Luis Rodriguez over 2 years
    This is great. The only thing I don't like is that the error is shown multiple times when the error persists and the user presses the submit button again.