title: jQuery Validation, scroll to error doesn't work correctly
body: <p>so i have a 3 stage form which validates at each step, and again on submission. Im having some problems and i think it may possibly be due to the structure of my JS, but I can't be sure. </p>
  
  <p>For some reason it only scrolls to the first error once, once that error is cleared when someone fills in the field it then just scrolls to the top of the page. despite the fact we could now be on a new page. I have copied all relevent code, and stripped out much of the JS as there is some 300 lines. I do have a live url if you wish to see the working copy its 'xxxx'</p>
  
  <p>Here is the JS; </p>
  
  <pre><code>var form = $("#msform");
      form.validate({
          rules: {
              age: { 
                  digits: true,
                  minlength: 2
              },
              group: {
                  required: true
              },
              product: {
                  required: true
              },
              tan: {
                  required: true
              },
              exfoliate: {
                  required: true
              },
              advertising: {
                  required: true
              },
              morizLove: {
                  required: true
              },
              morizMoreProducts: {
                  required: true
              },
              terms: {
                  required: true
              },
              media: {
                  required: true,
                  minlength: 4
              },
              other: {
                  required: true              
              },
              buyother: {
                  required: true,
                  minlength: 4
              },
          },
          messages: {
              fullname: { 
                  required: "Please tell us your full name"
              },
              age: { 
                  required: "Please tell us your age"
              },
              email: { 
                  required: "Please enter a valid email"
              },
              address: { 
                  required: "Please tell us your Address"
              },
              postcode: { 
                  required: "Please tell us your Post Code"
              },
              product: { 
                  required: "Please select a product"
              },
              tan: { 
                  required: "Please tell us how often you self tan"
              },
              buymost: { 
                  required: "Please tell us which product you use most"
              },
              group: {
                  required: "Please select at least 1"
              },
              maintain: {
                  required: "Please select at least 1"
              },
              advertising: {
                  required: "Please select at least 1"
              },
              morizMoreProducts: {
                  required: "Please tell us what products you would like to see from St. Moriz"
              },
              morizLove: {
                  required: "Please tell us what you love most about St. Moriz"
              },
              terms: {
                  required: "Please accept our Terms &amp; Conditions"
              },
              media: {
                  required: "Please tell us what media you have seen advertising this campaign"
              },
              other: {
                  required: "Please tell us where you normally buy St. Moriz products from"
              },
              buyother: {
                  required: "Please tell us which product you use most"
              },
          },
          errorPlacement: function(error, element) {
              switch(element.attr("name")) {
              case "product": 
                  error.insertAfter( $(".product-error") );
                  break;
              case "tan": 
                  error.insertBefore( $(".tan-error") );
                  break;
              case "group": 
                  error.insertAfter( $("#other") );
                  break;
              case "exfoliate": 
                  error.insertAfter( $(".exfoliate-error") );
                  break;
              case "maintain": 
                  error.insertAfter( $(".maintain-error") );
                  break;
              case "terms": 
                  error.insertBefore( $(".terms-error") );
                  break;
              case "advertising": 
                  error.insertBefore( $(".advertising-error") );
                  break;
              default:
                  // the default error placement for the rest
                  error.insertAfter(element);
              }
     }
      });
  
  $(".submit").click(function(){
      $("#msform").validate();
  
      if (form.valid() == false){
  
          $('html, body').animate({
         scrollTop: ($('.error').offset().top - 60)
      }, 500);
      }
  });
  
  
  $(".next").click(function(){
      // if(animating) return false;
      animating = true;
  
      current_fs = $(this).parent();
      next_fs = $(this).parent().next();
  
  
          if (form.valid() == true){
  
              //show the next fieldset
              next_fs.show();
              //hide the current fieldset with style
              current_fs.animate({opacity: 0}, {
                  step: function(now, mx) {
                      //as the opacity of current_fs reduces to 0 - stored in "now"
                      //1. scale current_fs down to 80%
                      scale = 1 - (1 - now) * 0.2;
                      //2. bring next_fs from the right(50%)
                      left = (now * 50)+"%";
                      //3. increase opacity of next_fs to 1 as it moves in
                      opacity = 1 - now;
                      current_fs.css({
                  'transform': 'scale('+scale+')',
                  'position': 'absolute'
                });
                      next_fs.css({'left': left, 'opacity': opacity, 'position': 'relative'});
                  },
                  duration: 800,
                  complete: function(){
                      current_fs.hide();
                      animating = false;
                  },
                  //this comes from the custom easing plugin
                  easing: 'easeInOutBack'
              });     
  
                  //activate next step on progressbar using the index of next_fs
              $("#progressbar li").eq($("fieldset").index(next_fs)).addClass("active").find('img').attr("src","images/boardActive.png");
  
              // Scroll to top of next step form.
  
              $('html, body').animate({
           scrollTop: $("#progressbar").offset().top - 200
              }, 500);
              return false;
  
          }   
          else { // Scrolls to top error
              $('html, body').animate({
           scrollTop: ($('.error').offset().top - 60)
          }, 500);
          }
  
  });
  
  $(".previous").click(function(){
      // if(animating) return false;
      animating = true;
  
      current_fs = $(this).parent();
      previous_fs = $(this).parent().prev();
  
      //de-activate current step on progressbar
      $("#progressbar li").eq($("fieldset").index(current_fs)).removeClass("active").find('img').attr("src","images/board.png");;
  
      //show the previous fieldset
      previous_fs.show();
      //hide the current fieldset with style
      current_fs.animate({opacity: 0}, {
          step: function(now, mx) {
              //as the opacity of current_fs reduces to 0 - stored in "now"
              //1. scale previous_fs from 80% to 100%
              scale = 0.8 + (1 - now) * 0.2;
              //2. take current_fs to the right(50%) - from 0%
              left = ((1-now) * 50)+"%";
              //3. increase opacity of previous_fs to 1 as it moves in
              opacity = 1 - now;
              current_fs.css({'left': left});
              previous_fs.css({'transform': 'scale('+scale+')', 'opacity': opacity, 'position': 'relative'});
          },
          duration: 800,
          complete: function(){
              current_fs.hide();
              animating = false;
          },
          //this comes from the custom easing plugin
          easing: 'easeInOutBack'
      });
  
  });
  </code></pre>
  
  <p>I know there is a lot of code there but I think it could be a structural issue. Thanks very much for taking the time to read this. Please see the IP address for a working copy of how the form reacts to validation. </p>
  
  <p>Thanks very much for taking the time to read this.</p>
  
  <p>EDIT: removed live link as question has been answered.</p>