We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26931
    • 2,314 Posts
    drwagner13, thanks for sharing smiley
      • 8109
      • 128 Posts
      EXAMPLE TEMPLATE

      I am providing the following template code to accompany my modified version of the PrevJumpNext snippet (ver 0.6) in hopes that it saves someone some time.

      Example snippet call:

      [!PrevJumpNext? &tpl=`PrevNextDiv` &displayWhat=`menutitle` &includeFolders=`0` &displayFixed=`0` &useJump=`0` &displayNoPrevNext=`1` &displayTotal=`0` &displayTitle=`1`  &sortBy=`pagetitle` &sortHow=`ASC`!]



      The template is saved as a chunk and called using the tpl parameter in the snippet call. So, following the example above, we can save the following as a chunk called "PrevNextDiv". Note that this template uses phx to handle some logic and the GetField snippet to get the parent document’s title:

      <div class="PrevJumpNext">
      <table>
      <tr>
      
      [+phx:if=`[+PJN_prevID+]`:is=`-1`:then=`
      
             <td class="previous"><p class="direction grayout">« Previous<br> </p></td>
      
      `:else=`
      
             <td class="previous"><p><a href="[~[+PJN_prevID+]~]"><span class="direction">« Previous</span><br>[+PJN_prevText+]</a></p></td>
      
      `+]
      
      <td class="index"><p><a href="[~[+PJN_indexID+]~]"><span class="direction">Back to</span><br>[[GetField? &parent=`1` &parentLevel=`1`]]</a></p></td>
      
      [+phx:if=`[+PJN_nextID+]`:is=`-1`:then=`
      
           <td class="next"><p><span class="direction grayout">Next »</span><br> </p></td>
      
      `:else=`
      
           <td class="next"><a href="[~[+PJN_nextID+]~]"><p><span class="direction">Next »</span><br>[+PJN_nextText+]</p></a></td>
      
      `+]
      
      </tr>
      </table>
      </div>


      And here’s some css to style the table.

      /********PREVNEXTJUMP********/
      
      div.PrevJumpNext {
      	margin: 10px 0;
      	border-top: 1px solid #658907;
      }
      
      .PrevJumpNext table {
      	width: 100%;
      	font-size: 0.8em;
      	line-height: 1.0em;
      	vertical-align: top;
      }
      
      .PrevJumpNext td {
      	width: 33%;
      	padding: 4px 4px 0 4px;	
      }
      
      .PrevJumpNext td p {
      	margin: 0;
      	padding: 0;
      }
      
      .PrevJumpNext td.previous p {
      	text-align: left;
      	padding-left: 4px;
      }
      
      .PrevJumpNext td.index p {
      	text-align: center;
      }
      
      .PrevJumpNext td.next p {
      	text-align: right;
      	padding-right: 4px;
      }
      
      .PrevJumpNext td.index:hover {
      	border-top: 3px solid #658907;
      	padding-top: 1px; //correct for hover effect
      }
      
      .PrevJumpNext td.previous:hover {
      	border-left: 3px solid #658907;
      	padding-left: 1px; //correct for hover effect
      }
      
      .PrevJumpNext td.next:hover {
      	border-right: 3px solid #658907;
      	padding-right: 1px;
      }
      
      .direction {
      	//font-variant: small-caps;
      	text-transform:uppercase;
      }
      
      .grayout {
      	color: #DAE6D8;
      }
      
      .PrevJumpNext td a {
      	color: #658907;
      	display: block; //causes link to fill table cell
      }
      
      .PrevJumpNext td a:hover {
      	color: #7D0C08;
      	text-decoration: none;
      }
      
      //*******END PREVNEXTJUMP*******//

        Revo 2.0.8-pl
        • 8109
        • 128 Posts
        I’ve discovered an ugly bug in this snippet. If called on a page that is a container with &includeFolders=`0`, the page does not get rendered and an error is returned. This is bad behavior! I may try to find a solution to the problem. Would it be best to output some sort of error message, or nothing at all?
          Revo 2.0.8-pl
          • 20085
          • 1 Posts
          Quote from: drwagner13 at Aug 22, 2009, 05:59 AM

          I’ve discovered an ugly bug in this snippet. If called on a page that is a container with &includeFolders=`0`, the page does not get rendered and an error is returned. This is bad behavior! I may try to find a solution to the problem. Would it be best to output some sort of error message, or nothing at all?

          After
          $y=1; (at around line 222)

          Add the line:
          $my_array = array();

          That should fix your problem.
            • 8109
            • 128 Posts
            Here is the updated code for version 0.6.1
            <?php
            /*
             * **************************
             * Snippet: PrevJumpNext
             * By: Jeroen Bosch modded by OncleBen31 modded by Aaron Heinrich
             * Modified for version 0.6.1 by D Russell Wagner (drwagner13), August 2009
             * Date: May 2006 - August 2009
             * version: 0.5 and 0.6 (based on the PrevJumpNext v0.4)
             * **************************
             *
             ******Version 0.6.1 changes*******
             *  A bug that caused the page to not be rendered if the page was a container and &includeFolders=`0` was set was fixed.
             *
             ******Version 0.6 changes*******
             *
             * This snippet is now templateable. The "usePlaceHolder" parameter is deprecated. Instead use the "tpl" 
             * parameter and provide a chunk with the appropriate placeholders. If a template is not provided, the
             * snippet output will be the usual output as before. To call this snippet multiple times per page, it is essential
             * to call it uncached: [!PrevNextJump!].
             *
             ******Version 0.5 changes*******
             *
             * the displayTotal parameter now returns the correct number of documents
             *
             * PNJ now accepts the following new parameters:
             * 
             * &displayWhat: to allow showing text other than the page title, such as the longtitle or menutitle
             * 
             * As a step toward making this snippet fully templatable, the output when using the "usePlaceHolder" option
             * now includes the following placeholders:
             
             *  - [+PJN_firstText+] : the first document's link text
             *  - [+PJN_firstID+] : the first document's ID *  - [+PJN_prevText+] : the previous document's link text
             *  - [+PJN_prevID+] : the previous document's ID
             *  - [+PJN_indexText+] : the text to use for the index page link
             *  - [+PJN_indexID+] : the index page ID
             *  - [+PJN_nextText+] : the next document's link text
             *  - [+PJN_nextID+] : the next document's ID
             *  - [+PJN_lastText+] : the last document's link text
             *  - [+PJN_lastID+] : the last document's ID
             *  - [+PJN_currentRecord+] : the current document's index value in the list
             *  - [+PJN_totalRecords+] : the total number of documents in the list
             * 
             * using the above placeholders, links can be built in a templated fashion:
             * <a href="[~[+PJN_firstID+]~]">[+PJN_firstText+]</a>
             * Note this is equivalent to the standard output, as given below, but the following is not:
             * <tr><a href="[~[+PJN_firstID+]~]">FIRST</a></tr>
             * <tr>[+PJN_firstText+]</a></tr>
             * 
             * you can  use the record numbers to make statements like "Showing record x of y."
             *
             * DESCRIPTION
             *
             * Generates links to navigate between documents in a directory.
             * Highly configurable. It can display :
             *  - 'Showing article x of x'
             *  - 'Prev' and 'Next' links with or without document titles
             *  - 'First' and 'Last' links.
             *  - 'Index' link to parent folder
             *  - A select to jump quickly to a document
             *
             *  Can output links or generate the following placeholders: 
             * the following placeholders output complete links to the referenced documents
             *  - [+PJN_first+] : a link to the first document
             *  - [+PJN_prev+] : a link to the  previous document
             *  - [+PJN_jump+] : the droplist to jump to the selected document
             *  - [+PJN_index+] : the link to return to the index page
             *  - [+PJN_next+] : a link to the next document
             *  - [+PJN_last+] : a link to the last document
             * the following placeholders can be used for making fully customized links
             *  - [+PJN_firstText+] : the first document's link text
             *  - [+PJN_firstID+] : the first document's ID 
             *  - [+PJN_prevText+] : the previous document's link text
             *  - [+PJN_prevID+] : the previous document's ID
             *  - [+PJN_indexText+] : the text to use for the index page link
             *  - [+PJN_indexID+] : the index page ID
             *  - [+PJN_nextText+] : the next document's link text
             *  - [+PJN_nextID+] : the next document's ID
             *  - [+PJN_lastText+] : the last document's link text
             *  - [+PJN_lastID+] : the last document's ID
             *  - [+PJN_currentRecord+] : the current document's index value in the list
             *  - [+PJN_totalRecords+] : the total number of documents in the list  
             *
             * PARAMETERS
             *
             * - startID : Int: id of document folder to start from (default: parent document id);
             * - sortBy : String : Document variable to sort items by. 'menuindex' or 'id' or 'createdon', etc...  (default: createdon);
             * - sortHow : [ASC|DESC] : Sort order? 'ASC' or 'DESC' (default ASC);
             * - tpl : String : name of chunk than holds the output template. ;
             * - displayTitle : Boolean : Display document titles instead of &prevText and &nextText (default true);
             * - displayWhat : String : What to display for the title: can be `pagetitle`, `longtitle`, or `menutitle` (default: pagetitle);
             * - displayFixed : Boolean : Show 'first' and 'last' links (default false);
             * - usePlaceHolder : DEPRECATED : Boolean : Generate placeholders and do not output html : [+PJN_first+] , [+PJN_prev+] , [+PJN_jump+] , [+PJN_index+] , [+PJN_next+] , [+PJN_index+]  (default false);
             * - useJump : Boolean : Replace the index link by the select list when NOT using the placeholders (default false);
             * - indexDocumentID : Int : ID of the document linked as "index". (default &startID);
             * - displayNoPrevNext : Boolean : Display &noPrevNextText in place of "previous" and "next" when there is no previous or next item (default false);
             * - noPrevNextText : String : Text to display if there is no Prev or Next item and &displayNoPrevNext == 1 :(default "No more records");
             * - indexText : String : Title for "index" item (default "Index");
             * - jumpText : String : Title for select list (default :"Please Select");
             * - firstText : String : Title for "first" link (default "First");
             * - prevText : String : Title for "previous" item when $displayTitle is set to false (default "Prev");
             * - nextText : String : Title for "next" item when $displayTitle is set to false (default "Next");
             * - lastText : String : Title for "last" item (default "Last");
             * - exclude : Array : Comma-separated list of document IDs to exclude from navigation (default [empty])
             * - separator : String : Inserted between items (default " | ");
             * - displayIndex : Boolean: display index menu item (default true);
             * - firstSymbol : String : Prefixed to "First" menu item (default [empty]);
             * - prevSymbol : String : Prefixed to "Previous" menu item (default [empty]);
             * - nextSymbol : String : Suffixed to "Next" menu item (default [empty]);
             * - lastSymbol : String : Prefixed to "Last" menu item (default [empty]);
             * - displayTotal : Boolean : Show "Showing article X of Y" item (default true);
             * - recordTypeName : String : Name of records type for "Total" item.  E.g. (if = "article") "Showing article 3 of 25" (default "article");
             * - includeFolders : Boolean : include folder documents in the menu (default true);
             * - maxTitleChars : Int : Truncate document titles to this number of characters (default 0 [=display entire title]
             *
             * OUTPUT
             *
             *  Menu items are not wrapped in an enclosing element. Output is anchor elements with semantic class names E.G.:
             *  <a href="url" class="previous">Previous Title</a> | <a href="url" class="index">Index</a> | <a href="url" class="next">Next Title</a>
             *  Class names are: total, currentNumber, totalNumber, first, previous, index, next, last
             *
             * EXAMPLE CALLS :
             *
             * [[PrevJumpNext? sortBy=`menuindex` &sortHow=`ASC` &displayTitle=`1`]]
             * 
             */
            
            // Settings
            
            if(!isset($startID)){
                $startID = $modx->documentObject['parent'];
            }
            if(!isset($sortBy)){
                $sortBy = 'createdon';
            }
            if(!isset($sortHow)){
                $sortHow = 'ASC';
            }
            if(!isset($tpl)){
                $tpl = '';
            }
            if(!isset($displayTitle)){
                $displayTitle = 1;
            }
            if(!isset($displayWhat)){
                $displayWhat = 'pagetitle';
            }
            if(!isset($titleMaxChars)){
                $titleMaxChars = 0;
            }
            if(!isset($displayFixed)){
                $displayFixed = 0;
            }
            if(!isset($usePlaceHolder)){
            	$usePlaceHolder = 0;
            }
            if(!isset($useJump)){
            	$useJump=false;
            }
            if(!isset($indexDocumentID)){
            	$indexDocumentID=$modx->documentObject['parent'];
            }
            if(!isset($displayNoPrevNext)){
            	$displayNoPrevNext=0;
            }
            if(!isset($noPrevNextText)){
            	$noPrevNextText="No more records";
            }
            if(!isset($indexText)){
            	$indexText="Index";
            }
            if(!isset($jumpText)){
            	$jumpText="Please Select";
            }
            if(!isset($firstText)){
            	$firstText="First";
            }
            if(!isset($prevText)){
            	$prevText="Prev";
            }
            if(!isset($nextText)){
            	$nextText="Next";
            }
            if(!isset($lastText)){
            	$lastText="Last";
            }
            if(!isset($exclude)){
            	$exclude=array();
            } else {
            	$exclude = split(",",$exclude);
            }
            if(!isset($separator)){
            	$separator=" | ";
            }
            if(!isset($displayIndex)){
            	$displayIndex=1;
            }
            if(!isset($firstSymbol)){
            	$firstSymbol="";
            }
            if(!isset($lastSymbol)){
            	$lastSymbol="";
            }
            if(!isset($prevSymbol)){
            	$prevSymbol="";
            }
            if(!isset($nextSymbol)){
            	$nextSymbol="";
            }
            if(!isset($displayTotal)){
            	$displayTotal=1;
            }
            if(!isset($recordTypeName)){
            	$recordTypeName="record";
            }
            if(!isset($includeFolders)){
            	$includeFolders=1;
            }
            
            $id = $modx->documentIdentifier;
            $fields='id,longtitle,pagetitle,menutitle,isfolder,hidemenu'; // what fields do you want to know
            $children = $modx->getActiveChildren($startID, $sortBy, $sortHow, $fields);
            $y = 1;
            $my_array = array();
            
            // sorting the documents, giving them a sequential and searchable index
            
            foreach ($children as $child) {
               if (!in_array($child['id'],$exclude) && !$child['hidemenu'] && !in_array($child['id'],$exclude) && ($includeFolders == 1 || $child['isfolder'] == 0)) {
                	$my_array[$y] = $child;
                	if ($my_array[$y]['id']==$id) {
                	    $current=$y; // The current page has number $y in the array
                	}
                   $y++;
                }
            }
            $prev = $current-1;
            $next = $current+1;
            $last = $y-1;
            
            //////// Construction of the elements
            
            $PJN_totalPlaceHolder = "Showing " . $recordTypeName . " <span class='currentNumber'>" . $current . "</span> of <span class='totalNumber'>" . $last . "</span>\n";
            
            // First item
            
            $PJN_firstPlaceHolder = "<a href='[~".$my_array[1]['id']."~]' class='first'>".$firstSymbol.$firstText."</a>" ;
            $PJN_firstID= $my_array[1]['id'];
            $PJN_firstText= $firstSymbol.$firstText;
            
            // Prev item
            
            if($prev > 0 && $displayTitle==false){
            
            	$PJN_prevPlaceHolder = "<a href='[~".$my_array[$prev]['id']."~]' class='previous'>".$prevSymbol.$prevText."</a>";
            	$PJN_prevID=$my_array[$prev]['id'];
            	$PJN_prevText=$prevSymbol.$prevText;
            
            } elseif($prev > 0 && $displayTitle==true) {
            	$prevTitle = ($maxTitleChars > 0) ? substr($my_array[$prev][$displayWhat],0,$maxTitleChars) . "..." : $my_array[$prev][$displayWhat];
            	$PJN_prevPlaceHolder = "<a href='[~".$my_array[$prev]['id']."~]' class='previous'>".$prevSymbol.$prevTitle."</a>";
            	$PJN_prevID=$my_array[$prev]['id'];
            	$PJN_prevText=$prevSymbol.$prevTitle;
            
            } elseif($prev == 0 && $displayNoPrevNext == true) {
            	$PJN_prevPlaceHolder = $noPrevNextText;
            	$PJN_prevText=$noPrevNextText;
                    $PJN_prevID=-1;
            }
             elseif($prev == 0) {
            	$PJN_prevPlaceHolder = '';
            	$PJN_prevText='';
                    $PJN_prevID=-1;
            }
            // Select List
            
            $PJN_jumpPlaceHolder = '<form action="" name="jump" id="jump">
            <select name="myjumpbox"
             onchange="location.href=jump.myjumpbox.options[selectedIndex].value">
            	 <option selected="selected">'.$jumpText;
            foreach ($my_array as $my_page) {
                 $jumpTitle = ($maxTitleChars > 0) ? substr($my_page[$displayWhat],0,$maxTitleChars) . "..." : $my_page[$displayWhat];
            	 $PJN_jumpPlaceHolder .= '    <option value="[~'.$my_page['id'].'~]">'.$jumpTitle.'</option>';
            	}
            $PJN_jumpPlaceHolder .= '</select></form>';
            
            // Index item
            
            $PJN_indexPlaceHolder = "<a href='[~".$indexDocumentID."~]' class='index'>".$indexText."</a>";
            
            // Next item
            
            if($next <= $last && $displayTitle==false){
            	$PJN_nextPlaceHolder = "<a href='[~".$my_array[$next]['id']."~]' class='next'>".$nextText.$nextSymbol."</a>";
            	$PJN_nextText=$nextText.$nextSymbol;
            	$PJN_nextID=$my_array[$next]['id'];
            } 
            
            elseif($next <= $last && $displayTitle==true) {
            	$nextTitle = ($maxTitleChars > 0) ? substr($my_array[$next][$displayWhat],0,$maxTitleChars) . "...".$nextSymbol : $my_array[$next][$displayWhat].$nextSymbol;
            	$PJN_nextPlaceHolder ="<a href='[~".$my_array[$next]['id']."~]' class='next'>".$nextTitle."</a>";
            	$PJN_nextText=$nextTitle;
            	$PJN_nextID=$my_array[$next]['id'];
            } 
            
            elseif($current == $last && $displayNoPrevNext == true) {
            	$PJN_nextPlaceHolder = $noPrevNextText;
            	$PJN_nextText=$noPrevNextText;
            	$PJN_nextID=-1;
            }
            elseif($current == $last) {
            	$PJN_nextPlaceHolder = '';
            	$PJN_nextText='';
                    $PJN_nextID=-1;
            }
            
            // Last item
            
            $PJN_lastPlaceHolder = "<a href='[~".$my_array[$last]['id']."~]' class='last'>".$lastText.$lastSymbol."</a>";
            $PJN_lastID=$my_array[$last]['id'];
            $PJN_lastText=$lastText.$lastSymbol;
            
            // //////// Output commputing modded by Oncleben31 modded by Aaron Heinrich
            
            //if ($usePlaceHolder==false) {
            if ($tpl=='') {
            
            	// Here starts the output
            	$output = "";
            
            	if ($displayTotal) {
            		$output .= "<span class=\"total\">" . $PJN_totalPlaceHolder . "</span>\n";
            
            	}
            
            	if($displayFixed==true && $prev-1>0) {
            		$output .= $PJN_firstPlaceHolder.$separator . "\n";
            	}
            
                	if ($prev>0 || $displayNoPrevNext == true) {
            	     $output .= $PJN_prevPlaceHolder; 
                        if ($displayIndex ==1  || $useJump==1 || $next < $last ) {
                             $output .= $separator;
                        }
            	}
            	if($useJump) {
            		$output .= $PJN_jumpPlaceHolder;
            		if ($next < $last || $displayNoPrevNext == true) {
                          $output .= $separator;
                    }
                    $output .= "\n";
            	} elseif ($displayIndex == 1) {
            		$output .= $PJN_indexPlaceHolder;
                            if ($next < $last || $displayNoPrevNext == true)  {
                                    $output .= $separator;
                            }
                    }
            		$output .=  "\n";
                    if ($next < $last || $displayNoPrevNext == true) {
            	      $output .= $PJN_nextPlaceHolder;
                      if ($displayFixed == true && $next+1 < $last) {
                                 $output .= $separator;
            	      }
            	      $output .= "\n";
                    }
            
            	if($displayFixed==true && $next+1 < $last) {
            		$output .= $PJN_lastPlaceHolder;
            		$output .= "\n";
            	}
            	return $output;
            }
            else {
            
            // Set PlaceHolder
            
            	$modx->setPlaceholder('PJN_total',$PJN_totalPlaceHolder);
            	
            	$modx->setPlaceholder('PJN_first',$PJN_firsPlaceHolder);
            	$modx->setPlaceholder('PJN_firstText',$PJN_firstText);
            	$modx->setPlaceholder('PJN_firstID',$PJN_firstID);
            	
            	$modx->setPlaceholder('PJN_prev',$PJN_prevPlaceHolder);
            	$modx->setPlaceholder('PJN_prevText',$PJN_prevText);
            	$modx->setPlaceholder('PJN_prevID',$PJN_prevID);
            	
            	$modx->setPlaceholder('PJN_jump',$PJN_jumpPlaceHolder);
            	
            	$modx->setPlaceholder('PJN_index',$PJN_indexPlaceHolder);
            	$modx->setPlaceholder('PJN_indexID',$indexDocumentID);
            	$modx->setPlaceholder('PJN_indexText',$indexText);
            	
            	
            	$modx->setPlaceholder('PJN_next',$PJN_nextPlaceHolder);
            	$modx->setPlaceholder('PJN_nextText',$PJN_nextText);
            	$modx->setPlaceholder('PJN_nextID',$PJN_nextID);
            	
            	$modx->setPlaceholder('PJN_last',$PJN_lastPlaceHolder);
            	$modx->setPlaceholder('PJN_lastText',$PJN_lastText);
            	$modx->setPlaceholder('PJN_lastID',$PJN_lastID);
            
                   $modx->setPlaceholder('PJN_currentRecord',$current);
            	$modx->setPlaceholder('PJN_totalRecords',$last);
            
            return $modx->getChunk($tpl);
            
            }
            ?>

              Revo 2.0.8-pl
              • 879
              • 2 Posts
              on line 321 you have:

                     $jumpTitle = ($maxTitleChars > 0) ? substr($my_page['pagetitle'],0,$maxTitleChars) . "..." : $my_page['pagetitle'];
              
                   $PJN_jumpPlaceHolder .= '    <option value="[~'.$my_page['id'].'~]">'.$jumpTitle.'</option>';
              
                  }
              


              this will fail on empty containers.

              the following code fixes it:

              if (is_array($my_array)) {
                     $jumpTitle = ($maxTitleChars > 0) ? substr($my_page['pagetitle'],0,$maxTitleChars) . "..." : $my_page['pagetitle'];
              
                   $PJN_jumpPlaceHolder .= '    <option value="[~'.$my_page['id'].'~]">'.$jumpTitle.'</option>';
              
                  }
              }
              



              p.s.: well i think that mojo has posted yesterday another solution for the same problem...
                • 17705
                • 501 Posts
                hi, nice update!

                btw, I tried it... with 5 documents... the index showed x of 5, but it stoped at 4... and Next link disappear

                no idea why...
                  • 17705
                  • 501 Posts
                  btw...

                  "previous" and "next" can be showed always?
                  even when you are in the begining, or the end... ?
                    • 8109
                    • 128 Posts
                    Dear luuciano,

                    If you are using a template, you must handle the first and last cases separately. I apply a css class to my prev or next items when on the first or last page and do not include the hyperlink. In my case I use a class called greyout, and the css does just that. My sample template is posted in a prior post to this forum. See above!

                    I’m open to suggestions for other ways to handle this.

                    I hope this helps. As for your prior issue, I can only imagine that the "show in menu" flag might be unchecked on the last document?
                      Revo 2.0.8-pl
                      • 17705
                      • 501 Posts
                      drwagner, thanks a lot!
                      I have instaled phx (really nice!)
                      and used something similar... thanks for the tip and your PrevJumpNext improvement