2013-06-13 13 views
16

Hiện nay tôi sử dụng để hiển thị lỗi xác nhận qua ajax:lỗi Validation trong chế độ AJAX

  if (data.validation_failed == 1) 
      { 
       var arr = data.errors; 
       $.each(arr, function(index, value) 
       { 
        if (value.length != 0) 
        { 
         $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>'); 
        } 
       }); 
       $('#ajax-loading').hide(); 
       $("#validation-errors").show(); 
      } 

Nó hoạt động tốt, thực hiện chính xác những gì tôi cần.

Vấn đề là những gì tôi phải làm gì để vận chuyển các lỗi từ laravel để ajax:

$rules = array( 
     'name' => 'required', 
     'password' => 'required' 
    ); 

    $v = Validator::make(Input::all(), $rules); 

    if (! $v->passes()) 
    { 

    $messages = $v->messages(); 

    foreach ($rules as $key => $value) 
    { 
     $verrors[$key] = $messages->first($key); 
    } 

     if(Request::ajax()) 
     {      
      $response_values = array(
       'validation_failed' => 1, 
       'errors' => $verrors);    
     return Response::json($response_values); 
     } 
     else 
     { 
     return Redirect::to('login') 
      ->with('validation_failed', 1) 
      ->withErrors($v); 
     }  

    } 

Nếu tôi muốn có các tên trường như chìa khóa, tôi phải lặp $ quy tắc, nhưng ngay cả khi tôi không sử dụng tên trường là khóa, nhưng tôi phải lặp lại thông báo lỗi để tạo $ verrors.

Làm cách nào để chuyển đổi $v->messages() thành tương đương với $verrors mà không cần lặp lại? Vì Response::json() đang mong đợi một mảng thay vì một đối tượng.

Trả lời

61

Cách dễ nhất là tận dụng đối tượng MessageBag của trình xác thực. Điều này có thể được thực hiện như thế này:

// Setup the validator 
$rules = array('username' => 'required|email', 'password' => 'required'); 
$validator = Validator::make(Input::all(), $rules); 

// Validate the input and return correct response 
if ($validator->fails()) 
{ 
    return Response::json(array(
     'success' => false, 
     'errors' => $validator->getMessageBag()->toArray() 

    ), 400); // 400 being the HTTP code for an invalid request. 
} 
return Response::json(array('success' => true), 200); 

Điều này sẽ cung cấp cho bạn một phản ứng JSON như thế này:

{ 
    "success": false, 
    "errors": { 
     "username": [ 
      "The username field is required." 
     ], 
     "password": [ 
      "The password field is required." 
     ] 
    } 
} 
+1

Đây có thể là một lời nhận xét ngu ngốc - nhưng không thiết lập mã http đến 400 có nghĩa là phản ứng JSON là hoàn toàn bị bỏ qua? – Beans

+2

Phụ thuộc vào 'khách hàng' đang đọc JSON. jQuery ví dụ xử lý này hoàn toàn tốt đẹp. Nó không kích hoạt thành công, nhưng gọi lại lỗi, đó là những gì bạn muốn. – DerLola

+1

Sử dụng jQuery, bạn có thể gặp lỗi khi sử dụng mã này trong yêu cầu ajax: 'error: function (xhr, status, data) { console.log (xhr.responseJSON.errors); } ' – Yako

8

Trong phản ứng ajax cố gắng một cái gì đó giống như

.fail(function(data) { 
     var response = JSON.parse(data.responseText); 
     var errorString = '<ul>'; 
     $.each(response.errors, function(key, value) { 
      errorString += '<li>' + value + '</li>'; 
     }); 
     errorString += '</ul>'; 
1

Tôi đang sử dụng Laravel 5.1 bằng cách này nhưng tôi nghĩ rằng các nguyên tắc cơ bản của điều này nên áp dụng cho các phiên bản khác. Laravel tự động gửi trả lời xác nhận lỗi xác thực. Bạn chỉ có thể làm như sau trong điều khiển của bạn:

public function processEmail(Request $request) 
{ 
    $this->validate($request, [ 
     'email' => 'required|email' 
    ]); 
    return response()->json(['message'=>'success']); 
} 

Sau đó, trong javascript của bạn (Tôi đang sử dụng jQuery đây):

var params = {email: '[email protected]'}; 
$.ajax({ 
    url: '/test/example', 
    method: 'POST', 
    data: params 
}) 
.done(function(data) { 
    // do something nice, the response was successful 
}) 
.fail(function(jqXHR, textStatus, errorThrown) { 
    var responseMsg = jQuery.parseJSON(jqXHR.responseText); 
    var errorMsg = 'There was a general problem with your request'; 
    if (responseMsg.hasOwnProperty('email')) { 
     errorMsg = responseMsg.email; 
     console.log(errorMsg); 
    } 
    // This will help you debug the response 
    console.log(jqXHR); 
    console.log(textStatus); 
    console.log(errorThrown); 
}); 

Nếu bạn nhìn vào sản lượng trên giao diện điều khiển bạn sẽ sớm xem cách lấy bất cứ thứ gì bạn muốn từ phản hồi được Laravel gửi lại. Trong phản hồi đó, các thông báo lỗi nằm trong json dưới dạng cặp khóa-giá trị trong đó khóa là tên của trường không xác thực, trong ví dụ 'email' của tôi. Hãy nhớ đảm bảo tuyến đường ajax được thiết lập trong tệp routes.php của bạn và phương thức (get/post) khớp với trong javascript.

1

Có cách tốt hơn để xử lý các lỗi xác thực khi sử dụng yêu cầu Ajax.

Tạo một lớp Yêu cầu như thường lệ, ví dụ UploadFileAjaxRequest:

public function rules() 
{ 
    return [ 
     'file' => 'required' 
    ]; 
} 

Sử dụng nó trong một phương pháp điều khiển:

public function uploadFileAjax(UploadFileAjaxRequest $request) 

Nếu có bất kỳ lỗi, nó sẽ trả về một mảng các lỗi mà bạn có thể sử dụng trong JS:

$.ajax({ 
    .... 
    error: function(data) { 
     var errors = data.responseJSON; // An array with all errors. 
    } 
}); 
2

Lara vel 5 lợi nhuận xác nhận lỗi tự động

cho rằng bạn chỉ cần làm sau điều,

Bộ điều khiển:

public function methodName(Request $request) 
{ 
    $this->validate($request,[ 
     'field-to-validate' => 'required' 
    ]); 

    // if it's correctly validated then do the stuff here 

    return new JsonResponse(['data'=>$youCanPassAnything],200); 
} 

Xem:

  $.ajax({ 
      type: 'POST', 
      url: 'url-to-call', 
      data: { 
       "_token": "{{ csrf_token() }}", 
       "field": $('#field').cal() 
      }, 
      success: function (data) { 
       console.log(data); 
      }, 
      error: function (reject) { 
       if(reject.status === 422) { 
        var errors = $.parseJSON(reject.responseText); 
        $.each(errors, function (key, val) { 
         $("#" + key + "_error").text(val[0]); 
        }); 
       } 
      } 
     }); 

bạn có thể xây dựng cho từng lĩnh vực validation một thẻ <span> có id là tên trường và hậu tố _error do đó nó sẽ hiển thị lỗi xác thực với ab Logic ove như là làm theo,

<span id="field_error"></span> 

Hy vọng nó sẽ giúp :)

+0

cảm ơn bạn vì điều này. tôi sẽ thử nó sau. –