We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 29181
    • 480 Posts
    Hi,
    this is just an enquiry to find out if anyone has done anything along these lines with ModX or has an idea how I should best approach it.

    To briefly describe the problem. The client wants a list of Opening Times for different times of the year and different times of the week etc. We are probably talking about 12 or 15 chunks at the moment. A default chunk displaying General Opening times will be displayed.

    Just below this he now wants a drop down menu showing all the possible opening times whereby a user can select one of the other options which will then replace the default opening times.

    Basically, then I need a snippet to grab a list of chunks (it would be good if I could find all the chunks under a certain heading) if possible, I then need to parse these chunks into a select list so that they are readable...ie from SundayOpeningTimes I need to make a Sunday Opening Times, to make things worse, some of the descriptions will contain commas and other special chars.

    When the user selects one of the new opening times, I need to grab the contents of the chunk and replace the current chunk, without relaoding the page if at all possible.

    I would very much appreciate any pointers on ANY parts of the above, or, of course, alternatives smiley

    Thanks,
    Taff
      Adrian Lawley: www.adrianlawley.com
      • 29181
      • 480 Posts
      After some thinking this over in bed last night...

      from SundayOpeningTimes I need to make a Sunday Opening Times, to make things worse, some of the descriptions will contain commas and other special chars.

      I think I will add the title right at the beginning of the chunk and then split it in the snippet so for example:

      Sunday Opening Times || Mon-Fri 09:00 -09:15 (Coffee from 09:05 to 09:12)

      will be split into title and content. smiley

      grab a list of chunks (it would be good if I could find all the chunks under a certain heading) if possible

      Well, I looked into the database and there is a snippet column and a category column in the site_htmlsnippets table...so maybe I’m on a winner here too.

      When the user selects one of the new opening times, I need to grab the contents of the chunk and replace the current chunk, without relaoding the page if at all possible.

      I read the AJAXify your site post...so maybe that is the solution. The problem will be if the person doesn’t have JavaScript installed...how am I going to call an onChange event for the drop down menu....Maybe adopt the AjaXSearch method and just create a div with links.

      One thing is for sure...this is definately an interesting little thing for me to work on. Hopefully it will open even more ModX doors. I’ll have a bit more of a think whilst I’m doing some higher priority stuff....and look forward to any pointers from the Guru’s wink

      Taff
        Adrian Lawley: www.adrianlawley.com
        • 34017
        • 898 Posts
        I would say the easiest way to get the chunks you need is to use the ’category’ field. You may also want to check out the @BINDINGS for TV’s as there is a lot you can do there. Also, heliotrope has created TV sort addon that might work for you (I havent tried it yet as the directions are in french).

        Chuck
          Chuck the Trukk
          ProWebscape.com :: Nashville-WebDesign.com
          - - - - - - - -
          What are TV's? Here's some info below.
          http://modxcms.com/forums/index.php/topic,21081.msg159009.html#msg1590091
          http://modxcms.com/forums/index.php/topic,14957.msg97008.html#msg97008
          • 29181
          • 480 Posts
          Thanks for your help Chuck,

          The @SELECT works remarkable well when you consider my lack of knowledge (hence calling a field a column wink ) Using a new TV I can output that .

          I think however that I’m going to have to delve deeper and use a snippet....so being the sort of guy I am I decided to see how others are accessing the DB. Trying to adapt a few lines from Wayfinder I have:
          <?php
          global $modx;
          $fields="id,name,description,category,snippet"; 
          $tblsc = $modx->getFullTableName("site_htmlsnippets");
          $catNo=11;
                 
          $sql = 'SELECT '.$fields.' FROM '.$tblsc.' WHERE category = '.$catNo.';';
                  $result = $modx->dbQuery($sql);
                  $resourceArray = array();
                  for($i=0;$i<@$modx->recordCount($result);$i++)  {
                    array_push($resourceArray,@$modx->fetchRow($result));
                  }
                  return $resourceArray;
             
          ?>
          


          but am receiving the following error:

          Parse error: parse error, unexpected ’}’ in c:\instantrails\instantrails\www\salem\manager\includes\document.parser.class.inc.php(748) : eval()’d code on line 13

          [EDIT]Getting Array returned now....global modx; works wonders LOL[/EDIT]

          *Sits up and begs* smiley

          Cheers,
          Taff
            Adrian Lawley: www.adrianlawley.com
            • 34017
            • 898 Posts
            I like the way it’s done in the $ppp snippet. It’s another idea for you.

            $table = $modx->getFullTableName($ppp_useTable);
            $results= $modx->db->select($fields, $table, "category= $catNo", "", "");
            									
            	while($row = $modx->db->getRow($results)) {
            		//do something
            	}
            


            The full code to loop through multiple rows and display them in a document is below. (You dont need this right here, but it’s a good example of getChunk, setPlaceholder.

            $table = $modx->getFullTableName($ppp_useTable);
            $results= $modx->db->select($fields, $table, "category= $catNo", "", "");
            									
            	while($row = $modx->db->getRow($results)) {
            		$key = '';
            		$value = '';
            					
            		$chunk_tpl = 'chunk_for_each_row'; //example: <field type="select" name="[+tvValueHere+]
            		$chunkTpl = $modx->getChunk($chunk_tpl);
            
            		foreach($row as $key => $value) {
            			$chunkTpl = str_replace('[+' . $key . '+]', $value, $chunkTpl);
            		}	
            					
            		$createList .= 	$chunkTpl;
            	}
            	
            	$listName = 'document_placeholder'; //put in your document [+document_placeholder+]
            	$modx->setPlaceHolder($listName, $createList);
            
              Chuck the Trukk
              ProWebscape.com :: Nashville-WebDesign.com
              - - - - - - - -
              What are TV's? Here's some info below.
              http://modxcms.com/forums/index.php/topic,21081.msg159009.html#msg1590091
              http://modxcms.com/forums/index.php/topic,14957.msg97008.html#msg97008
              • 29181
              • 480 Posts
              Firstly Chuck, thanks for all the help! grin

              I’ve decided against using Ajax for the time being. I couldn’t get my head around the Ajaxify your site post, with using template switchers and the like. I’m going to grab all the data I need from the db is a oner and create a JavaScript array.

              Something like this is what I’m using to grab the data I need:

              <?php
              global $modx;
              $fields="id,name,description,category,snippet";
              $tblsc = $modx->getFullTableName("site_htmlsnippets");
              $catNo=1;
              
              $sql = 'SELECT '.$fields.' FROM '.$tblsc.' WHERE category = '.$catNo.';';
              $result = $modx->dbQuery($sql);
              $resourceArray = array();
              for($i=0;$i<@$modx->recordCount($result);$i++) {
              array_push($resourceArray,@$modx->fetchRow($result));
              }
              ?>
              


              Building the JavaScript function
              echo "<script type=\"text/javascript\">
              function changeLink(ID)
              {
              var currText=ID.options[ID.selectedIndex].value;\n
              alert(currText);
              var chunkSnippets = new Array()
              
              foreach ($resourceArray as $arrayNumber => $arrayMulti){
              echo "chunkSnippets[".$arrayNumber."] = \"".$arrayMulti['snippet']\";
              }
              echo "document.getElementById('TagToBeRenamed').innerHTML=chunkSnippets[currText]";
              
              echo "}\n</script>";



              Something like this to create the select options
              <?php
              echo "<form name=\"selectChunkForm\" method=\"post\" action=\"\"><select name=\"select\" onChange=\"changeLink(this)\" >
              <option value=\"0\">Select other opening hours</option>";
              $outputTag="";
              foreach ($resourceArray as $arrayNumber => $arrayMulti){
              $outputTag .= "<option value='".$arrayNumber."' > ".$arrayMulti['description']."</option> \n";
              }
              echo $outputTag;
              echo "</select></form>";
              ?>


              And that will be it moreorless, a couple of other thing’s I need to browse PHP.net for is a way to remove the whitespace from the HTML chunk so as not to cause any problems with the JavaScript function and I should be good to go...Oh yes, a couple of placeholders so the JS goes at the top wink

              Thanks again,
              Taff
                Adrian Lawley: www.adrianlawley.com
                • 29181
                • 480 Posts
                <?php
                //forgetting this could case headaches
                global $modx;
                //handy variables for the sql call
                $fields="id,name,description,category,snippet";
                $tblsc = $modx->getFullTableName("site_htmlsnippets");
                $catNo=1;
                
                //get our fields from the db and save them into a multidimensional array
                $sql = 'SELECT '.$fields.' FROM '.$tblsc.' WHERE category = '.$catNo.';';
                $result = $modx->dbQuery($sql);
                $resourceArray = array();
                for($i=0;$i<@$modx->recordCount($result);$i++) {
                array_push($resourceArray,@$modx->fetchRow($result));
                }
                
                //Start creating the javascript function
                $js_output = "<script type=\"text/javascript\">
                function changeLink(ID)
                {
                var currText=ID.options[ID.selectedIndex].value;\n
                var chunkSnippets = new Array()\n";
                //loop thru our db results creating a JS array that looks like:
                // chunkSnippets[0] = "This is the HTML"
                foreach ($resourceArray as $arrayNumber => $arrayMulti){
                // addslashes...spent more time looking for this than the script itself ;-)
                $t = addslashes($arrayMulti['snippet']);
                //get rid of nasty newlines and that
                $s = str_replace(array("\n", "\r", "\t"), '', $t);
                //create the array
                $js_output.= "chunkSnippets[".$arrayNumber."] = \"".$s."\";\n";
                }
                //This is the magic replace innerHTML bit
                $js_output.= "document.getElementById('rename').innerHTML=unescape(chunkSnippets[currText])";
                //Finish off the JS tag
                $js_output.= "}\n</script>";
                $modx->setPlaceholder('JSfunction', $js_output);
                
                
                //Now for the select form
                $form_output = "<form name=\"selectChunkForm\" method=\"post\" action=\"\"><select name=\"select\" onChange=\"changeLink(this)\" >";
                //Loop through again, this time creating a select tag with all the options
                foreach ($resourceArray as $arrayNumber => $arrayMulti){
                $form_output .= "<option value='".$arrayNumber."' > ".$arrayMulti['description']."</option> \n";
                }
                //and finish the selct tag and form tag
                $form_output .= "</select></form>";
                $modx->setPlaceholder('selectTag', $form_output);
                ?>
                
                


                I wonder if there would be any interest in making this into a reusable snippet? I still need to add some "no javascript functionality" along the lines of "You have JavaScript turned off...I suppose seeing the opening times of our museums are the least of your worries!"

                You can view it at http://www.flash-genie.de where I’ve been pottering around with that and other things.

                Anyways, thanks for joining me on my journey Chuck!

                Taff
                  Adrian Lawley: www.adrianlawley.com
                  • 34017
                  • 898 Posts
                  No problem Taff. Do you think you could write a little tutorial on how you setup the chunks, categories, and form calls? I would love to see how you pieced that together.

                  Chuck

                    Chuck the Trukk
                    ProWebscape.com :: Nashville-WebDesign.com
                    - - - - - - - -
                    What are TV's? Here's some info below.
                    http://modxcms.com/forums/index.php/topic,21081.msg159009.html#msg1590091
                    http://modxcms.com/forums/index.php/topic,14957.msg97008.html#msg97008
                    • 29181
                    • 480 Posts
                    Sure thing, I can show you my strategy. Some thing’s could be improved in my (limited) opinion.
                    I created a new category where I placed all the opening times. I then looked at the {prefix}_categories table to see what id my "Opening Times" category had.
                    I suppose I could add that as a parameter to the snippet call if I need it again then look in this table for WHERE id = $parameterPassed which could save somebody without knowledge of phpMyAdmin and such some time...but for me I just defined it in the variable $catNo below.
                    The fields I’m selecting from the site_htmlsnippets and the table itself are also defined here:
                    <?php
                    //forgetting this could case headaches
                    global $modx;
                    //handy variables for the sql call$fields="id,name,description,category,snippet";
                    $tblsc = $modx->getFullTableName("site_htmlsnippets");
                    $catNo=1;
                    


                    Using the variables above I then grabbed the data I needed from a database and stuck it into an array called $resourceArray
                    //get our fields from the db and save them into a multidimensional array
                    $sql = 'SELECT '.$fields.' FROM '.$tblsc.' WHERE category = '.$catNo.';';
                    $result = $modx->dbQuery($sql);
                    $resourceArray = array();
                    for($i=0;$i<@$modx->recordCount($result);$i++) {
                    array_push($resourceArray,@$modx->fetchRow($result));
                    }
                    


                    I then needed to brush the dust of my JavaScript: The definitive guide & Ajax in Action to create the JS function.
                    Using a foreach array I populate a JavaScript array so that it looks like chunkSnippets[0] = "This is the HTML from the snippet field"
                    I also had to use addslashes so the user can simply craet HTML chunks using the RTE as is, without having to worry. It took me a long time to find addslashes. I was using HTMLentities and SpecialChars and I don’t know what. I kept getting an unknown Object JS error before that ...I knew why (the quotes in the HTML chunk) and that solved it, to be on the safe side I got rid of all newlines tabs and whatever \r does too wink
                    foreach ($resourceArray as $arrayNumber => $arrayMulti){
                    // addslashes...spent more time looking for this than the script itself ;-)
                    $t = addslashes($arrayMulti['snippet']);
                    //get rid of nasty newlines and that
                    $s = str_replace(array("\n", "\r", "\t"), '', $t);
                    //create the array and save each line to our js_output variable
                    $js_output.= "chunkSnippets[".$arrayNumber."] = \"".$s."\";\n";
                    }
                    


                    After browsing the web undecided whether to use the DOM, Ajax or simply innerHTML I went with innerHTML. The speed difference is minimal, and all the "everyday" browsers support it. If I used an AJAX library (like htmlhttprequest.js) we would be talking 7KB so I decided to load the chunks in straight away. the getElementById has been hard-coded, but yet again could easily be replaced by another parameter. So now I add

                    $js_output.= "document.getElementById('rename').innerHTML=chunkSnippets[currText]";


                    to do just that. Then using the nifty setPlaceHolder I did

                    $modx->setPlaceholder('JSfunction', $js_output);
                    


                    to create a [+JSfunction+] placeholder so that I can place the JS at the top of my template instead of in the content or somewhere else. A nifty little thing indeed.

                    It’s all downhill from here. Create a simple form that holds a <select> with an onChange handler, same principle as before, loop through with
                    foreach to create the option tags. This is somethign TobyL showed me a couple of weeks back...and it saves lives wink

                    foreach ($resourceArray as $arrayNumber => $arrayMulti){
                    $form_output .= "<option value='".$arrayNumber."' > ".$arrayMulti['description']."</option> \n";
                    }
                    


                    Close the select tag and create another placeholder for the jumpMenu and all is good.

                    $modx->setPlaceholder('selectTag', $form_output);
                    


                    Disclaimer: I’m not much of a programmer, and aren’t sure of any potential security threats, unseen overheads or anything like that...but it works
                    and that get’s the thumbs up from me. I’ll probably update the code to use those parameters I mentioned above.

                    Any comments?

                    Cheers,
                    Taff
                      Adrian Lawley: www.adrianlawley.com
                      • 29181
                      • 480 Posts
                      I’ve slightly updated the code to incorporate the category name to search for with a call similar to:

                      [[CreateJavaScriptArrayFromTable?&$catDescription=`Category to search for`]]

                        Adrian Lawley: www.adrianlawley.com