2013-06-13 9 views
16

Attualmente io uso questo per visualizzare gli errori di convalida tramite la tecnologia AJAX:errori di convalida in modalità 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(); 
      } 

Funziona bene, fa esattamente quello che mi serve.

Il problema è quello che devo fare per trasportare gli errori da laravel a 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); 
     }  

    } 

Se voglio avere i nomi dei campi come chiave, devo iterare $ regole, ma anche se io non usare i nomi dei campi come chiave, eppure devo ripetere i messaggi di errore per costruire $ verrors.

Come è possibile convertire $v->messages() nell'equivalente di $verrors senza la necessità di iterare? Poiché Response::json() prevede una matrice anziché un oggetto.

risposta

61

Il modo più semplice è sfruttare l'oggetto MessageBag del validatore. Questo può essere fatto in questo modo:

// 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); 

Questo darebbe una risposta JSON come questo:

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

questo può essere un commento stupido - ma non l'impostazione del codice http a 400 significa che la risposta JSON è completamente ignorato? – Beans

+2

Dipende dal "client" che legge il JSON. jQuery ad esempio lo gestisce perfettamente. Non innesca il successo, ma il callback degli errori, che è quello che vuoi. – DerLola

+1

Utilizzando jQuery, è possibile ottenere errori utilizzando questo codice nella richiesta Ajax: 'error: function (xhr, status, data) { console.log (xhr.responseJSON.errors); } ' – Yako

8

Nella risposta ajax provare qualcosa di simile

.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

sto usando laravel 5.1 tra l'altro, ma penso che i fondamenti di questo dovrebbero applicarsi ad altre versioni. Laravel restituisce automaticamente la risposta all'errore di convalida. Si può solo effettuare le seguenti operazioni nel controller:

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

Poi, nel tuo javascript (sto usando jQuery qui):

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); 
}); 

Se si guarda in uscita sulla console avrete vedrai presto come afferrare tutto ciò che vuoi dalla risposta inviata da Laravel. In questa risposta i messaggi di errore sono in json come coppie chiave-valore in cui la chiave è il nome del campo che ha fallito la convalida, nel mio esempio 'email'. Ricordarsi di assicurarsi che il percorso Ajax sia impostato nel file routes.php e che il metodo (get/post) corrisponda a quello presente nel javascript.

1

Esiste un modo migliore per gestire gli errori di convalida quando si utilizza la richiesta Ajax.

Crea una classe Request come al solito, per esempio UploadFileAjaxRequest:

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

utilizzare in un metodo di controllo:

public function uploadFileAjax(UploadFileAjaxRequest $request) 

Se non v'è alcun errore, restituisce un array di errori che è possibile utilizzare in JS:

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

Lara vel errore di convalida 5 ritorna automaticamente

per che basta per fare cosa seguente,

Controller:

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); 
} 

Vista:

  $.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]); 
        }); 
       } 
      } 
     }); 

si può costruire per ogni campo validation un tag <span> con ID come nome campo e suffisso _error quindi mostrerà l'errore di convalida con logica ove come come seguire,

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

Speranza che aiuta :)

+0

grazie per questo. lo proverò più tardi –

Problemi correlati