2

I'm developing a site in Craft 2, using a modal to display the login form. The modal can be seen by clicking the Login button at top right.

I'm essentially using the form as outlined in the Craft 2 docs here. But it's not set up to work properly with a modal behavior. Currently, if a user types the wrong password credentials, the form still executes, refreshing to the homepage. It's only when the user once again clicks the "login" button that the modal is once again revealed, now showing the error message.

How might I check whether the user's credentials are valid before submitting the form? If credentials are incorrect, I'd like to prevent execution of the form and keep the modal on screen for the user to try again.

Thanks

2

You may use some ajax to send your form so your modal will not validate and/or close and your page wont reload.

Here's a working example of what you will need to do in JS (this example use jQuery):

$('#yourFormId').submit( function (e ) {
      e.preventDefault();
      var data = $(this).serialize();
      $.ajax({
        method: 'POST',
        url: '/',
        data: data,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
      })
    .success(function(data) {
          console.log('success', data);
    })
      .error(function(data) {
        console.log('error', data);
      });
    });

If validation errors happen, you will see that in the data object folowwing the .error.

  • Thanks, Maxime. Is it possible to submit a standard Craft 2 login form via AJAX, or would I need to use a plugin like SproutForms? – Ed Hebert Feb 7 '19 at 15:19
  • @EdHebert i had a working example in my answer, take a look and feel free to ask for more details! – Maxime Lafrenière Feb 7 '19 at 15:33
  • Thank you so much, Maxime! Makes perfect sense. – Ed Hebert Feb 7 '19 at 16:24
  • @EdHebert feel free to mark my answer as THE answer ;) – Maxime Lafrenière Feb 8 '19 at 14:34
2

@Maxime, I had to edit your code slightly, as $.ajax() doesn't accept .success as a chain.

$('#login-form').submit( function (e ) {
    e.preventDefault();
    var data = $(this).serialize();
    $.ajax({
        method: 'POST',
        url: '/',
        data: data,
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        success: function(){
            console.log('success', data);
        },
        error: function() {
            console.log('error', data);
        }

    });

});

Also, I notice that the code above returns success regardless of whether the password is correct. That is, if I type the wrong password, I still get "success" and the data string.

Any ideas?

1

I am developing in Craft 3 and the accepted answer needs some modification to work. I might also be ahead a version of jQuery. Craft 3 looks for the 'Accept' header in the controller to determine if a JSON response is needed. Therefore you need to also send an 'Accept','application/json; charset=utf-8' header to elicit a JSON response from the login command.

$('#main-nav-login').submit(function (e) {
    e.preventDefault();
    var data = $(this).serialize();
    $.ajax({
            method: 'POST',
            url: '/',
            data: data,
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Accept':'application/json; charset=utf-8'
            }
        })
        .done(function (data) {
            console.log(data);

            // example error
            // {errorCode: "invalid_credentials", error: "Invalid username or password."}
            if(typeof data.error !== "undefined"){
                // handle error here
                console.log(`Something's not right. ${data.error}`);
            }

            // handle success redirect
            if(typeof data.success !== "undefined" && data.success === true){
                typeof data.returnUrl !== "undefined" ? location.href = data.returnUrl : location.href = '/';
            }

        })
        .fail(function (data) {
            console.log('error', data);
        });
});

If the user login has failed, you will get a JSON response from the .done method that looks something like this:

{errorCode: "invalid_credentials", error: "Invalid username or password."}

You can then use this to display error messages appropriately. A successful sign in will return JSON like this:

{success: true, returnUrl: "http://localhost/", csrfTokenValue: "Q5c..."}

The returnUrl field could be used to navigate to the appropriate page.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.