0

I have a dynamic login header. 2 links, login / register and profile / logout.

I have a php class function that was being used to check if logged in and displaying relevant links, it worked fine.

I then moved to an ajax login as I didn't want a page refresh and the login box drops down and rolls back up. Again, it works fine.

I've noticed a slight issue, by slight I mean very irritating :)

Once logged in, Every single page refresh on new page shows a flicker where 'profile' becomes 'login' and then flickers back again. It only happens when the page is loading and doesn't last long but it's not very nice.

Could someone help me solve it please? I'm pretty new to Ajax/jQuery and spent ages wiht the help of some guys in here getting the ajax/jquery part functional in the first place.

this is script that toggles the login divs

<script>
        window.onload = function(){
            $(function() {
                var loggedIn = <?php echo json_encode($general->loggedIn()); ?>;
                $("#loggedIn").toggle(loggedIn);
                $("#loggedOut").toggle(!loggedIn);
            });
        }
    </script>

Thanks

EDIT: Ajax

function validLogin(){

$('#error').hide();
var username = $('#username').val();
var password = $('#password').val();

if(username == ""){
    $('input#username').focus();
    return false;
}

if(password == ""){
    $('input#password').focus();
    return false;
}

var params = {username: username, password: password};
var url = "../loginProcessAjax.php";

$("#statusLogin").show();

$.ajax({
    type: 'POST',
    url: url,
    data: params,
    dataType: 'json',
    beforeSend: function() {
      document.getElementById("statusLogin").innerHTML= '<img src="../images/loginLoading.gif" /> checking...' ;
    },

    success: function(data) {

        $("#statusLogin").hide();

        if(data.success == true){

            $('#loggedIn').show();
            $('#loginContent').slideToggle();
            $('#loggedOut').hide();

        }else{
           // alert("data.message... " + data.message);//undefined
            $("#error").show().html(data.message);
        }

    },
    error: function( error ) {
        console.log(error);
    }
});
 }
null
  • 3,469
  • 7
  • 41
  • 90

3 Answers3

2

Use PHP to hide the unwanted element by doing the following

<?php
$loggedIn = $general->loggedIn();
?>
... Some HTML

<div>
    <div id="loggedIn" <?php echo ( $loggedIn ? '' : 'style="display: none;"' ); ?>>
        .... Logged in stuff
    </div>
    <div id="loggedOut" <?php echo ( !$loggedIn ? '' : 'style="display: none;"' ); ?>>
        .... Logged Out Stuff
    </div>
</div>

<script>

    var loggedIn = <?php echo json_encode($loggedIn); ?>;

    $('#loginForm').submit(function() {
        ... Handle form submit
        ... When ajax returns true or false we can set loggedIn and then toggle the containers
    });

</script>
MajorCaiger
  • 1,893
  • 1
  • 12
  • 18
  • I can't do this because of the initial ajax call. This was my first option but when you login for the first time, the page doesn't refresh so loggedIn is still false and still displays login until a refresh is made – null Jul 23 '13 at 21:05
  • This is essentailly exactly what I had before implementing the ajax. Ajax kills the above on the initial login. – null Jul 23 '13 at 21:07
  • You can still have the ajax call there for when they log in and update the HTML after the ajax call, and you can still set the javascript variable using json_decode just as you are doing. Just get rid of the .toggle()'s in the window.onload and set the HTML in PHP – MajorCaiger Jul 23 '13 at 21:07
  • You could render both containers to the page, but use php to set the `display` property. The ajax call could switch the visible div on login. – Jason P Jul 23 '13 at 21:08
  • Yep Jason P makes a valid point, have both HTML containers rendered and use PHP to set in inline style="display: none" on the one to hide by default. – MajorCaiger Jul 23 '13 at 21:10
  • The same way you are doing now. If you render both HTML elements to begin with you can just use $('#loggedIn').toggle() – MajorCaiger Jul 23 '13 at 21:12
  • @JasonP & Major - could you elaborate a bit more please? I've updated the Question with the ajax – null Jul 23 '13 at 21:13
  • Thankyou! That looks elegant compared to what I'm doing. – null Jul 23 '13 at 21:24
  • Above where you mentioned ajax toggles - do you mean : if(data.success == true){ $('#loginContent').slideToggle(); – null Jul 23 '13 at 21:39
  • Your ajax request for the login form submission is fine. You no longer need the window.onload toggles. – MajorCaiger Jul 24 '13 at 07:28
1
// CSS-Stylesheet 
#loggedIn,
#loggedOut {display: none}

<script>
        $(document).ready(function() {
            var loggedIn = <?php echo json_encode($general->loggedIn()); ?>;     
            if (loggedIn == true) { // i can just guess here...
                $("#loggedIn").show();
            }
            else {
                $("#loggedOut").show();
            }
        });
</script>
de_nuit
  • 650
  • 7
  • 13
0

Three possible solutions:

  • If the script element is placed inside the body, move it to head element.

  • Use the following script instead:

      $(document).ready(function () {
          'use strict';
          var loggedIn = <?php echo json_encode($general->loggedIn()); ?>;
          $('#loggedIn').toggle(loggedIn);
          $('#loggedOut').toggle(!loggedIn);
      });
    
  • Hide both links in the "logged in" div using $('#loggedIn
    a).hide();
    and then, show them on the window.onload event using
    $('#loggedIn a).show();. A bit dirty, bit it may work.

federico-t
  • 12,014
  • 19
  • 67
  • 111
  • 'use strict' - what does that do? – null Jul 23 '13 at 21:26
  • script is in body but it's in the header include. I'd rather it be in this one place that in the head of all the other pages – null Jul 23 '13 at 21:27
  • @SteveGreen In this case nothing really, but it's [good practice](http://stackoverflow.com/a/1335881/2612112) to include it. – federico-t Jul 23 '13 at 21:31