views:

786

answers:

4

I've been working on this all day and I'm stuck here... I'm making a slide-down login-form that is submitted with the jquery ajax.form plugin. The effects work, the submission works. But when you put them together they don't work...

This is for expression engine, so the {if} tags are just EE conditionals. See that the content changes once the user is logged in--I just need this to reload so that the content changes--I think it'd be easier then doing a bunch of .html() rewrites... Once the form is submitted, the correct content reloads and is clickable, but the "#panel" won't re-animate.

<div id="client-login">
<div class="wrap">
<p  class="work-message">We're doing some work under the hood!  If things get/are funky, please excuse us!</p>
    {if logged_out}
    <div id="client" class="login">Client Login</div>
    {/if}
    {if logged_in}
    <div id="client" class="login">Hey, {username}!</div>
    {/if}
</div>
</div>
<div id="panel">
    <div id="panel-content" class="wrap">
    {if logged_out}
    {exp:member:login_form id="login-form"}
    <ul>
    <li>
    <label><span>Username</span></label>
    <input type="text" name="username" value="" maxlength="32" class="input" size="25" />
    </li>
    <li>
    <label><span>Password</span></label>
    <input type="password" name="password" value="" maxlength="32" class="input" size="25" />
    </li>
    <li class="login-forgot">
    <a href="{path='member/forgot_password'}">Forgot your password?</a>
    </li>
    {if auto_login}
    <li class="checkbox">
    <input class='checkbox' type='checkbox' name='auto_login' value='1' /> Auto-login on future visits
    </li>
    {/if}
    </ul>
    <p>
    <input type="submit" id="panelsubmit" name="submit" value="Submit" />
    </p>
    {/exp:member:login_form}
    {/if}
    <div id="messages">
    <p></p>
    </div>
{if logged_in}
    <div id="logout">
     <h2>What do ya wanna' do?!</h2>
     <form id="login-form" >

       <input type="hidden" name="ACT" value="10" />

       <input type="submit" value="Log Out" />

     </form> 
    </div>
{/if}

$(document).ready(function()
{
$('.login').toggle(
function()
{
  $('#panel').stop().animate({
  height: "150", 
  padding:"20px 0",
  backgroundColor:'rgba(0,0,0,0.8)',
 }, 500);
 $('#client-login').stop().animate({
  backgroundColor:'rgba(0,0,0,0.8)',
 }, 500);
},
function()
{
  $('#panel').stop().animate({
    backgroundColor:'rgba(0,0,0,0.2)',
  height: "0", 
  padding:"0px 0",
  }, 500);     
 $('#client-login').stop().animate({
  backgroundColor:'rgba(0,0,0,0.2)',
 }, 500);

});

    $('#login-form').ajaxForm({  
        // success identifies the function to invoke when the server response 
        // has been received; here we apply a fade-in effect to the new content 
        success: function() { 
            $("#client").remove().fadeOut("fast");
            $("#client-login").load("/ #client-login").fadeIn("fast");
            $("#panel-content").remove().fadeOut("fast");
            $("#panel").load("/ #panel-content").fadeIn("fast");

        } 
    }); 
});

The functionality is basically there, but the form needs to work the same AFTER it's submitted as it does before! Also, the animation for the .remove doesn't work. I'm a jscript noob, and I don't know how to improve this!

Thanks for aiding me in my scripting ignorance (and impatience)!

+5  A: 

Since you're loading the content via AJAX, the animation and functionality that were present before the reload will not work anymore because the effects were only bound to the original elements. To fix this, you need to re-bind the loaded content to the animations, etc.

There are a couple of ways to do this. Firstly, you could just re-apply your animation functions to the loaded content. For example, once the content has loaded, call a function that re-binds the animations to the new elements.

Secondly, and more easily, you can use the jQuery live() function. This is the better method in my opinion. The live() function binds all current and future elements, instead of just binding current elements. So when creating your animation, create it inside the live() function. Here is a usage example from http://docs.jquery.com/Events/live:

$("p").live("click", function(){
  $(this).after("<p>Another paragraph!</p>");
});
James Skidmore
I'm not sure my syntax is correct. It's kind-of working, but I have to click it two times to initialize...I'm not sure what to do! Please excuse my ignorance!
Kevin Brown
Can you post your syntax?
James Skidmore
A: 
$('.login').toggle(
function()
{
    $('#panel').stop().animate({
    height: "150", 
    padding:"20px 0",
    backgroundColor:'rgba(0,0,0,0.8)',
   }, 500);
   $('#client-login').stop().animate({
    backgroundColor:'rgba(0,0,0,0.8)',
   }, 500);
 },
 function()
 {
    $('#panel').stop().animate({
      backgroundColor:'rgba(0,0,0,0.2)',
    height: "0", 
    padding:"0px 0",
    }, 500);     
   $('#client-login').stop().animate({
    backgroundColor:'rgba(0,0,0,0.2)',
   }, 500);

});

$('#login-form').ajaxForm({  
    // success identifies the function to invoke when the server response 
    // has been received; here we apply a fade-in effect to the new content 
    success: function() { 
        $("#client-login .wrap").fadeOut('slow');
        $("#client-login .wrap").remove();         
        $("#client-login").load("/ #client-login").fadeIn(2000);
        $("#panel-content").fadeOut('slow');
        $("#panel").load("/ #panel-content").fadeIn(2000);
         $('#panel').animate({
      backgroundColor:'rgba(0,0,0,0.2)',
    height: "0", 
    padding:"0px 0",
    }, 500);   
         $('#client-login').animate({
    backgroundColor:'rgba(0,0,0,0.2)',
   }, 500);
    } 
});

All the action happens in the "header" div...

Kevin Brown
How do you want the animation to happen? Does it happen when you do something (like a click), or does it happen just when the page loads/AJAX content is reloaded?
James Skidmore
The animation happens on click (just like the slideToggle).The ajax will call a new animation--fade in new content (possible slide closed). I'm not totally sure yet how I want to do things, but the main problem resides with the clicking.I've edited the script (upadted).
Kevin Brown
Does the updated code work? Looks like it should...
James Skidmore
Yea, that is w/o the .live function, so it doesn't bind after ajax. When I wrapped this in the .live function, I had to click two, sometimes three times to get the slider to work AFTER the ajax was called...Check my website and click client-login (that's what I'm working on).
Kevin Brown
Hey hey!I think the issue lies here: .toggle is called by a "click" event. The .live only works with a click event, so to get the animation you need two clicks.Things get a little jumbled after ajax, but I think I'm on the right track...I just don't know where to go now...Should I perhaps go with .bind instead of .live?
Kevin Brown
A: 

Alright, this is what I have and it seems to work... Is there a better way to do this?

$(document).ready(function()
{
$("#client-login").css({backgroundColor:'rgba(0,0,0,0.2)'});
$(".login").live('mouseover', function(){ 
    $(".login").toggle(
    function()
    {
        $('#panel').stop().animate({
        height: "150", 
        padding:"20px 0",
        backgroundColor:'rgba(0,0,0,0.8)',
       }, 500);
       $('#client-login').stop().animate({
        backgroundColor:'rgba(0,0,0,0.8)',
       }, 500);
     },
    function()
    {
        $('#panel').stop().animate({
          backgroundColor:'rgba(0,0,0,0.2)',
        height: "0", 
        padding:"0px 0",
        }, 500);     
       $('#client-login').stop().animate({
        backgroundColor:'rgba(0,0,0,0.2)',
       }, 500);
});
});
$(".login").live('mouseover', function(){ 

    $('#login-form').ajaxForm({  
        // success identifies the function to invoke when the server response 
        // has been received; here we apply a fade-in effect to the new content 
        success: function() { 
            $("#client-login .wrap").fadeOut('slow');
            $("#client-login .wrap").remove();         
            $("#client-login").load("/ #client-login").fadeIn(2000);
            $("#panel-content").fadeOut('slow');
            $("#panel").load("/ #panel-content").fadeIn(2000);
             $('#panel').animate({
          backgroundColor:'rgba(0,0,0,0.0)',
        height: "0", 
        padding:"0px 0",
        }, 500);   
             $('#client-login').animate({
        backgroundColor:'rgba(0,0,0,0.2)',
       }, 500);
        } 
    }); 
    }); 
});
Kevin Brown
Is there a particular reason that you have two live events?
James Skidmore
It acted funny when I wrapped it in one--I could have just made a typo...
Kevin Brown
A: 

I got it!

$(document).ready(function(){
    $("#client-login").css({backgroundColor: 'rgba(0,0,0,0.2)'});
    var speed = 300;
    var openpanel = function() {
         $("#client-login").stop().animate({
             backgroundColor: 'rgba(0,0,0,0.8)'
       },speed);
            $("#panel").stop().animate({
             backgroundColor: 'rgba(0,0,0,0.8)',
             height: '200px'
             },speed);
            $('#panel').removeClass("closed");
     };
    var closepanel = function() {
         $("#client-login").stop().animate({
             backgroundColor: 'rgba(0,0,0,0.2)'
       },speed);
            $("#panel").stop().animate({
             backgroundColor: 'rgba(0,0,0,0.2)',
             height: '0px'
             },speed);
            $('#panel').addClass("closed");
     };
    $(".login").live("click",function() {
       if ($("#panel").hasClass("closed"))
       {
      openpanel();
       } else {
      closepanel();
       };
    $('#login-form').ajaxForm({
      // success identifies the function to invoke when the server response
      // has been received; here we apply a fade-in effect to the new content
      success: function() {
        closepanel();
        $("#client-login").load("/ #client-login");
        $("#panel").load("/ #panel-content", 1000);
        }
    });
    });
});

Thanks for your help, James!

Kevin Brown
No problem! Happy to help.
James Skidmore