Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML5

Three Ways to Dynamically Load HTML Content into a Web Page

4.94/5 (11 votes)
29 Oct 2013CPOL4 min read 144.1K  
Demonstrates three ways to dynamically add or replace HTML content on a web page

Introduction

The three methods presented in this article for replacing HTML content dynamically (in response to user actions) all work fine; I will demonstrate all three and you can choose which best suits your situation.

Background

As I was in the process of architecting and designing my HTML5 app/website, I contemplated what would be the best way to swap out HTML content in response to selections made by the user. I initially considered generating HTML beforehand and storing it in separate files to be accessed as needed, but thought this seemed to be too much of a "brute-force" (amateurish) approach - it would be more "elegant" to dynamically generate the HTML somehow. And so my first implementation involved using jQuery's getJSON(), accessing and parsing raw *.json files. But the jQuery HTML-building code was kind of hard to read and "ugly" so I decided to be a little more "cutting edge" and went the Razor route (pun intended, but I don't want to admit it), converting C#/Razor classes into *.json files (still using jQuery's getJSON(), but accessing a Razor/*.cshtml file rather than a raw *.json file).

Finally, I reverted to my original inclination, and used jQuery's Load() method to grab an HTML file. The latter is, admittedly, the least fancy or "elegant," but it is the most straightforward, not requiring a "middleman" such as Razor to convert the C# classes into json, nor requiring the creation of raw JSON files that are parsed and morphed into HTML. Theoretically, at least, "cutting out the middle man" is not only easier to maintain, but also should run faster (in actuality, no approach seems much different from the others as far as speed goes, and I have not profiled it to see for sure which type of operation is fastest). 

Using the code 

The first method I used was to load *.json files using jQuery's getJSON() method (creating the *.json files is left as an exercise to the reader - in my case, I created a C# utility that saved the necessary data to a CSV file, then used the  CSV to JSON converter, and finally the JSON Lint site to clean up any bad data that had infiltrated due to bugs in my utility and "edge cases" in the data). 

Here is some sample raw JSON, from "sundance.json":

JavaScript
{
    "category":"2012",
    "film":"blankfilm",
    "instavid":"blankbluray",
    "bluray":"blankdvd",
    "dvd":"blankinstavid",
    "imghtml":"blankimghtml"
  },
  {
    "category":"U.S. Grand Jury Prize Dramatic",
    "film":"Beasts of the Southern Wild",
    "instavid":"B00A7JKMA2",
    "bluray":"B008220ALC",
    "dvd":"B008220AGC",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008220ALC/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B008220ALC.01.MZZZZZZZ.jpg\" 
      alt=\"Beasts of the Southern Wild Movie Cover\" /></a>"
  },
  {
    "category":"U.S. Grand Jury Prize Documentary",
    "film":"The House I Live In",
    "instavid":"B00B19HFMK",
    "bluray":"--",
    "dvd":"B00CEJVNEM",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00CEJVNEM/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B00CEJVNEM.01.MZZZZZZZ.jpg\" 
      alt=\"The House I Live In Movie Cover\" /></a>"
  },
  {
    "category":"World Cinema Grand Jury Prize Dramatic",
    "film":"Violeta Went to Heaven (Violeta se Fue a Los Cielos)",
    "instavid":"--",
    "bluray":"--",
    "dvd":"B00CKDO9I4",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00CKDO9I4/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://ecx.images-amazon.com/images/I/513Puff-bQL._SL160_.jpg\" 
      alt=\"Violeta Went to Heaven (Violeta se Fue a Los Cielos) Movie Cover\" /></a>"
  },
  {
    "category":"World Cinema Grand Jury Prize Documentary",
    "film":"The Law in These Parts",
    "instavid":"--",
    "bluray":"--",
    "dvd":"B00C4WL3ZI",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00C4WL3ZI/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B00C4WL3ZI.01.MZZZZZZZ.jpg\" 
      alt=\"The Law in These Parts Movie Cover\" /></a>"
  },
  {
    "category":"Audience Award U.S. Dramatic",
    "film":"The Surrogate (retitled The Sessions)",
    "instavid":"B00B7G3NFU",
    "bluray":"B00ANGICRE",
    "dvd":"B00AEK9BKQ",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B00ANGICRE/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B00ANGICRE.01.MZZZZZZZ.jpg\" 
      alt=\"The Surrogate (retitled The Sessions) Movie Cover\" /></a>"
  },
  {
    "category":"Audience Award U.S. Documentary",
    "film":"The Invisible War",
    "instavid":"B009G9YCB4",
    "bluray":"--",
    "dvd":"B008MIYKLW",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008MIYKLW/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B008MIYKLW.01.MZZZZZZZ.jpg\" 
      alt=\"The Invisible War Movie Cover\" /></a>"
  },
  {
    "category":"Audience Award World Cinema Documentary",
    "film":"Searching for Sugar Man",
    "instavid":"B00AY7Q01C",
    "bluray":"B008JFUTUY",
    "dvd":"B008JFUTT0",
    "imghtml":"http://www.amazon.com/exec/obidos/ASIN/B008JFUTUY/garrphotgall-20\" 
      target=\"_blank\"><img height=\"160\" width=\"107\" 
      src=\"http://images.amazon.com/images/P/B008JFUTUY.01.MZZZZZZZ.jpg\" 
      alt=\"Searching for Sugar Man Movie Cover\" /></a>"
  },

...and here is the jQuery used to get it and parse it, morphing it into HTML:

JavaScript
function Urlify(ASINVal) {
    return "http://www.amazon.com/exec/obidos/ASIN/" + ASINVal + "/garrphotgall-20";
}
JavaScript
$.getJSON('Content/sundance.json', function (data) {
    $.each(data, function (i, dataPoint) {
        if (IsYearOrTwoYearSpan(dataPoint.category)) {
            htmlBuilder += '<div class=\"yearBanner\">' + dataPoint.category + '</div>';
        } else {
            htmlBuilder += '<section class=\"wrapper\" >
                <a id=\"mainImage\" class=\"floatLeft\" href=\"' +
                dataPoint.imghtml +
                '<div id=\"prizeCategory\" class=\"categorySmallerFont\">' +
                dataPoint.category +
                '</div><br/><cite id=\"prizeTitle\" >' +
                dataPoint.film +
                '</cite><br/>';
            if (dataPoint.bluray.length > 2) {
                htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.bluray) + '\"' +
                    ' target=\"_blank\" >Blu-Ray</a></button>';
            }
            if (dataPoint.dvd.length > 2) {
                htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.dvd) + '\"' +
                    ' target=\"_blank\" >DVD</a></button>';
            }
            if (dataPoint.instavid.length > 2) {
                htmlBuilder += '<button><a href=\"' + Urlify(dataPoint.bluray) + '\"' +
                    ' target=\"_blank\" >InstaVid</a></button>';
            }
            htmlBuilder += '</section>';
        } //else
    }); //each
    $('#MoviesContent').html(htmlBuilder).
         find('img, button').click(function () {
             $(this).css('border', '1px solid silver');
         });
    $('#MoviesContent').css('background-color', 'black');
    $('button').button();
}) //getJSON 

This works just fine (as you can see by selecting Movies > Sundance from my web site, but the code was hard to write because of having to make sure all the quotes are escaped and so forth, and hard to look at, being "9 times uglier than a bag of butts," to quote Eddie J. Nelson, an old friend of mine. 

Then, primarily because of the time-consuming but necessary preliminary steps of creating raw *.json files, I decided to use Razor to convert C# classes into json (it was easier to have a utility write out the C# class instances than to go through the CSV to JSON process -- and easier to read them). Here is an example of that Razor code:

C#
@{
    var books = new List<BookClass>
    {
        new BookClass{Year=2013, YearDisplay="blankYearDisplay", Category="2013", 
            Title="blankTitle", Author="blankAuthor", 
            KindleASIN="blankKindleASIN", HardboundASIN="blankHardboundASIN", 
            PaperbackASIN="blankPaperbackASIN", ImgSrc="blankImgSrc"},
        new BookClass{Year=2013, YearDisplay="2013", Category="Best Novel", 
            Title="Redshirts", Author="John Scalzi", KindleASIN="B0079XPUOW", 
            HardboundASIN="0765316994", PaperbackASIN="0765334798", 
            ImgSrc="http://images.amazon.com/images/P/B0079XPUOW.01.MZZZZZZZ"},
        new BookClass{Year=2013, YearDisplay="2013", Category="Best Novella", 
            Title="The Emperor's Soul", Author="Brandon Sanderson", 
            KindleASIN="B00A1XOPE8", HardboundASIN="--", 
            PaperbackASIN="1616960922", 
            ImgSrc="http://images.amazon.com/images/P/B00A1XOPE8.01.MZZZZZZZ"},
		. . .
        new BookClass{Year=1946, YearDisplay="blankYearDisplay", Category="1946", 
            Title="blankTitle", Author="blankAuthor", 
            KindleASIN="blankKindleASIN", HardboundASIN="blankHardboundASIN", 
            PaperbackASIN="blankPaperbackASIN", ImgSrc="blankImgSrc"},
        new BookClass{Year=1946, YearDisplay="1946", Category="Best Novella", 
            Title="Animal Farm", Author="George Orwell", 
            KindleASIN="B003ZX868W", HardboundASIN="0151010269", 
            PaperbackASIN="184046254X", 
            ImgSrc="http://images.amazon.com/images/P/B003ZX868W.01.MZZZZZZZ"}
    };
    Response.ContentType = "application/json";
    Json.Write(books, Response.Output);
}

As you can see, the code above converts the C# classes to JSON files when it calls Json.Write. The jQuery to deal with this JSONized data is the same as for the raw *.json files, except that it references the GetHugos.cshtml file shown above, rather than a *.json file:  

JavaScript
$.getJSON('GetHugos', function (data) { 
. . .  

Finally, I tried the most direct approach of  generating HTML content, of which here is an example: 

HTML
<div class="yearBanner">2013</div>
<section class="wrapper" ><a class="floatLeft" 
  href="http://www.amazon.com/exec/obidos/ASIN/B0085DOE2O/garrphotgall-20" 
  target="_blank"><img height="160" width="107" 
  src="http://images.amazon.com/images/P/B0085DOE2O.01.MZZZZZZZ.jpg" 
  alt="Tucker's Reckoning by Ralph Compton and Matthew Mayo book cover"></img></a>
    <div class="category">Best Short Novel</div><br/><cite 
    >Tucker's Reckoning</cite><br/><div class="author">Ralph 
    Compton and Matthew Mayo</div><br/><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/B0085DOE2O/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/0451415612/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button>
    <button><a href="http://www.amazon.com/exec/obidos/ASIN/0451465482/garrphotgall-20" 
    target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B00ERRJ9VS/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://ecx.images-amazon.com/images/I/51FamWEIkzL._SL160_.jpg" 
    alt="With Blood in Their Eyes by Thomas Cobb book cover"></img></a>
    <div class="category">Best Long Novel</div><br/><cite 
    >With Blood in Their Eyes</cite><br/><div class="author"
    >Thomas Cobb</div><br/><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/0816521107/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button>
    <button><a href="http://www.amazon.com/exec/obidos/ASIN/0816521107/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/B00ERRJ9VS/garrphotgall-20" 
    target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B008EXK2LC/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/B008EXK2LC.01.MZZZZZZZ.jpg" 
    alt="The Coyote Tracker by Larry Sweazy book cover"></img></a>
    <div class="category">Best Paperback</div><br/><cite  
    >The Coyote Tracker</cite><br/><div class="author">Larry Sweazy</div>
    <br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B008EXK2LC/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/1410454002/garrphotgall-20" target="_blank" 
    rel="nofollow" >Hardcover</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/0425250415/garrphotgall-20" 
    target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B0083JCERC/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/B0083JCERC.01.MZZZZZZZ.jpg" 
    alt="Panhandle by Brett Cogburn book cover"></img></a><div  
    class="category">Best First Novel</div><br/><cite  
    >Panhandle</cite><br/><div  class="author">Brett Cogburn</div><br/>
    <button><a href="http://www.amazon.com/exec/obidos/ASIN/B0083JCERC/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/1410460975/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button>
    <button><a href="http://www.amazon.com/exec/obidos/ASIN/B00ERJREPO/garrphotgall-20" 
    target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B009T3C88Q/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/B009T3C88Q.01.MZZZZZZZ.jpg" 
    alt="Geronimo by Robert M. Utley book cover"></img></a><div  
    class="category">Best Biography</div><br/><cite  
    >Geronimo</cite><br/><div  class="author">Robert M. Utley</div>
    <br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B009T3C88Q/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/0300126387/garrphotgall-20" target="_blank" 
    rel="nofollow" >Hardcover</a></button><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/0300198361/garrphotgall-20" target="_blank" 
    rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B009KM8OGQ/garrphotgall-20" target="_blank">
    <img height="160" width="107" src="http://images.amazon.com/images/P/
    B009KM8OGQ.01.MZZZZZZZ.jpg" alt="With Golden Visions Bright Before Them: Trails to the Mining West, 
    1849-1852 by Will Bagley book cover"></img></a><div class="category">Best 
    Historical</div><br/><cite >With Golden Visions Bright Before Them: Trails to the Mining West, 
    1849-1852</cite><br/><div class="author">Will Bagley</div><br/><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/B009KM8OGQ/garrphotgall-20" target="_blank" 
    rel="nofollow" >Kindle</a></button><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/0806142847/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/B00CLHRS4Q/garrphotgall-20" target="_blank" 
    rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B0080K3P40/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/B0080K3P40.01.MZZZZZZZ.jpg" 
    alt="Desert Reckoning: A Town Sheriff, A Mojave Hermit and the Biggest Manhunt in Modern California History 
    by Deanne Stillman book cover"></img></a><div class="category">Best Nonfiction 
    Contemporary</div><br/><cite >Desert Reckoning: A Town Sheriff, A Mojave Hermit and 
    the Biggest Manhunt in Modern California History</cite><br/><div class="author">
    Deanne Stillman</div><br/><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/B0080K3P40/garrphotgall-20" target="_blank" 
    rel="nofollow" >Kindle</a></button><button><a 
    href="http://www.amazon.com/exec/obidos/ASIN/B00B1L0ZW0/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/B00CWL160S/garrphotgall-20" target="_blank" 
    rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/B0074VTH6G/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/B0074VTH6G.01.MZZZZZZZ.jpg" 
    alt="Wide Open by Larry Bjornson book cover"></img></a><div  
    class="category">Best Juvenile Fiction</div><br/><cite  
    >Wide Open</cite><br/><div class="author">Larry Bjornson</div>
    <br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/B0074VTH6G/garrphotgall-20" 
    target="_blank" rel="nofollow" >Kindle</a></button><button>
    <a href="http://www.amazon.com/exec/obidos/ASIN/1410460584/garrphotgall-20" 
    target="_blank" rel="nofollow" >Hardcover</a></button>
    <button><a href="http://www.amazon.com/exec/obidos/ASIN/0425247481/garrphotgall-20" 
    target="_blank" rel="nofollow" >Paperback</a></button></section>
<section class="wrapper" ><a class="floatLeft" 
    href="http://www.amazon.com/exec/obidos/ASIN/0803235208/garrphotgall-20" 
    target="_blank"><img height="160" width="107" 
    src="http://images.amazon.com/images/P/0803235208.01.MZZZZZZZ.jpg" 
    alt="Light on the Prairie: Solomon D. Butcher, Photographer of Nebraska’s Pioneer Days 
    by Nancy Plain book cover"></img></a><div  class="category">
    Best Juvenile Nonfiction</div><br/><cite >Light on the Prairie: Solomon D. Butcher, 
    Photographer of Nebraska’s Pioneer Days</cite><br/><div class="author">Nancy 
    Plain</div><br/><button><a href="http://www.amazon.com/exec/obidos/ASIN/0803235208/garrphotgall-20" 
    target="_blank" rel="nofollow" 
    >Hardcover</a></button></section> 

The code to use it follows:

JavaScript
$('#BooksContent').load('Content/spur.html', function () {
    $('button').button();
});

From a coding perspective, the straightforward HTML methodology is the simplest. Obviously, the jQuery code is very minimal and, in fact, the "$('button').button()" line is eye candy (jQuery UI goodness), and not strictly necessary. 

You can compare the performance of the various approaches by selecting the awards on my HTML5 app/website that use them: For the raw HTML approach, select Books > Spurs (Western); for the Razor/cshtml getJSON() approach, select Books > Hugos (Science Fiction).

 Image 1

All the others so far use the raw *.json files / getJSON() methodology. Unless I am convinced otherwise, awards yet to be added (Nobel Prize for Literature, Nebulas, James Beard, and Edgars) will use the raw HTML alternative. 

Points of Interest 

As mentioned, all three of the methodologies work. The latter two are the easiest to "pre-process" - that is, the utility that creates the Razor code and the utility that generates the raw HTML make for faster work than first creating a CSV file, converting that to JSON, and then tweaking that JSON file until it is properly parsed. Unless I find a good reason to change my mind, I will probably stick with the "boring", inelegant, and "brute-forceish" method of replacing the content by loading HTML files using raw HTML files and the jQuery Load() method, rather than calling getJSON().

History

  • First posted 10/1/2013.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)