Link to home
Start Free TrialLog in
Avatar of Jamie
JamieFlag for United Kingdom of Great Britain and Northern Ireland

asked on

PHP script, using Ajax to dynamically load content into Bootstrap 4 Collapse/Accordion panels on panel title press, with loading icon

Hello all,

I'm a hobbyist, starting to dip my toe into Bootstrap 4, along with JQuery and Ajax.

I've got a PHP script, which works fine for tabs in Bootstrap 3 - and I'm now trying to convert it into Bootstrap 4 Collapse/Accordion - but cannot get it working - my ajax content currently appears outside all the accordion tabs, at the very bottom of the screen. I've spent some time researching this, but cannot see examples on what I'm trying to achieve.
 
For my Bootstrap 4 Accordion, when it initially appears, I want the first panel open and populated with my dynamic ajax content - with loading gif -  with each panels content being dynamically refreshed with ajax with each panel press.

<script>
$(document).ready(function() {


    $("#247button").click(function() {
 
        $("#ajax-content").empty().append("<div id='loading'><img src='/images/loading.gif' height='60' width='60' alt='Loading' /></div>");
        $("#nav li a").removeClass('current');
        $(this).addClass('current');
 
        $.ajax({ url: this.href, success: function(html) {
            $("#ajax-content").empty().append(html);
            }
    });
    return false;
    });
 
    $("#ajax-content").empty().append("<div id='loading'><img src='/images/loading.gif' height='60' width='60' alt='Loading' /></div>");
    $.ajax({ url: '/247getday2staffTIMES.php', success: function(html) {
            $("#ajax-content").empty().append(html);
    }
    });
});
</script>  


<div id="accordion">
  <div class="card">
    <div class="card-header" id="heading1">
      <h5 class="mb-0">
        <button id="247button" class="btn btn-link" data-toggle="collapse" data-target="#collapse1" aria-expanded="true" aria-controls="collapse1">
          <icon class="fa fa-user"></icon>  Jamie 1        </button>
      </h5>
    </div>

    <div id="collapse1" class="collapse show" aria-labelledby="heading1" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>	
	
	  <div class="card">
    <div class="card-header" id="heading2">
      <h5 class="mb-0">
        <button id="247button" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse2" aria-expanded="false" aria-controls="collapse2">
          <icon class="fa fa-user"></icon>  Jamie 2 
        </button>
      </h5>
    </div>
    <div id="collapse2" class="collapse" aria-labelledby="heading2" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
	  <div class="card">
    <div class="card-header" id="heading3">
      <h5 class="mb-0">
        <button id="247button" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse3" aria-expanded="false" aria-controls="collapse3">
          <icon class="fa fa-user"></icon>  Jamie 3 
        </button>
      </h5>
    </div>
    <div id="collapse3" class="collapse" aria-labelledby="heading3" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
	  <div class="card">
    <div class="card-header" id="heading4">
      <h5 class="mb-0">
        <button id="247button" class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse4" aria-expanded="false" aria-controls="collapse4">
          <icon class="fa fa-user"></icon>  Jamie 4 
        </button>
      </h5>
    </div>
    <div id="collapse4" class="collapse" aria-labelledby="heading4" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
	<div align="left" id="ajax-content" class="">This is default text, which will be replaced</div></div>



</html>

Open in new window


Any help will be greatly appreciated.

Many thanks

Regards

Jamie
Avatar of Swatantra Bhargava
Swatantra Bhargava
Flag of India image

Add below the line and see the result

$("#ajax-content").html('');
$("#ajax-content").empty().append(html);

Open in new window

Avatar of Jamie

ASKER

Hi Swatantra

Many thanks for replying so quickly - do you mean as below as it does not seem to make any difference?

<script>
$(document).ready(function() {


    $("#247button").click(function() {
 
        $("#ajax-content").empty().append("<div id='loading'><img src='/images/loading.gif' height='60' width='60' alt='Loading' /></div>");
        $("#nav li a").removeClass('current');
        $(this).addClass('current');
 
        $.ajax({ url: this.href, success: function(html) {
            $("#ajax-content").html('');
            $("#ajax-content").empty().append(html);
            }
    });
    return false;
    });
 
    $("#ajax-content").empty().append("<div id='loading'><img src='/images/loading.gif' height='60' width='60' alt='Loading' /></div>");
    $.ajax({ url: '/247getday2staffTIMES.php', success: function(html) {
            $("#ajax-content").html('');
            $("#ajax-content").empty().append(html);
    }
    });
});
</script>  

Open in new window


Many thanks

Jamie
Trying to understand what you are trying to do

Let's look at your ajax (lines 19-21)
$.ajax({ url: '/247getday2staffTIMES.php', success: function(html) {
  $("#ajax-content").empty().append(html);
}

Open in new window

You fetch the content and then you add it to the <div> with id ajax-content.
This is on line 88
<div align="left" id="ajax-content" class="">This is default text, which will be replaced</div></div>

Open in new window

Which is outside the accordion - so the code is doing exactly what you are telling to do.  The question is what is it you were really wanting it to do.

If you want the first panel to be populated on page load with the AJAX content then you need to tell it to do that. If you look at the first panel it has an id of collapse1. BUT this is where it gets fuzzy - does your AJAX return the <div class="card-body"> as well or just the content inside the card-body. I am going to assume it does not return the card-body container.
In which case you can replace your AJAX with this
$.ajax({ url: '/247getday2staffTIMES.php', success: function(html) {
  $("#collapse1 .card-body").html(html);
}

Open in new window

If it does include the card-body then
$.ajax({ url: '/247getday2staffTIMES.php', success: function(html) {
  $("#collapse1").html(html);
}

Open in new window


Note: the suggestion above is superfluous
$(selector).html('') and $(selector).empty() do the same thing and neither are required.
All you need is $(selector).html(returnedContent) to do the same thing.

Working sample here
Also your ajax-content code - you don't need to do an empty and append - again just set the HTML. Don't put into script what you can put into markup. On document load you are setting the content to Loading - just add that to the document - then in your success handler overwrite it or remove it - refer the above sample for how to do this.
I just had another look at your code and noticed some other issues.
You have created all your buttons with the same ID's this is a big no-no id's must be unique.
In addition your code is doing two ajax calls with a return. I am fixing these and will post back shortly
Ok I need more information about what you are doing. Lines 11 to 16 of your code are causing problems.

You refer to this.href - this refers to the button clicked which does not have an href defined. I have updated buttons to <a> and added an href. The code now loads the content for each panel with AJAX.

NOTE: I have made the content pages PHP scripts with SLEEP commands to simulate waiting for the page so you can see what the loading gif does
CSS
<style>
.loading {
	display: none;
}
.loading img {
	width: 60px;
}
</style>

Open in new window

HTML
<div id="accordion">
  <div class="card">
    <div class="card-header" id="heading1">
      <h5 class="mb-0">
        <a href="t3296-content1.php" id="247button1" class="btn btn-link 247button" data-toggle="collapse" data-target="#collapse1" aria-expanded="true" aria-controls="collapse1">
          <icon class="fa fa-user"></icon>  Jamie 1        </a>
      </h5>
    </div>

    <div id="collapse1" class="collapse show" aria-labelledby="heading1" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>  
  
    <div class="card">
    <div class="card-header" id="heading2">
      <h5 class="mb-0">
        <a href="t3296-content2.php" id="247button2" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse2" aria-expanded="false" aria-controls="collapse2">
          <icon class="fa fa-user"></icon>  Jamie 2 
        </a>
      </h5>
    </div>
    <div id="collapse2" class="collapse" aria-labelledby="heading2" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
    <div class="card">
    <div class="card-header" id="heading3">
      <h5 class="mb-0">
        <a href="t3296-content3.php" id="247button3" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse3" aria-expanded="false" aria-controls="collapse3">
          <icon class="fa fa-user"></icon>  Jamie 3 
        </a>
      </h5>
    </div>
    <div id="collapse3" class="collapse" aria-labelledby="heading3" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
    <div class="card">
    <div class="card-header" id="heading4">
      <h5 class="mb-0">
        <a href="t3296-content4.php" id="247button4" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse4" aria-expanded="false" aria-controls="collapse4">
          <icon class="fa fa-user"></icon>  Jamie 4 
        </a>
      </h5>
    </div>
    <div id="collapse4" class="collapse" aria-labelledby="heading4" data-parent="#accordion">
      <div class="card-body">
        Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
      </div>
    </div>
  </div>
 
  <div align="left" id="ajax-content" class="loading"><img src="images/loading.gif" alt="Loading" /></div>
  </div>

Open in new window

jQuery
<script>
$(function() {
  // CHANGE TO USE A CLASS NOT AN ID
  $(".247button").click(function(e) {
	e.preventDefault();
	// SHOW THE LOADING GIF
    $("#ajax-content.loading").show();
	// SET THE CURRENT
	if (!$(this).hasClass('current')) {
		$(".current").removeClass('current');
		$(this).addClass('current');
	}
	var target = $(this).data('target');
    $.get(this.href)
		.then(function(html) {
			$(target + " .card-body").html(html);
			$("#ajax-content.loading").hide();
	});
  });
});
</script>

Open in new window

Updated sample here
Updated to put loading gif inside the panel
Avatar of Jamie

ASKER

Hi Julian,

Apologies for my delay in replying to you - your very detailed reply and explanation is very much appreciated.

My accordion code is generated on the fly via php/mysql,  but as you say, the resulting code, didn't even have unique id's - so no wonder I was having so many problems and it didn't work! I'm going through your solution in detail, so I can fully understand your solution.  Will come back asap.

Many thanks

Jamie
Avatar of Jamie

ASKER

Hi Julian,

I've changed my dynamic generated accordion code, so that it generates the text as per your worked example - it now makes far more sense to me, hopefully sorting out most/all my errors - this is definitely a steep learning curve for me!

I can't see why, but for some reason, the loading icon appears at the bottom of the screen (see attached)  - and not in the panel in to be loaded with the updated ajax content? The first panel also needs to load and display the dynamic ajax content on first load. All the panels need to be full width, hence me putting the default text in - but probably not the best way to achieve this?

Many thanks for all your help and expertise with this.

Jamie

<!doctype html>
<html>
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="/bootstrap-4.1.1/css/bootstrap.min.css">
<script src="/bootstrap-4.1.1/js/bootstrap.min.js"></script>
<script src="/jquery-3.3.1/jquery.min.js"></script>
<script src="/popper-1.14.3/popper.min.js"></script>


<style>
.loading {
	display: none;
}
.loading img {
	width: 60px;
}
</style>

<script>
$(function() {
  // CHANGE TO USE A CLASS NOT AN ID
  $(".247button").click(function(e) {
	e.preventDefault();
	// SHOW THE LOADING GIF
	 $("#ajax-content.loading").show();	// SET THE CURRENT
	if (!$(this).hasClass('current')) {
		$(".current").removeClass('current');
		$(this).addClass('current');
	}
	
	var target = $(this).data('target');
    $.get(this.href)
		.then(function(html) {
			$(target + " .card-body").html(html);
			$("#ajax-content.loading").hide();
	});
  });
});
</script>
 
    

</head>
<body>


<div class="container">
<div class="row"> <!-- Start Aaccordion ROW -->

<div id="accordion">
  <div class="card">
    <div class="card-header" id="heading1">
      <h5 class="mb-0">
        <a href="247getday2staffTIMES.php" id="247button1" class="btn btn-link 247button" data-toggle="collapse" data-target="#collapse1" aria-expanded="true" aria-controls="collapse1">
          <icon class="fa fa-user"></icon> Jamie 1        </a>
      </h5>
    </div>

    <div id="collapse1" class="collapse show" aria-labelledby="heading1" data-parent="#accordion">
      <div class="card-body">This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present?</div>
    </div>
  </div>	
	
	  <div class="card">
    <div class="card-header" id="heading2">
      <h5 class="mb-0">
        <a href="247getday2staffTIMES.php" id="247button2" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse2" aria-expanded="false" aria-controls="collapse2">
          <icon class="fa fa-user"></icon> Jamie 2 
        </a>
      </h5>
    </div>
    <div id="collapse2" class="collapse" aria-labelledby="heading2" data-parent="#accordion">
      <div class="card-body">This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present?</div>
    </div>
  </div>
 
	  <div class="card">
    <div class="card-header" id="heading3">
      <h5 class="mb-0">
        <a href="247getday2staffTIMES.php" id="247button3" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse3" aria-expanded="false" aria-controls="collapse3">
          <icon class="fa fa-user"></icon> Jamie 3 
        </a>
      </h5>
    </div>
    <div id="collapse3" class="collapse" aria-labelledby="heading3" data-parent="#accordion">
      <div class="card-body">This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present?</div>
    </div>
  </div>
 
	  <div class="card">
    <div class="card-header" id="heading4">
      <h5 class="mb-0">
        <a href="247getday2staffTIMES.php" id="247button4" class="btn btn-link collapsed 247button" data-toggle="collapse" data-target="#collapse4" aria-expanded="false" aria-controls="collapse4">
          <icon class="fa fa-user"></icon> Jamie 4 
        </a>
      </h5>
    </div>
    <div id="collapse4" class="collapse" aria-labelledby="heading4" data-parent="#accordion">
      <div class="card-body">This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present? This is default text to ensure panel is full width, as not the case if this text is not present?</div>
    </div>
  </div>
 
	
<div align="left" id="ajax-content" class="loading"><img src="images/loading.gif" alt="Loading" /></div>

</div>

</html>

Open in new window

Accordian-Loading.jpg
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Jamie

ASKER

Hi Julian,

I knew you had it working, I just couldn't work out where I'd gone wrong - apologies for this.

Many thanks for all your patience and  detailed explanations in providing the 100% solution. As a hobbyist,  I generally only do some coding in the evenings or when time allows - so your expert skills, dedication and helpfulness cannot be underestimated - it is very much appreciated.

Following your solution and guidance has enabled me to correct my script errors and give me a better understanding of the coding techniques needed - hopefully preventing me from making the same mistakes in the future.

Many thanks

Jamie
You are most welcome, Jamie.