Question

I am creating a HTML page out of mutliple static HTML files using JQuery. The main html file has place holders for header.html and footer.html, as below:

<!DOCTYPE html>
<html>
<head>

<title>Bootstrap 101 Template</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="place-holder" include-file="bbheader.html"></div>
</html>

The file bbheader.html contains its own placeholder to load any additional HTML content at runtime.

Content of bbheader.html

<div class="nav navbar">
    <p> Hello I am bbheader. Thanks for loading me!</p>
    <div class='place-holder' include-file='bbfooter.html'></div>
</div>

To load these files, I am using a JQuery script as below:

$(function () {
    loadRecursive($(this));
});

function loadRecursive(context) {
    //search matching elements that have 'place-holder' class
    $('.place-holder', context).each(function() {
        $.get($(this).attr('include-file'), function(data, textStatus) {
            $(this).replaceWith(data);
            loadRecursive($(this));
        }, 'html');
});
}

Instead of using JQuery.load, I am using get because, load call adds the fetched content as a child of the div context. What I wanted was to replace the place holder div completely and substitute it with the fetched content. So, I am using get() and replaceWith().

But the function is failing to replace because, it is not getting the correct div context at this line "$(this).replaceWith(data);". I expected $(this) to be the div which I want to replace, but it seems here 'this' points to some object constructed by JQuery to fetch the content.

I am a novice in JQuery and I am not able to get this right. Is there a better /altenative way to do this?

thanks..

Updates: Tried as suggested by Leonard and this is the new code:

function loadRecursive(context) {
    //search matching elements that have 'place-holder' class
    $('.place-holder', context).each(function() {
        var that = this;
        $.get($(this).attr('include-file'), function(data, textStatus) {
            $(that).replaceWith(data);
            loadRecursive(that);
        }, 'html');
    });
}

But it works only for 1st level. After executing replace?With(), when it goes to recursion, the 2nd call to loadRecursive doesn't get the modified 'self'.

Expected:

<div class="nav navbar">
<p> Hello I am bbheader. Thanks for loading me!</p>
<div class='place-holder' include-file='bbfooter.html'></div>
</div>

But it still has

(<div class="place-holder" include-file="bbheader.html"></div>

Am I missing something?

EDIT:

Thanks Leonard! It works with the following change:

function loadRecursive(context) {
    //search matching elements that have 'place-holder' class
    $('.place-holder', context).each(function() {
        var that = $(this);
        $.get(that.attr('include-file'), function(data, textStatus) {
            repl = $(data);
            that.replaceWith(repl);
            loadRecursive(repl);
        }, 'html');
    });
}
Was it helpful?

Solution

Simple, just save the element:

function loadRecursive(context) {
    //search matching elements that have 'place-holder' class
    $('.place-holder', context).each(function() {
        var self = $(this);
        $.get(self.attr('include-file'), function(data, textStatus) {
            self.html(data); // Load the data into the placeholder
            loadRecursive(self); // Fix sub placeholders
            self.replaceWith(self.get(0).childNodes); // Unwrap the content
        }, 'html');
    });
}

Don't expect this to be the same in different/nestled functions :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top