Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Multi-Part Content script

  1. #1
    Join Date
    Mar 2005
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Multi-Part Content script

    hi folks

    can anyone help me to add more than one scipt of this Multi-Part Content script (DD->dynamic content) on ONE page (e.g. box1 box2 etc.).

    i tried to use 'numbered' functions
    e.g.
    cycleforward
    cycleforward1

    for box 1 and box 2

    but either text form link 2 changed in box one or no links in box 2 were visible.

    thanx
    tom
    Last edited by gracilis; 03-18-2005 at 07:42 AM.

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default 2 of the same

    Numbering the functions is good, do that to all the variables, id names, anything unique to the script too, if you are thorough it will work. The name of the game is, don't let anything in one version of the script affect the other version.

  3. #3
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by jscheuer1
    Numbering the functions is good, do that to all the variables, id names, anything unique to the script too, if you are thorough it will work. The name of the game is, don't let anything in one version of the script affect the other version.
    Time would probably be better spent rewriting the script after reading my treatise on creating re-usable scripts. Of course, it would need more work than that:

    Code:
    var createMultipartSection = (function() {
      var getElementById;
    
      if(!Array.prototype.push) {
        Array.prototype.push = function() {
          for(var j = 0, n = arguments.length; j < n; ++j) {
            this[this.length] = arguments[j];
          }
          return this.length;
        };
      }
    
      if(document.getElementById) {
        getElementById = function(id) {return document.getElementById(id);};
      } else if(document.all) {
        getElementById = function(id) {var r = document.all[id];
          if(('number' == typeof r.length) && r.tags) {
            for(var j = 0, n = r.length; j < n; ++j) {
              if(r[j].id == id) {return r[j];}
            }
          } else if(r.id == id) {return r;}
          return null;
        };
      } else {getElementById = function() {return null;};}
    
      function getParts(ancestor) {
        var elements = ancestor.getElementsByTagName
             ? ancestor.getElementsByTagName('*')
             : ancestor.all ? ancestor.all : [],
            r = [];
    
        for(var j = 0, n = elements.length, c, cN; j < n; ++j) {
          c = elements[j]; cN = c.className;
          if(('string' == typeof cN) && /(^|\s+)multipart-part(\s+|$)/.test(cN)) {
            r.push(c);
          }
        }
        return r;
      }
    
      function showElement(element, show) {
        if(element.style) {element.style.display = show ? '' : 'none';}
      }
    
      return function(id, loop, navProvided, start) {
        var current = start || 0,
            next = loop
             ? function() {return cycle(1);}
             : function() {return move(1);},
            previous = loop
             ? function() {return cycle(-1);}
             : function() {return move(-1);},
            back, forward, parts, section;
    
        function cycle(delta) {
          showElement(parts[current], false);
          current = (current + delta + parts.length) % parts.length;
          showElement(parts[current], true);
          return false;
        }
    
        function move(delta) {
          if(((current + delta) < parts.length) && ((current + delta) >= 0)) {
            showElement(parts[current], false);
            current += delta;
            showElement(parts[current], true);
            showElement(back, current != 0);
            showElement(forward, current != (parts.length - 1));
          }
          return false;
        }
    
        if((section = getElementById(id)) && (parts = getParts(section)).length) {
          if(navProvided) {
            back = getElementById(id + '-back');
            forward = getElementById(id + '-forward');
          } else if(document.createElement && document.createTextNode
             && document.body && document.body.appendChild)
          {
            var n = document.createElement('ul'),
                b = document.createElement('li'),
                f = document.createElement('li');
    
            back = document.createElement('a');
            forward = document.createElement('a');
    
            if(n && b && back && f && forward && n.appendChild) {
              n.id = id + '-navigation';
              back.id = id + '-back'; back.href = '#';
              forward.id = id + '-forward'; forward.href = '#';
    
              back.appendChild(document.createTextNode('Back'));
              b.appendChild(back);
              n.appendChild(b);
    
              forward.appendChild(document.createTextNode('Forward'));
              f.appendChild(forward);
              n.appendChild(f);
    
              document.body.appendChild(n);
            } else {back = forward = null;}
            b = f = n = null;
          }
          if(back && forward) {
            back.onclick = previous;
            forward.onclick = next;
            showElement(back, current != 0);
            showElement(forward, current != (parts.length - 1));
    
            for(var j = 0, n = parts.length; j < n; ++j) {
              if(j != current) {showElement(parts[j], false);}
            }
          }
        }
      };
    })();
    The code above creates a function, createMultipartSection, which takes four arguments:

    • id - A string containing the id attribute of an element which is the ancestor of a group of parts. Required.
    • loop - A boolean which indicates whether the parts should be navigated in a cyclic or linear fashion. Defaults to false (linear).
    • navProvided - A boolean which indicates whether createMultipartSection needs to create navigation controls or if they are already in the document. Defaults to false (create).
    • start - A number specifying which part to show first. Defaults to zero (0).
    If the navigation generation feature isn't used, the code should work with IE4+ and any DOM supporting user agent (Opera, Firefox, Safari, etc). If the navigation generation feature is used, the script will not work with IE4 as it doesn't possess a particularly useful document.createElement method. That said, the script is currently untested, but it should work.

    The behaviour of the script has changed, and does have new features.

    • The class name which parts should use is multipart-part. This can be changed by editing the regular expression in the getParts function. The use of a regular expression for class name matching also allows for the use of multiple class names rather than only one.
    • The expected naming of the navigation elements is based upon the id passed as the first argument. The navigation container should have the id, id-navigation, the back control should have id-back, and the forward control should have id-forward. If the navigation elements are generated, they will follow the same pattern so you can reliably style them.
    • The generated navigation controls will be in the form of an unordered list, inserted at the end of the document. A basic CSS rule for styling them would be:

      Code:
      #id-navigation {
        list-style-type: none;
        margin: 1em 0;
        padding: 0;
      }
      #id-navigation li {
        display: inline;
        margin: 0;
        padding: 0 1ex;
      }
      You can, of course, add things such as absolute positioning. Adjust as you see fit. If you want to control your own placement, and what is used for the controls, specify true for the third argument and follow the pattern in the previous point.
    • The parts found during execution will be hidden automatically, with the exception of the starting part. They must not be hidden via a style sheet rule.


    The function must be called after the containing element, its parts, and any provided navigation has been parsed by the user agent. Calling the function as part of a load event handler will obviously accomplish this, but an earlier call is possible.

    Have fun,
    Mike

  4. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default Rewrite as per Treatise

    Thanks for the rewrite, Mike! I must have been slipping up, as I usually start a message like my previous one in this thread with language stating that it is better to rewrite the script to get it to perform the new tasks. That treatise is something else though. I noticed the author is the only one to reply to its thread. I read it through once, seems very useful except hard to understand. I know Mike usually knows what he is talking about even if we don't. Similarly, this rewrite above seems a little difficult to understand but, at least I think I got it on the first read through (own ignorance showing through). I feel as though I, or someone, should take on the task of being Mike's voice in matters relating to humans. That being said, code loads up real nice on a blank page. I've downloaded the original script's content and will try plugging it in to see if I can make it do something. Too bad we don't have the content from the person who started this thread to play with.

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default OK, set it up

    I set the above rewrite up, as per instructions, assuming I understood them. Seems to work fine except that I cannot seem to avoid this type of layout on the page:

    Section containing first set of content

    Section containing second set of content

    controls for 1st section

    controls for 2nd section

    any suggestions?

    our work is at:
    Rewrite MultiPart Content
    Last edited by jscheuer1; 03-18-2005 at 06:13 PM. Reason: add link

  6. #6
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by jscheuer1
    Thanks for the rewrite, Mike!
    You're welcome.

    I must have been slipping up, as I usually start a message like my previous one in this thread with language stating that it is better to rewrite the script to get it to perform the new tasks.
    Particularly if you're trying to introduce such a radical change. A non-trivial script that wasn't designed to be used more than once could never be so easily adapted.

    That treatise is something else though.
    Hmm. Should I take that as a compliment?

    I noticed the author is the only one to reply to its thread. I read it through once, seems very useful except hard to understand.
    That's why I posted again, hoping to get questions. I've had at least five attempts at explaining closures, and that's about the best one so far (I think). It really isn't an easy thing to do, especially writing for a general audience.

    Similarly, this rewrite above seems a little difficult to understand [...]
    I would normally heavily comment something as complicated as that, but I ended up writing it in the reply text area, rather than in jEdit. It was awkward enough due to the restricted space.

    [...] I think I got it on the first read through
    As always, if something needs an explanation, just ask. If really necessary, I'll edit the post and comment the lot.

    I feel as though I, or someone, should take on the task of being Mike's voice in matters relating to humans.
    Oh. Cheers for that!

    That being said, code loads up real nice on a blank page.
    Well, it doesn't really do much except create a few functions unless you invoke the function.

    Too bad we don't have the content from the person who started this thread to play with.
    I'd have tested the code myself, then. To be honest, I was feeling lazy as I had other things on my mind. If I wasn't reasonably sure that it would work, then I would have set up an example.

    There's currently only one change that I have in mind, which would provide a better solution to the positioning problem. Instead of passing a boolean for the third argument (create controls), the code could require a function instead. This callback could allow the user to create and insert the controls anywhere, and anyhow they chose. If the argument was null or omitted, the code could attempt to find pre-included controls. It's easy to implement, but not so simple to use as the author must know how to manipulate the document tree.

    Quote Originally Posted by jscheuer1
    I set the above rewrite up, as per instructions, assuming I understood them. Seems to work fine except that I cannot seem to avoid this type of layout on the page:

    Section containing first set of content

    Section containing second set of content

    controls for 1st section

    controls for 2nd section

    any suggestions?
    A couple of points:

    1. Remove the id attribute on the inner div elements, with the exception of the last in each table which should really have the value checker-navigation and checker2-navigation respectively.
    2. Call the createMultipartSection function with the third argument set to true. This will cause it to find and use your navigation components. For example,

      Code:
      function load() {
        /* Don't loop. Use existing navigation. */
        createMultipartSection('checker', false, true);
        createMultipartSection('checker2', false, true)
      }
      
      <body onload="load();">
    3. Don't hide the div elements containing the navigation links. Also, there's no need to set actions for the links: a handler will be added automatically.
    4. The style sheet suggestions I made were only useful if you allowed the code to add navigation controls itself. Also, if you didn't want the controls to appear at the bottom, position them using CSS.


    That would change the mark-up to something like:

    HTML Code:
    <table id="checker" width="350">
    <tr>
      <td>
      <div class="multipart-part">
        <img src="files/photo1.jpg" align="left">
        <p>Blah, blah, blah...</p>
      </div>
      <div class="multipart-part">
        <img src="files/photo2.jpg" align="left">
        <p>Blah, blah, blah...</p>
      </div>
      <div class="multipart-part">
        <p>Blah, blah, blah...</p>
      </div>
      <div id="checker-navigation" style="width: 250px">
        <a id="checker-back" style="float: left"
         href="#"><img src="files/35.gif" border="0"> Back</a>
        <a id="checker-forward" style="float: right"
         href="#">Forward <img src="files/36.gif" border="0"></a> 
      </div>
      </td>
    </tr>
    </table>
    Again, untested.

    Mike

  7. #7
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default Suggestions Included

    Think I got all that. There are now two versions:

    Links Removed, will reappear updated in later post

    They generate phantom content while loading (IE6) but, that resolves itself once the page is fully loaded or read from cache. Not sure why. Time limited, for debugging right now.
    Last edited by jscheuer1; 03-19-2005 at 04:34 AM. Reason: remove links

  8. #8
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default display

    Using IE6 I find that by marking inner div's (except the first) display:none it solves the problem but, think I am missing something that might have prevented that necessity. I have updated the online versions to reflect this latest change:

    HTML controls - inner divs display:none

    Generated controls - inner divs display:none

    Looking at them in NS7.2 presented a new question, no phantoms but the HTML controls are not where I'd expect them to be. I can use the '!important' hack to get them lined up but, I'm sure you would have a better way. It is really IE6 that is parsing the css wrong to begin with.
    Last edited by jscheuer1; 03-19-2005 at 04:45 AM. Reason: Update Links

  9. #9
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I thought I should produce my own example, so I did.

    The script used there has changed to include the callback enhancement I mentioned. I also fixed a problem with the getParts function in IE 5.01/IE 5.5, altered the Array.push replacement slightly, and commented the code.

    I've now tested the script in IE versions 4.01, 5.01, 5.5 and 6, plus Firefox 1.0 and Opera 7.54u1, and it works on all of them. However,

    • Control generation still won't work with IE4, for reasons previously mentioned.
    • IE 5.01 doesn't like the example at all, but that's due to its poor CSS support, not the script. Ironically, versions 4 and 5.5 are fine, though 4 doesn't do quite what it's supposed to. Still, it's not as broken as 5.
    • The overlapping images are due to the use of absolute positioning. I originally used float but that revealed a rather annoying bug in Firefox that I couldn't be bothered to find a workaround for. Though I did fix it initially, adding the second demonstration just brought it back again, so I gave up. I must remember to check Bugzilla at some point to see if it's a known problem.


    One other change is the expected control id values. Instead of the back and forward suffixes, the code now looks for previous and next. They're more appropriate adjectives, and it homogenizes the code.

    I think that's it!

    Mike

  10. #10
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Nice work! One would think our original poster would have plenty to work with in tackling his/her objectives. I was thinking though that for someone like you or I who is comfortable using absolute positioning in laying out a page (either entirely or mixing it with other methods), this is all well and good. Can this rewritten script work like the one we are jumping off from, for folks who would rather not take that leap just yet? Looking back at DD's version, it appears that the placement of the initial division element determines where the multi-part content appears on a page and that only one short style declaration is required for content height. Can we emulate that simplicity, or go even further by having content entered into the script section and placement be determined by where, in the markup, we call the function from (rather than having it an onload event as it is in all versions so far including DD's)? I know that second part would be really tough. On a separate matter, I know what an 'em' is what's an 'ex', as in "padding: 1ex"?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •