0

I'm almost there, creating an ajax login for a bootstrap modal but have run into a little problem.

Consider this:

Here is the modal, stock bootstrap & stock login form:

<div class="modal fade" id="LoginModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-body">

<div id="loginMessage"></div>
        <div class="loginForm">
    <div class="loginMessage">[[+errors]]</div>
    <div class="loginLogin">
        <form id="loginform" class="loginLoginForm" action="[[~[[*id]]]]" method="post">
                 <legend class="loginLegend">[[+actionMsg]]</legend>
                <label class="loginUsernameLabel">[[%login.username]]
                    <input class="loginUsername" type="text" name="username" />
                </label>
                <label class="loginPasswordLabel">[[%login.password]]
                    <input class="loginPassword" type="password" name="password" />
                </label>
                <input class="returnUrl" type="hidden" name="returnUrl" value="[[+request_uri]]" />
                [[+login.recaptcha_html]]
                <input class="loginLoginValue" type="hidden" name="service" value="login" />
                <span class="loginLoginButton"><button type="button" id="loginSubmit" name="submit">login</button></span>
         </form>
    </div>
</div>
<a href="[[~15]]">Forgot your Password?</a>
</div>

    </div>
  </div>
</div>

Now the jquery:

<script>

    // ajax login
    $(function() {

        $("button#loginSubmit").click(function(){

            console.log("running processor");

            $.ajax({
                type: "POST",
                url: "[[~17]]",
                dataType  : "json",
                cache : false,
                data: $('form#loginform').serialize(),
                success: function(data){

                    if(data.status == 'success'){

                        console.log("login success");

                        $("#loginMessage").html('success' + data.msg)
                        $("#LoginModal").modal('hide'); 
                        window.location.replace('[[~14]]');

                    }else if(data.status == 'error'){

                        console.log("login error");

                        $("#loginMessage").html('err' + data.msg)

                    }

                },

                error: function(data){
                    //alert("failure");
                }

            });

        });

    });

</script>

Now the processor:

<?php

$status = 'success';
$msg = 'login was successful';

$output = $modx->runSnippet('Login',array(
   'errTpl' => 'ajaxLoginErrorTpl',
   'loginResourceId' => '14',
   'logoutResourceId' => '15',
));

$loginerror = $modx->getPlaceholder('errors');

if(isset($loginerror)){

    $status = 'error';
    $msg = $loginerror;

}

$response_array = array(
    'status' => $status,
    'msg' => $msg,
    );

header('Content-type: application/json');

$output = json_encode($response_array);

return $output;

This works fine for a failed login, the errors get caught and displayed in the loginMessage div.

The problem starts when a user has a ~successful~ log in. A user has to click twice to "appear" logged in.

I saw only "appear" logged in because on the first click the modal does not disappear & the user is not redirected BUT the user does get logged in. Login is trying to redirect, the response array is not returned and the jquery does not complete. On the second click the user does get redirected, I don't know why.

I can ~sort of~ fix this by altering the login.php package ~ adding a return to the redirectAfterLogin function before it can redirect, but we all know that is dirty pool.

So;

  • Is there a way to tell login to not redirect on a successful login?

if not,

  • Any thoughts on how to fix this?
jgillich
  • 71,459
  • 6
  • 57
  • 85
Sean Kimball
  • 4,506
  • 9
  • 42
  • 73

3 Answers3

0

Did you see AjaxForm ? Simple example:

[[!AjaxSubmit?
    &snippet=`MySnippet`
    &form=`tpl.AjaxForm.example`
]]

And how about to "disable" button after first click?

$(this).attr('disabled','disabled');
Vasis
  • 2,281
  • 1
  • 16
  • 23
  • AjaxForm? I don't see how that will help, the problem is with the modx redirectAfterLogin function. Also, I don't need to disable the login button, it works fine, the ajax call just does not catch the redirect. – Sean Kimball Jun 23 '14 at 19:58
  • http://stackoverflow.com/questions/199099/how-to-manage-a-redirect-request-after-a-jquery-ajax-call - is this solution of your question? – Vasis Jun 24 '14 at 10:28
0

for the sake of experiment we put in jQuery block redirecting:

error: function(data){
                    window.location.replace('[[~[[*id]]]]');
                }

and it works now

0

Столкнулся с подобной проблемой. Создал posthook, если какие-то проблемы с авторизацией, то posthook не вызывается, а возвращается ошибка. Поэтому решение можно сделать так:

Обработчик AJAX(php):

<pre>
if($_POST['ajax']=='loginajax' && isset($_POST['service']) && $_POST['service']=='login' && isset($_POST['password']) && isset($_POST['username'])){

    $arrayRes = array(
        'status' => 'ok', // never used. It's for me, to remember what it returns on success :)
        'msg' => '',
    );

    $modx->runSnippet('Login', array(
        'tplType' => 'modChunk',
        'loginResourceId' => 6,    
        'postHooks' => 'authHookAjax'   // this is solution!!!
    ));

    $loginerror = $modx->getPlaceholder('errors');
    // if it has errors in auth
    if(!empty($loginerror)){
        $arrayRes['status'] = 'error';
        $arrayRes['msg'] = $loginerror;
        die(json_encode($arrayRes));
    }

    die(json_encode($arrayRes)); // never do it
}
</pre>

Snippet (Hook) - authHookAjax:

    $formFields = $hook->getValues();

    // checking ajax :)
    if(isset($formFields['ajax']) && $formFields['ajax']=='loginajax'){
        die(json_encode(array('status' => 'ok', 'msg' => '')));
    }

    return true;

Теперь в Javascript:

    $.ajax({
       .....
    .done(function(data){

          if(data.status=='error'){ err.html(data.msg); return ;} // error
          if(data.status=='ok'){
               window.location.reload();
               return ;
          }

       }).....