1

I am using a snippet to load external divs to Bootstrap accordion items. Initially, the divs were loaded on page load, but then I modified the code so that they would load on button click.

I have used two different snippets to make this happen, and they both result in a rather jumpy transition of the accordion items when expanding. However, this didn't happen when the divs where loaded on page load.

I have searched for a solution to this problem, I have tried many things that worked for other people (such as zero margin and padding or enclosing both the button and the panel-body inside a div), but none of them worked in this case.

If you have any suggestions, please tell me. Thank you in advance

HTML

  <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
    <div class="panel panel-default">
      <div class="panel-heading" role="tab" id="headingOne">
        <h4 class="panel-title">
          <a data-href="/path/to.html #firstdiv" class="ajax-link" data-ajaxtarget="#first" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
            Read more
          </a>
         </h4>
        </div>
        <div id="collapseOne" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
         <div class="panel-body" id="first"></div>
        </div>
      </div>
     </div>

JS/JQuery

(function($){
$(document).ready(function(){
ajaxLink(); 
linkPreventDefault();  
});

function ajaxLink(){
$("a.ajax-link").on('click', function(event){     
  var thisLink = $(this);
  var targetUrl = thisLink.attr("data-href");
  var target = thisLink.data('ajaxtarget');
  console.log("loading via ajax: "+ targetUrl + ",in div: "+ target);

  $(target).load( targetUrl, function( response, status, xhr ) {
      if ( status == "error" ) {
        var msg = "Sorry but there was an error: ";
        console.error (msg + xhr.status + " " + xhr.statusText );
      }else if(status="success"){
        console.log("successfully loaded");
        //OPTIONAL: unbind the links click event and bind a new one
        noMoreAjax(thisLink);          
    }
  });
  event.preventDefault();   
});
}

function linkPreventDefault(){
$('a.link-prevent').click(function(event){
  console.log
  event.preventDefault();
});
}

function noMoreAjax(item){    
var linkItem = $(item);
console.log("No more Ajax for this link");
linkItem.removeClass('ajax-link');
linkItem.addClass('link-prevent');
linkItem.unbind('click');
$(linkItem).click(function(event){
  console.log("Preventing after ajax");
  event.preventDefault();
});
}

})(jQuery); 

(OLD JS:

$(document).ready(function(){
$('#accordion').click(function(){
    $('#first').load('/path/to.html #firstdiv');
});
})

)

  • Per http://stackoverflow.com/questions/28977499/bootstrap-accordion-how-to-avoid-page-scroll-when-collapse-or-expand-elements try data-href="" – Simon H Jan 29 '16 at 20:24
  • @SimonH For some reason, both href="" and href="#" make the page scroll to the top. It only works when I remove the href attribute altogether, though it produces the exact same results as before making any of these changes. Thank you for your comment though, it sure was interesting to know about this. –  Jan 30 '16 at 10:37

2 Answers2

0

You should expand accordion item once received response for the ajax call. So remove data-toggle="collapse" href="#collapseOne" attributes from your link and call $('#collapseOne').collapse() in callback function, like this:

 $(target).load( targetUrl, function( response, status, xhr ) {
      if ( status == "error" ) {
        var msg = "Sorry but there was an error: ";
        console.error (msg + xhr.status + " " + xhr.statusText );
      }else if(status="success"){
        $('#collapseOne').collapse();
        console.log("successfully loaded");
        //OPTIONAL: unbind the links click event and bind a new one
        noMoreAjax(thisLink);          
    }
  }); 
Roman Hutnyk
  • 1,549
  • 9
  • 14
  • First of all, thank you for your reply. And yes, that was pretty impressive.. However, when I remove those two attributes, it's no longer possible for users to make the items collapse by clicking again on the relevant buttons. Is there something else I can do about this? Also, I use many different accordions per page, but it seems that I can't really replace #collapseOne with a class name in the snippet. Can you tell me if there is some alternative to this? –  Jan 29 '16 at 21:35
  • @ctl I'm not sure why are you looking for alternative, just add missed pieces here. I helped you to figure out why it is jumping; now you need to add logic, that will decide if accordion data should be loaded with ajax, or it already sits there (if user opens it for the second time) and if accordion should be collapsed or expanded – Roman Hutnyk Jan 29 '16 at 21:45
  • The accordion should be collapsed, without making it impossible for users to make it collapse again after it's expanded though. As for when the data should be loaded, your suggestion seems to be a good way to deal with this. The problem is, someone like me who doesn't know much about JS/Javascript may usually be able to decide what they need to do, but they don't always know the way to do it. So it's not just a matter of logic to me. –  Jan 30 '16 at 09:56
  • @ctl see my new answer. – Roman Hutnyk Jan 30 '16 at 20:23
0

See a working sample here

I've used setTimeout() to fake ajax call, so you'll need to update that part, but other than that, everything is there.

Roman Hutnyk
  • 1,549
  • 9
  • 14
  • Thank you very much for your reply. I tried to implement it myself but it seems that I'm doing something wrong, as it only works at times. Shouldn't I include all of my JS snippet inside it, should I only use some part of it? –  Feb 09 '16 at 15:13
  • 1. Check for differences in HTML, or use mine. 2. Use your javascript, but take my event handler for accordion. 3. Substitute setTimeout() in my code with real ajax call you have. 4. Mark an answer if it was useful for you :) – Roman Hutnyk Feb 09 '16 at 15:40
  • Of course I will mark it once I manage to make it work using the information that you gave me, I'm actually looking forward to it.. :) It's just that, I still can't make it work, I try to adjust the HTML that I've got so that both of the snippets will be able to work, but that just seems impossible. Just in case you'd like to have a look: https://plnkr.co/edit/qoIGu1ScPjfn1nK7Lgbr?p=preview –  Feb 09 '16 at 16:10