jqueryajaxtwitter-bootstrapdynamically-generated

Bootstrap Collapse not working after dynamically created elements


having difficulty with the Bootstrap "collapse" function on a dynamically generated HTML page. I looked at this link (among many others), but nothing is working.

I'm running a page where data is fetched on page load via AJAX/webservice calls.

Then, I am drawing the UI from jQuery using essentially -

$('someSelector').append($('<div/>',{'class':'someClass'}).append(more things)

The HTML renders perfectly. It's the collapse feature that fails to work correctly.

I have a button that, when clicked, should collapse/expand a div. Both the button and div are being dynamically generated via jQuery.

After the page is loaded, although the markup is accurate, the Collapse feature doesn't work. Adding event listeners to the dynamically created buttons and simply running a show/hide doesn't work either. (It DOES work, though, on elements that weren't created via jQuery - but this doesn't help me). :( I've compared against hard-coded HTML (which works), and assume it has to do with the fact that jQuery/Bootstrap needs to be re-initialized?

My main thought is that I need to re-initialize jQuery/Bootstrap, but I don't know how to do that. :/

Any help would be greatly appreciated! I've spent soooo much time on this already. Thank you!!!

Here's the jQuery I've got and the rendered markup after jQuery is finished appending everything:

// I'm calling this function at the end of the dynamically created HTML
// I was hoping it would "brute-force" show the div I want to go.
// Didn't work though :(

function createExpandDetailsBtnListener() {
    var detailsBtns = document.getElementsByClassName("requests-item_btn");

    for (var i = 0; i < detailsBtns.length; i++) {
        detailsBtns[i].addEventListener("click", function (e) {
            var $_target = $(e.currentTarget);

            var trgt = e.target.getAttribute("data-target"); //return #default-item-detail_1
            $(trgt).show();

            //var $_div = $_target.find(".collapse");
            //if ($_div) {
            //    $_div.collapse('toggle');
            //}
            }
            , false);
    }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<ul>
<li class="requests-item requests-item-css requests-item-Submitted requests-item-687">
	<div class="requests-item-summary requests-item-summary_687">
		<div class="requests-item-column requests-item-column_requestId">
			<div class="requests-item_value partialSubmit">M687</div>
			<div class="requests-item_key">Request #</div>
		</div>
		<div class="requests-item-column requests-item-column_description">
			<div class="requests-item_value partialSubmit">sdfs sdfs</div>
			<div class="requests-item_key">Description</div>
		</div>
		<div class="requests-item-column requests-item-column_status">
			<div class="requests-item_value partialSubmit">Submitted</div>
			<div class="requests-item_key">Status</div>
		</div>
		<div class="requests-item-column requests-item-column_btn">
			<button class="btn requests-item_btn" type="button" data-toggle="collapse" data-target="#requests-item-detail_687">
				<span class="glyphicon glyphicon-chevron-down"></span>
			</button>
		</div>
	</div>
	<div id="requests-item-detail_687" class="collapse">
		<div class="requests-item_detail">
			<div class="request-detail">
				<div class="request-detail_contents">
					<ul class="request-detail_tabs">
						<li class="request-detail-tab">
							<span class="request-detail-tab_title">Request Details</span>
						</li>
					</ul>
				</div>
			</div>
		</div>
	</div>
</li>
</ul>


Solution

  • Figured out a "workaround"/answer.

    The jQuery wasn't identifying the element by ID, so I searched the dom from the button. (Combination of .parent()s and .siblings, etc.) This may not be the best method, but it worked for me.

    This resolved the issue for me in terms of getting the div to properly collapse/expand. :) Posting the answer in case anyone else runs into a similar issue because I spent so much time on it/was frustrated!