RidingTheClutch.com

Client Side Includes via Javascript

Lots of the little prototype and sample sites I create at work are not backed by an app server—they’re just a series of html/CSS/JS files that show, for example, how a text field should swap to an editable state when clicked on.

The problem is that I lose the benefit of including common parts of the page via something like Rails’s render method. You want to include the same header across all of your pages, but if you copy/paste that header into five different templates, then have to make one small change…you get the idea.

The other day I thought about the old server side include technology that most web servers support. I wanted to do something similar, but on the client side. I assumed that a standard Ajax call via XMLHTTPRequest wouldn’t work from the local file system (since it actually uses http to get your file) but turns out it works just fine! Found a snippet online and modified a bit:

["\nfunction include(url,id) {\n  var req = false;\n  // For Safari, Firefox, and other non-MS browsers\n  if (window.XMLHttpRequest) {\n    try {\n      req = new XMLHttpRequest();\n    } catch (e) {\n      req = false;\n    }\n  } else if (window.ActiveXObject) {\n    // For Internet Explorer on Windows\n    try {\n      req = new ActiveXObject(\"Msxml2.XMLHTTP\");\n    } catch (e) {\n      try {\n        req = new ActiveXObject(\"Microsoft.XMLHTTP\");\n      } catch (e) {\n        req = false;\n      }\n    }\n  }\n  if (req) {\n    // send out the response\n    req.open('GET', url, false); req.send(null);\n    // if the optional 'id' element is present, insert returned text into it, otherwise write to the page wherever it was called\n    document.getElementById(id) ? document.getElementById(id).innerHTML = req.responseText : document.write(req.responseText);\n  } else {\n    document.write('This browser does not support XMLHTTPRequest objects which are required for this page to work');\n  }\n}\n"]

Stick that in your <head> and then to include another file somewhere just make a call like so:

["\n<script type=\"text/javascript\">include('header.html')</script>\n"]

By default this will write the included file wherever you put the include call. If you want to target it to a specific element just pass that element’s id as a second parameter:

["\n<div id=\"header_container\"></div>\n<script type=\"text/javascript\">include('header.html','header_container')</script>\n"]

Make sure the call to include() goes after you have created the element that’s going to contain it, as above, otherwise the element won’t exist in the dom yet and nothing will happen.

blog comments powered by Disqus