timokfine's avatar

Login form inside modal - submit with AJAX?

I've placed my app's login form inside a Foundation modal window. It works great when a login attempt is successful, but I need a way to display validation errors/failed attempts inside the modal window.

Should I be submitting the form with AJAX and if so, how hard is it to implement?

Any ideas would be much appreciated.

Thanks!

0 likes
13 replies
bashy's avatar
@if ($errors->all()) // check if there's any errors, not sure what to use but all should work?
    $('#modal').modal('show'); // could do this in bootstrap
@endif
skashizadeh's avatar

it's simple.

if ajax returned 1 then it's successfull and you will redirect your page to home or dashboard. if it was failed then ajax result contains needed "html+error content " that must be added to a div in your modal to display to user.

do not forgot to empty that div befor request

kfirba's avatar

You can submit it using AJAX but I would maybe do things a little bit differently. If there are validation errors and the user is redirected back to the page so he can retry login in I would show the modal again and populate the email with a right error message.

The validator redirects back with $errors variable so you can add this code to your modal:

@if($errors->any())
    <ul>
    @foreach($errors as $error)
        <li>$error</li>
    @endforeach
    </ul>
@endif

That will solve the errors display. Obviously the user won't see anything because the modal is hidden so you can add this line of code to the bottom of the view:

@if($errors->any())
<script>
    $('#myModal').foundation('reveal', 'open');
    // or any other way you want to manually open your modal.
</script>
@endif
skashizadeh's avatar

if you have problem with ajax you can use my ex bellow :

$(document).ready(function() {
        $('form').submit(function() {
            $.ajax({
                url: "http://targetdomain.url/",
                data: {
                    username: nitrammit,
                    password: 123
                },
                type: "GET",
                dataType : "json",
                success: function( json ) {
                    // do what ever you want here. add content to <div> if it was not 1 . 
                    console.log(json);
                },
                error: function( xhr, status, errorThrown ) {
                    console.log( "Sorry, there was a problem!" );
                }
            });
            json = '';
            return false;
        });
    });

    
bestmomo's avatar

Dont close the modal if there are validation errors. Here an example (but with Bootstrap, I think it's same for Foundation) that show a modal, submit with Ajax without closing the modal, and closing it only if there is no errors :

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="utf-8">
    <link href="assets/css/bootstrap.css" rel="stylesheet">
    <style type="text/css">
      body {padding-top: 20px;}
    </style>
  </head>
  <body>
    <div class="container">     
      <div id="html">
        <button data-toggle="modal" data-backdrop="false" href="#formulaire" class="btn btn-primary">Informations</button>
      </div>
      <div class="modal fade" id="formulaire">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <button type="button" class="close" data-dismiss="modal">x</button>
              <h4 class="modal-title">Vos infos :</h4>
            </div>
            <div class="modal-body">
              <form action="test.php">
                <div class="form-group">
                  <label for="nom">Nom</label>
                  <input type="text" class="form-control" name ="nom" id="nom" placeholder="Votre nom">
                </div>
                <div class="form-group">
                  <label for="email">Email</label>
                  <input type="email" class="form-control" name="email" id="email" placeholder="Votre Email">
                </div>
                <button type="submit" class="btn btn-default">Envoyer</button>
              </form>
            </div>
            <div class="modal-footer">
              <button class="btn btn-info" data-dismiss="modal">Annuler</button>
            </div>
          </div>
        </div>
      </div>
    </div>
    <script src="assets/js/jquery.js"></script>
    <script src="assets/js/bootstrap.min.js"></script>
    <script>
      $(function(){
        $("form").submit(function(e) {
          e.preventDefault();
          var $form = $(this);
          $.post($form.attr("action"), $form.serialize())
          .done(function(data) {
            // Some stuff there
            $("#formulaire").modal("hide");
          })
          .fail(function() {
            // Dispatch errors in modal
          });
        });
      });
    </script>
  </body>
</html>
timokfine's avatar

Thanks for the help! @bashy @skashizadeh @kfirba @bestmomo

I've worked out how to redirect to the homepage on form submission and reopen the modal with its validation errors, but I think I'd rather use AJAX for a better user experience.

AJAX isn't my strongest skill, but I could have sworn @JeffreyWay did a video on AJAX in Laravel 4 awhile ago? I can't seem to find it. Did he publish one? Or am I imagining things again?

skashizadeh's avatar

there is no video tutorial needed about this.just a little jquery knowledge. Ajax is independent to laravel , you must add follow jquery code in your view :

$(document).ready(function() {
        //$('form').submit(function() {
            $.ajax({
                url: "http://localhost/test/route",
                data: {
                    username: nitrammit,
                    password: 123
                },
                type: "GET",
                dataType : "json",
                success: function( json ) {
            alert(json);
                },
                error: function( xhr, status, errorThrown ) {
                    console.log( "Sorry, there was a problem!" );
                }
            });
            json = '';
            return false;
        //});
    });

and then you need to create route for "http://localhost/test/route" like bellow :

Route::any('/test/route',function()
    {
        return 'yess, my ajax works fine. TnQ guys ^_^ . you had postet following variables : '.print_r(Input::all());
    }
);

when page is reloaded content of http://localhost//test/route will be displayed. :) hope you enjoy

timokfine's avatar

@skashizadeh Thanks, dude!

I've got the following in my JS file.

$('.ajax-form').on('submit', function(e) {

    e.preventDefault();

    var form = $(this);
    var url = form.prop('action');
    
    $.ajax({
        type: "post",
        url: url,
        data: form.serialize(),
        dataType: 'json',
        success: function(json) {
            alert(json);

        },
        error: function(json) {
            alert(json);
        },
    });

});

Am I on the right track?

How can I use the response in my success/alerts? For example, if I was posting to the following route:

Route::any('test',function() {
    return 'this is the response';
});

How could I capture the returned response? What about validation errors? How do I capture those if I post to the default login route?

Sorry. JS is my Achilles' heel. I'm a bit out of my depth here.

:)

skashizadeh's avatar

seems currect. i think you have your user and pass field on your site and want to show errors by modal in foundation. if you got response in your alert then every thing is fine and almost done. so if you want to open a modal with some content you must return that content from your router to your jquery variable ( json ) and then use it like bellow :

never used Foundation but i think you must have this in your view :

<div id="myModal" class="reveal-modal" data-reveal>
</div>

update jquery like this:

$('.ajax-form').on('submit', function(e) {
    e.preventDefault();
    var form = $(this);
    var url = form.prop('action');
    
    $.ajax({
        type: "post",
        url: url,
        data: form.serialize(),
        dataType: 'json',
        success: function(json) {
        if(json=="no_errors"){
                window.location = URL::to('/Dashboard');
        }
        else{
            $('#myModal').foundation('reveal', 'close');
            $( "#myModal" ).empty();
            $( "#myModal" ).append(json);
            $('#myModal').foundation('reveal', 'open');
        }
        },
        error: function(json) {
            alert(json);
        },
    });

});

and finaly return content like follow from router :

Route::any('test',function() {
    return '<h2>yes finaly.</h2>';
});

after submitting your form your modal will be like this :

<div id="myModal" class="reveal-modal" data-reveal>
    <h2>yes finaly.</h2>
</div>

hope you get my point :)

ap_dev's avatar

@Tim86, were you ever able solve this problem. I am trying to do the exact same thing and still cant get it.

jekinney's avatar

Both foundation and bootstrap have a CSS class that opens a modal on page load.

I perform an if statement in the model. If has errors open modal on page load. Then no Ajax or extra JavaScript and in your controller redirect back with errors or better yet a form request.

For bootstrap replace the fade class with open I believe. I'll have to double check.

timokfine's avatar

@ap_dev Sorry, mate. I haven't written a line of Laravel code in over 6 months. It makes me sad inside.

Please or to participate in this conversation.