We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 16429
    • 254 Posts
    Hi all.

    First of all, the credits:

    • Thanks to Angus Turnbull, from TwinHelix Designs, for creating the HTMLHttpRequest v1.0beta3 script that let us use AJAX and calmly sleep at night knowing it degrades to normal links and our sites are still usable even with JS off. Thanks Angus, for the help too.
    • Thanks to PaulGregory, who pointed me to the right direction when I reached a dead end in my thoughts, avoiding me to reinvent the wheel when appropiate tools where available. Without your advice I’d never ended this thing. This leads to the next credit...
    • Thanks to Susan Ottwell for the TemplateSwitcher plugin. I’ve to say you’re a factory of useful code. This plugin is exactly what I need to put the pieces all together. Thanks, thanks, thanks: it would took months for me to write a similar piece of code (mmm... not so english, I think).
    • No credit but shame on my provider who restored a 3-days-old backup on my domain where I was 1 line of code away from the goal, forcing me to do the test from the start (and restoring 3 days of work in a morning, by the way). >:(
    • ADDED: Thanks to heliotrope who pointed out (and corrected) the way you add the alternative template to the link: he added the ability to use the REL attribute.
    • Thanks to MODx and to all who work in-with-after-under-around-etc it. I don’t think MODx is a CMS, nor a Framework.
      MODx is a magic wand.
    Ok. Let’s start the explanation.

    Goals
    This tutorial explain how to implement AJAX Dinamic Content in MODx.
    Those who are deeply in the AJAX world will recognize this tecnique to be Hijax, progressive enhancement.
    For those more distant from AJAX this means that first of all your site works as it is expected to do without AJAX and JavaScript, and AJAX is an enhancement that adds something to your page. Your site will work perfectly even if the user browser has JS turned off, because it beautifully degrades to a normal page-by-page navigation.

    You can use my last work like a demo. Sorry it’s in Italian. The AJAXified links are the six box containing a link. Try it with JS on, then turn it off and restart from prodottiajax.html.

    So the goal is to create a page with links that load content from other pages in a target area (a div) if the JS is on, and if JS is off act like a normal (non-AJAX) site.

    Requirements
    You’ll need:

    • The script HTMLHttpRequest v1.0beta3 from TwinHelix. To preserve credit I link only the page: you can simply download it from there, and watch some demo, too (in fact this script can do even more complicated things). From the .zip file (which is comprensive of demo files) you can delete all but htmlhttprequest.js and htmlhttprequest.html (well, you don’t need this because I’ll write the code you find in it so you can copy and paste from here, but better keep it, you can check differences with your template).
    • The Template Switcher plugin from Susan Ottwell.
    It’s important you remember we have to create a navigational structure like a normal site, and AJAX is only an enhancing.
    Let’s assume, for the tutorial, that you’re going to upload the script to manager/media/script/ajax/htmlhttprequest.js.
    When you’ve gathered all you need, time to start working.

    1. Understand how htmlhttprequest 1.0beta3 works.
    From the comments in the code:

    Any link with a class="loadinto-IdOfTarget" attribute will load into an element with an id="IdOfTarget" attribute. It’s that easy!
    So if we have:
    <ul>
     <li><a class="loadinto-thisIsMyTarget" href="content/introduction.html">Introduction</a></li>
     <li><a class="loadinto-thisIsMyTarget" href="content/usage.html">Usage Notes</a></li>
     <li><a class="loadinto-thisIsMyTarget" href="content/advantages.html">Advantages</a></li>
    </ul>
    <div id="thisIsMyTarget">
     <p>When one of the above link is clicked this paragraph will be replaced by the content of the target page</p> 
    </div>
    

    The strenght of this script is (when JS is on) that it thinks about catching the links and updating the content, so we can write simple links that work when JavaScript is off.
    I thinks is so easy we don’t need to stay here more time.

    2. Modify and upload htmlhttprequest.js and create TemplateSwitcher plugin.
    Open htmlhttprequest.js and search for this string:
    RemoteFileLoader.prototype.loadInto=function(uri,destId){

    Right after "{" add:
    document.getElementById(destId).innerHTML='<img src="manager/media/script/ajax/waiting.gif" />';

    This will add a fancy "waiting.gif" animating icon while the browser load the content of the external file. You can find plenty on http://www.ajaxload.info/. Upload the image to the path indicated, or change the path. You can add html code there, like "Loading" with a span or what you want. Play with it.
    When you’ve done, save and upload htmlhttprequest.js.
    Then install TemplateSwitcher (you’ll find more info about installing it on its page in the repository).

    3. Create 2 templates
    To do the trick we need 2 templates.
    Create a normal template, it will be the template we assign to the pages so include all you need to present your page to the visitor.
    In the <head></head> section, add:
    <script src="manager/media/script/ajax/htmlhttprequest.js" type="text/javascript"></script>
    <script type="text/javascript">//<![CDATA[
    var docClickLoader = new RemoteFileLoader('docClickLoader');
    function loadInto(src, destId, evt) // Function modified by Heliotrope to accept REL attr - kudo
    {
    template = 'template='+ src.rel;
    url =  src.href;
    src.href = (url.indexOf('?')>0)? url + '&' + template: url + '?' + template ;
     var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
     if (ok) cancelEvent(evt);
    };  // End of the modified by Heliotrope function - kudo
    
    
    function toggleInto(src, destId, evt)
    {
     var dest = document.getElementById(destId);
     if (!dest.contentLoaded)
     {
      var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
      if (ok) dest.contentLoaded = true;
     }
     cancelEvent(evt);
     if (!dest.toggleState)
     {
      src.innerHTML = 'Close: ' + src.innerHTML;
      dest.style.display = 'block';
      dest.toggleState = 1;
     }
     else
     {
      src.innerHTML = src.innerHTML.replace(/^Close: /, '');
      dest.style.display = 'none';
      dest.toggleState = 0;
     }
    };
    addEvent(document, 'click', function(evt)
    {
     evt = evt || window.event;
     if (evt.which > 1 || evt.button > 1) return;
     var src = evt.target || evt.srcElement;
     if (src.nodeType && src.nodeType != 1) src = src.parentNode;
     while (src)
     {
      var srcName = (src.nodeName||src.tagName||'').toLowerCase();
      if (srcName == 'a' && src.className && src.className.match(/^(load|toggle)into-(.+)$/))
      {
       if (RegExp.$1 == 'load') return loadInto(src, RegExp.$2, evt);
       if (RegExp.$1 == 'toggle') return toggleInto(src, RegExp.$2, evt);
      }
      src = src.parentNode;
     }
    }, 1);
    //]]></script>
    

    This is the uncommented code from the header of the htmlhttprequest.html file, plus a line (search for "kudo") which adds "?template=OnlyContent" to the link with the LoadInto function corrected by Heliotrope which gives us the ability to select the template for the loaded content by adding a REL attribute to the link in the shape of "rel="NameOfTemplate"". This will trigger TemplateSwitcher and change the template.
    Why I need to change the template?
    Well, remember that if the user is surfing by AJAX we have a full page yet, with header, menus, footer. We need to change only the content, so we need a template with only the things we whant to change (let’s say pagetitle, etc).
    Note 1: I’ve not done so much tests, but it seems to execute cached snippets only if they’re in a chunk. Because of the restore I didn’t deeper tests so make some try if it doesn’t seem to work.
    You can name the secondary template like you want, but if it’s named other than OnlyContent you’ve to change the code. Search for "kudo".
    Your links will have to look like this:
    <a class="loadinto-thisIsMyTarget" rel="nameOfTemplateForContentOnly" href="my_link.html">

    Make some try to find what you want in the dinamic loaded page, if you want chunks, tvs, snippets... you’re free smiley.

    4. Remember to add the target div

    Ok. Now, depending how you want to use AJAX, create a target div and give it a id. Put it in the first template, or in a specific page content, or where you want. It relies on the effect you want to achieve. You can have different target of different links on the same page, so you’ve nothing to stop you.

    5. Fill with pages
    Fill your pages. Remember that your structure of links have to work without JS and AJAX.
    Ok, now you’re ready and you can start adding "loadinto-idOfTarget" class to the links you want to load in the target div. Have fun here too, use it as DropMenu class, create a list of links, have fun I’ve told it.

    Advice: start with 1 page cointaining the target div and a list of links to other pages to test. Then stop smiling like a child with a new toy (I know, I smiled in this way too) and start thinking what you can do with it.

    Done smiley
    You’re site is AJAXified at no cost. Play with it, have fun. Remember to say thanks to the credited ones!

    Bye

    Info on compatibility (great) and other things on the htmlhttprequest page.

    Correction n. 1: corrected the way to choose the template by adding the Heliotrope piece of script to use REL.
      kudo
      www.kudolink.com - webdesign (surprised?)

      [img]http://www.kudolink.com/kudolinkcom.png[/img] [sup]proudly uses[/sup] [img]http://www.kudolink.com/modx.png[/img]
      • 25663 MODX Staff
      • 12,272 Posts
      OK... so wow! laugh

      Thanks for a super-helful tutorial indeed. How does this handle bookmarks? For example, let’s say I’m here and click the "Delicatessen" link and want to bookmark that particular page/result?

      P.S. Looks like they’re restoring old data again, because half the links just went dead due to a MODx failure to find the template... ugh!
        Ryan Thrash, MODX Co-Founder
        Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
        • 16429
        • 254 Posts
        Quote from: rthrash at Aug 26, 2006, 12:36 PM

        OK... so wow! laugh

        Thanks for a super-helful tutorial indeed. How does this handle bookmarks? For example, let’s say I’m here and click the "Delicatessen" link and want to bookmark that particular page/result?
        By now it doesn’t handle bookmarks nor "Back button" (it’s the same page, so you’re taken back to the page you visited prior the AJAXed one).
        It’s the next step. I’ll take a look, try to hack some JS code into it... Let me some time smiley

        Quote from: rthrash at Aug 26, 2006, 12:36 PM

        P.S. Looks like they’re restoring old data again, because half the links just went dead due to a MODx failure to find the template... ugh!
        I’ve tested it now with Firefox and IE 6, it works like a charme. Can you send me a screenshot?. I hope they had not done another restore, or I’m definitely going to kill them all.
        This are the compatibility notes of the script:
        Quote from: TwinHelix

        * Tested and Works: IE6/Win, IE5.5/Win, IE5/Win, IE4/Win, Mozilla/Win, Opera7/Win, Safari/Mac, IE5/Mac.
        * Untested, Probably Works: IE4/Mac, Mozilla/Mac, Opera/Other, Konqueror/Linux.
        * Definitely Won’t Work in v3.x browsers, NS4, and Opera v6 and lower. Make sure you account for older browsers or search engines in your site design!
          kudo
          www.kudolink.com - webdesign (surprised?)

          [img]http://www.kudolink.com/kudolinkcom.png[/img] [sup]proudly uses[/sup] [img]http://www.kudolink.com/modx.png[/img]
          • 16429
          • 254 Posts
          Quote from: rthrash at Aug 26, 2006, 12:36 PM

          Thanks for a super-helful tutorial indeed. How does this handle bookmarks? For example, let’s say I’m here and click the "Delicatessen" link and want to bookmark that particular page/result?

          I’m talking with Angus Turnbull about hiring him to add bookmark and history capability to the script. Stay tuned!.
            kudo
            www.kudolink.com - webdesign (surprised?)

            [img]http://www.kudolink.com/kudolinkcom.png[/img] [sup]proudly uses[/sup] [img]http://www.kudolink.com/modx.png[/img]
            • 28042 ☆ A M B ☆
            • 24,524 Posts
              Studying MODX in the desert - http://sottwell.com
              Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
              Join the Slack Community - http://modx.org
              • 6726
              • 7,075 Posts
              Thanks a ton Kudolink for this great step by step AJAX tutorial, it will really be helpful grin
                .: COO - Commerce Guys - Community Driven Innovation :.


                MODx est l&#39;outil id
                • 11975
                • 2,542 Posts
                Hi,

                a very handy tutorial.

                But this line in js script fails in safari 2 and suppose that friendlies url are activated

                src.href = src.href + '?template=OnlyContent'; 


                each time the link is clicked "?template=OnlyContent" is appended to the url.

                Clicked twice the link in status bar looks like this
                <a href="http://test.kudolink.com/attrezzature.html?template=OnlyContent?template=OnlyContent">Attrezzature</a>

                Perhaps this is the reason of this error




                :-)

                By the way the site is really nice.
                A lot of useful and clever scripting has been made such as highlighting content.
                Thumbs up.
                  Made with MODx : [url=http://www.copadel.com]copadel, fruits et l
                  • 16429
                  • 254 Posts
                  Thanks for the comment on the site smiley

                  I added that line of JS, it tooks me 2 days of research because I’ve no clues on JS, if someone knows how to add that parameter without this problem (as you describe) please, correct it.
                  As told, I’m talking with the JS author to rewrite this script to use Prototype.

                  I know, this isn’t perfect, but can be useful to add something so "Web 2.0" to a site.
                    kudo
                    www.kudolink.com - webdesign (surprised?)

                    [img]http://www.kudolink.com/kudolinkcom.png[/img] [sup]proudly uses[/sup] [img]http://www.kudolink.com/modx.png[/img]
                    • 11975
                    • 2,542 Posts
                    Hi,

                    I’m not an expert about JS.
                    But here are some changes that I’ve made in your code.

                    Changed these lines :
                    function loadInto(src, destId, evt)
                    {
                     src.href = src.href + '?template=OnlyContent'; // Added this line to switch template: change to your template name - kudo
                     var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
                     if (ok) cancelEvent(evt);
                    };
                    


                    function loadInto(src, destId, evt)
                    {
                    template = 'template='+ src.rel;
                    url =  src.href;
                    src.href = (url.indexOf('?')>0)? url + '&' + template: url + '?' + template ;
                     var ok = docClickLoader.loadInto(src.href || src.getAttribute('href'), destId);
                     if (ok) cancelEvent(evt);
                    }; 


                    That way you can specify the template in the html with rel attributes of the <a class="loadinto-thisIsMyTarget" rel="template" href="my_link.html">

                    hope that helps

                    :-)
                      Made with MODx : [url=http://www.copadel.com]copadel, fruits et l
                      • 16429
                      • 254 Posts
                      Very good, this adds great flexibility to the script smiley
                      Thanks!

                      Sincerely, I wrote this tutorial hoping to catch the attention of someone more expert than me in this kind of topics to explore this thing and eventually add something.
                      Like you’ve done smiley
                        kudo
                        www.kudolink.com - webdesign (surprised?)

                        [img]http://www.kudolink.com/kudolinkcom.png[/img] [sup]proudly uses[/sup] [img]http://www.kudolink.com/modx.png[/img]