Anuncio

Entra a participar en el Slack de Laraveles. Solicita tu invitación aquí.
Nos ayuda a manter la comunidad

#1 06/09/2018 18:39:35

JonathanP
Miembro
Registrado: 18/06/2018
Mensajes: 11

Iniciando con AJAX - Laravel 5.6

Buen día gente,
Tengo un formulario sencillo en el cual los usuarios pueden cambiar su contraseña en la app y funciona bien.
Quiero hacerle una mejora cambiando hacia una petición ajax y estoy bastante enredado con el asunto. He visto buena cantidad de tutoriales y en casi todos veo formas diferentes de hacerlo pero ninguna me ha funcionado hasta el momento. Voy a adjuntar el código que tengo en este momento haber si me pueden orientar un poco.

@section('head_propio')
    <script>

        $(document).ready(function () {
           
            $('#formPass').submit(function (e) {
                e.preventDefault();
                var formu = $(this);
                var varurl = $(this).attr("action"); // con esta url me funciona con peticion HTML, para ajax hay que hacer algun cambio?

                $.ajax({
                    url: varurl,
                    headers:{'X-CSRF-TOKEN': $("#token").val()},  // El token si puede ir aca, o debe ser en $.ajaxSetup({}) ?       
                    data: formu.serialize(),
                    type: 'POST',
                    dataType: "html", // hay que cambiarlo a "json" ?
                    success:function(result){ //Esta función se ejecuta sólo si la petición se hizo correctamente ó es necesario respuesta "positiva" del servidor?
                        console.log("result");                                
                    }, 
                    error:function(data){
                        var errors = $.parseJSON(data.responseText);
                        $.each(errors, function (key, value) {
                            console.log("key: " + key + " value: " + value);
                        });                               
                    } 
                });
            });
        });       
       
        }
    </script>
@endsection


@section('content')
    <div class="container-fluid row justify-content-center text-center mt-4">
        <form method="post" action="{{url('/cambiarPassword')}}" id="formPass">
            {{csrf_field()}}

            <input type="hidden" name="_token" id="token" value="{{csrf_token()}} ">

            @php
                if (Session::has('message')){
                    if (strpos(Session::get('message'),"incorrecta") !==false) {
                        echo("<p class='alert alert-danger small'>");
                    }else{
                        echo("<p class='alert alert-success small'>");
                    }
                    echo(Session::get('message') . "</p>");
                }
            @endphp

            <div class="form-group">
                <label for="mypassword">Contraseña Actual:</label>
                <input type="password" name="mypassword" class="form-control mb-1" >
                @php
                    if ( !empty($errors->first('mypassword')) ) {
                        $messages = $errors->getMessages();
                        foreach ( $messages["mypassword"] as $message ){
                            echo("<p class='alert alert-danger small' >". $message . "</p>");
                        }
                    }
                @endphp
            </div>

            <div class="form-group">
                <label for="password">Nueva Contraseña:</label>
                <input type="password" name="password" class="form-control mb-1" required onkeyup="validarPass_largo()">
                <p id="val_passwordLargo" class="mt-1 d-none small"></p>
                @php
                    if ( !empty($errors->first('password')) ) {
                        $messages1 = $errors->getMessages();
                        foreach ( $messages1["password"] as $message ){
                            echo("<p class='alert alert-danger' >". $message . "</p>");
                        }
                    }
                @endphp
            </div>

            <div class="form-group">
                <label for="mypassword">Confirma tu nueva Contraseña:</label>
                <input type="password" name="password_confirmation" class="form-control" required onkeyup="validarPass_igual()">
                <p id="val_password" class="mt-1 d-none small"></p>
            </div>

            <button type="submit" class="btn btn_csi_ama px-3 py-1 my-4" name="confirmar">Confirmar</button> <br>
        </form>
    </div>
@endsection

La ruta (en web.php)

Route::post('/cambiarPassword', 'generalController@cambiarPassword');

El controlador

    public function cambiarPassword(Request $request){
    
        $rules = [
            'mypassword' => 'required',
            'password' => 'required|confirmed|min:5|max:20',
        ];
        
        $messages = [
            'mypassword.required' => 'El campo es requerido.',
            'password.required' => 'El campo es requerido.',
            'password.confirmed' => 'Las contraseñas no coinciden.',
            'password.min' => 'Se requieren mínimo 5 caracteres.',
            'password.max' => 'Se permiten máximo 20 caracteres.',
        ];
        
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()){
            return new JsonResponse($validator->errors(), 422);
        }
        else{
            $current_user=$this->getCurret_User();
            if (Hash::check($request->mypassword, $current_user->password)){
                $user = new User;
                $user->where('email', '=', $current_user->email)
                     ->update(['password' => bcrypt($request->password)]);
                return redirect('/password')->with('message', 'Contraseña Actualizada');
            }
            else
            {
                return redirect('/password')->with('message', 'Contraseña actual incorrecta');
            }
        }
    
    }

Cualquier ayuda es agradecida !

Desconectado

#2 07/09/2018 02:02:28

uicabpatweyler
Miembro
Registrado: 19/03/2016
Mensajes: 10

Re: Iniciando con AJAX - Laravel 5.6

Me gustaría compartir contigo la forma de que como manejo mis formularios con Ajax, recuerda y deseo aclarar, que no es la única o la mejor, pero a mi me ha funcionado.

Definición del formulario en la vista:

<form action="" method="post" id="id_del_formulario" name="name_del_formulario">
{{csrf_field()}}
  .....
  .....
 campos inputs, selects, del formulario
</form>

Omito el valor de "action" ya que lo defino en las propiedades de ajax de esta manera:

$.ajax({
    type:"POST",
    url:"{{route('ruta_para_guardar')}}",
    data: $("#id_del_formulario").serialize(),
    dataType : 'json',

Te recomiendo que uses siempre el helper "route", usando las rutas que creas en el archivo "routes\web.php".

Esta linea en tu código:

headers:{'X-CSRF-TOKEN': $("#token").val()},

Considero que está de mas, ya que esta linea {{csrf_field()}} del formulario se encarga de crear un input oculto con esa propiedad, y al usar  serialize() se incluye de manera automática.

Ahora bien, mi declaración completa de ajax, queda asi:

$.ajax({
    type:"POST",
    url:"{{route('ruta_para_guardar')}}",
    data: $("#id_del_formulario").serialize(),
    dataType : 'json',
    success: function(data){
        //La variable data toma su valor en tu controlador, tu se la puedes asignar. Mas adelante te muestro como la defino
    },
   error: function(xhr,status, response ){

        //Obtener el valor de los errores devueltos por el controlador
        var error = jQuery.parseJSON(xhr.responseText);

        //Obtener los mensajes de error
        var info = error.message;
        
       //Crear la lista de errores
       var errorsHtml = '<ul>';
           $.each(info, function (key,value) {
                errorsHtml += '<li>' + value[0] + '</li>';
            });
           errorsHtml += '</ul>';
          alert(errorsHtml);
   }

Ahora en tu controlador podría quedar así:

$validator = Validator::make($request->all(), $rules, $messages);

//Se cumplen todas las reglas de validación que tu has establecido
if($validator->passes()){
    //Este codigo se ejecuta si se cumplen todas tus validaciones
    //Usualmente después de que haber procesado la información y haberla guardado en nuestra base de datos devuelvo el 
   //siguiente código para indicarle a Ajax que la petición se proceso correctamente

   return response()->json([
    'success'   => true,
    'message'   => 'Los datos se han guardado correctamente.' //Se recibe en la seccion "success", data.message
    ], 200);
}

//Esta parte se ejecuta si las validaciones fallan
$errors = $validator->errors();

        $errors =  json_decode($errors);

        return response()->json([
            'exception' => false,
            'success'   => false,
            'message'   => $errors //Se recibe en la sección "error" de tu código JavaScript, y se almacena en la variable "info"
        ], 422);

Por ejemplo, esta linea de tu codigo del controlador:

return redirect('/password')->with('message', 'Contraseña Actualizada');

Podrias reeemplazarla por esta:

return response()->json([
    'success'   => true,
    'message'   => 'La contraseña se ha actualizado correctamente' //Se recibe en la seccion "success", data.message
    ], 200);

Y esta:

 return redirect('/password')->with('message', 'Contraseña actual incorrecta');

Por esta

return response()->json([
    'success'   => false,
    'message'   => 'Contraseña actual incorrecta
    ], 422);

Para finalizar, como mencione al principio, no es la única forma, pero a mi me ha funcionado. Espero haberte ayudado, y si tienes mas dudas, plantealas acá para poder apoyarte. Saludos.

Desconectado

#3 07/09/2018 15:52:56

JonathanP
Miembro
Registrado: 18/06/2018
Mensajes: 11

Re: Iniciando con AJAX - Laravel 5.6

Hombre muchisimas gracias por tomarse el tiempo por ayudarme. Con lo indicado en su respuesta ya lo tengo listo !
Sólo un par de dudas:

Podrías por favor explicarme los argumentos
     

 error: function(xhr,status, response) 

Y por qué si en el controlador se genera una respuesta similar tanto para éxito como para error los argumentos que usan el "success" y el "error" en la vista son diferentes?

return response()->json(['success'   => XXX, 'message'   => XXX'], 200) 

Disculpa abusar, pero me gusta aprender y veo que tienes buenos conocimientos

Última edición por JonathanP (07/09/2018 17:34:54)

Desconectado

#4 07/09/2018 18:13:59

uicabpatweyler
Miembro
Registrado: 19/03/2016
Mensajes: 10

Re: Iniciando con AJAX - Laravel 5.6

El tipo de respuesta no son las mismas, de alguna manera tenemos que indicarle a Ajax si la operación tuvo éxito o error. Es por eso que el ultimo parámetro en la respuesta, 200 o 422, son códigos de estado de HTTP. https://es.wikipedia.org/wiki/Anexo:C%C … stado_HTTP , https://developer.mozilla.org/es/docs/Web/HTTP/Status , y el parametro "success" indica si fue "exito" o "error". Los errores pueden ser variados, por ejemplo que tu servidor de BD no responda o se demore demasiado, que no se encuentre disponible, que un campo determinado no sea del tipo correcto, o que una transacción no se lleve a cabo de manera correcta.

Acá esta la documentación oficial de $.ajax: https://api.jquery.com/jQuery.ajax/

Puedes devolver varios parámetros en base a la respuesta de tu servidor, es por eso que esta funcion tiene dos secciones, "sucess y "error", dependiendo de a complejidad de tu proyecto les puedes dar muchos usos.

En teoría y a grandes rasgos eso es lo que he logrado entender hasta el día de hoy.

Espero poder haber despejado un poco tus dudas.

Saludos, y seguimos en contacto

Desconectado

#5 07/09/2018 18:22:43

JonathanP
Miembro
Registrado: 18/06/2018
Mensajes: 11

Re: Iniciando con AJAX - Laravel 5.6

De nuevo muchas gracias hombre, ya con la documentación termino de afinar dudas

Desconectado

Pié de página <- REVISAR ->

Powered by FluxBB

Ayuda a mantener la comunidad: