We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 40092
    • 265 Posts
    Hi guys, might be a long shot but i'm trying anyways.

    Might someone know or have an easy example on how to use AJAX to change a LIMIT to a query without refreshing the whole page.
    I'm wanting to make something that initially loads 6 results on page, and by pressing a butten the rest of the reuslts (between 20 to 40 in total per page).

    Not looking for ready to use copy/paste code here, but just an example wich will make me understand what need to do.

    Cheers
      • 45078
      • 34 Posts
      I'm working on something similar at the moment. I'll post my solution up here once it's done - essentially I'm going to create a static PHP script that runs the 'getResources' snippet using an offset value (starting from 0) as a query parameter to return the results; the JavaScript would keep tabs of the offset value, incrementing it (by 10 perhaps?) each time the "Load More" button is clicked and passing it to the AJAX call.
        • 4172
        • 5,888 Posts
        here's a bit of an angular - exercise:

        snippet 'getResourcesToJson':
        <?php
        
        $classname = $modx->getOption('classname',$scriptProperties,'modResource');
        $fields = $modx->getOption('fields',$scriptProperties,'id,pagetitle');
        $limit = $modx->getOption('limit',$scriptProperties,10);
        $offset = $modx->getOption('offset',$scriptProperties,0);
        $offset = $modx->getOption('offset',$_REQUEST,$offset);
        
        
        $items = array();
        $c = $modx->newQuery($classname);
        $c->select($modx->getSelectColumns($classname,$classname,'',explode(',',$fields)));
        
        $count = $modx->getCount($classname,$c);
        
        $c->limit($limit,$offset);
        //$c->prepare();echo $c->toSql();
        if ($collection = $modx->getCollection($classname,$c)){
            foreach ($collection as $object){
                $items[] = $object->toArray('',false,true);
            }    
        }
        
        
        $index = 'i'. str_pad($offset, 10 ,'0', STR_PAD_LEFT);
        $blocks['blocks'][$index]['items'] = $items;
        $blocks['offset'] = (int) $offset;
        $blocks['limit'] = (int) $limit;
        $blocks['index'] = $index;
        $blocks['last'] = $offset + $limit >= $count ? '1' : '0';
        
        return $modx->toJson($blocks);
        
        ?>
        


        html:
            <!doctype html>
            <html xmlns:ng="http://angularjs.org" ng-app="myApp">
            <head>
            <base href="[[++site_url]]" 
            </head>
            <body >
        
            <div ng-controller="ItemsCtrl">
                <div ng-repeat="block in blocks">
                  <div ng-repeat="item in block.items">
                    <h3>{{item.pagetitle}}</h3>
                  </div>
                </div>
                <div ng-repeat="morebutton in morebuttons">
                  <button ng-click = "loadMore()" >Load more</button>
                </div>   
            </div>
        
            <script src="http://code.angularjs.org/1.2.11/angular.min.js"></script> 
            <script type="text/javascript" >
                // declare a module
                var myApp = angular.module('myApp',[]);
             
                myApp.controller('ItemsCtrl', ['$scope','$http', function($scope,$http) {
                    
                    $scope.loadMore = function(){
                    
                        $http({method: 'GET', url: '[[~172]]?offset=' + $scope.offset}).
                          success(function(data, status, headers, config) {
                              if (data.blocks){
                                 $scope.setItems(data);
                              }
                              
                        }).
                          error(function(data, status, headers, config) {
                          // called asynchronously if an error occurs
                          // or server returns response with an error status.
                        });            
                    }
                    
                    $scope.setItems = function(json){
                        var offset = json.offset || 0;
                        var limit = json.limit || 0; 
                        var last = json.last || 0; 
                        var blockindex = json.index || 'i0';
                        $scope.blocks = $scope.blocks || {};
                        $scope.blocks[blockindex] = json.blocks[blockindex];
                                       
                        if (last == '1'){
                            $scope.morebuttons = [];
                        }else{
                            $scope.morebuttons = [{"text":"Load more"}];
                        }
                        
                        $scope.offset = offset+limit;               
                    }
                    
                    $scope.setItems([[!getResourcesToJson]]) ;
                    
                }]);     
            </script>       
        
            </body>
            </html>
        


        Create a Resource with a blank Template and just this content:

        [[!getResourcesToJson]]


        change this in the code above

        [[~172]]


        to the id of your new created ajax-resource

        Have fun!

        [ed. note: Bruno17 last edited this post 12 years, 8 months ago.]
          -------------------------------

          you can buy me a beer, if you like MIGX

          http://webcmsolutions.de/migx.html

          Thanks!
          • 40092
          • 265 Posts
          Thanks rodoneill, i'm 0 experienced in AJAX and looking on the internet gives me so many resources that say different things wich confuses instead of teaches me, really.

          And Thanks Bruno, i don't know angular, besides it's existence, yet. I've looked some intro's and looks quite good. I'll know what i'll be doing this weekend ;-)
            • 3749
            • 24,544 Posts
            This might help (or not). wink

            http://bobsguides.com/blog.html/2014/01/15/how-javascript-works-in-modx/

            I'm sorry, I don't have an example for you. What you want to do is relatively simple, if you're used to Ajax, but difficult to understand if you're not.

            The problem is that with an Ajax request, the results are returned to the browser, not to the server running MODX. You could use regular JS to alter the value of a form field before submitting the form, but you want to avoid refreshing the page.

            In that case, one way is to have a button on the screen with an OnClick() event that calls a JS function. That function issues an ajax request to a processor file and sends along some information in the form of a JSON string. The processor file contains PHP that uses the information sent in the Ajax call to do a query, then return a success flag along with the results.

            The Ajax call will have a "Success" function. When it receives the data back, it uses JS to alter what's on the screen and show the extra data.

            **********

            BTW, If the results won't ever be all that long, I would be inclined to cheat and do something like the following. It just puts the additional results in a hidden div and uses a button to toggle their visibility.

            Create a Tpl chunk called ResultsChunk like this:

            <div id="first" class="show">
              [[+initial_results]]
            </div>
            
            <div id="additional" class="hide">
                [[+additional_results]]
            </div>
            
            <button onclick="toggle('additional');">Show More</button>
            
            


            CSS:

            div.show {
               display:block;
            }
            div.hide {
               display:none;
            }


            Now the additional data is hidden on page load (though visible when you do a "view source").

            PHP

            Write a snippet that puts the first n results (as a string of HTML) in a variable called $first and the rest in a variable called $second (as a similar string).

            Then do this:

            $fields = array(
               'initial_results' => $first;
               'additional_results => $second;
            );
            return $modx->getChunk('ResultsChunk', $fields);


            JS (to show the additional data when the button is clicked)

            <script type="text/javascript">
            function toggle(divId) {
                var e = document.getElementById(divId);
                if(e.style.display == 'none')
                    e.style.display = 'block';
                else
                    e.style.display = 'none';
                
            }
            </script>


            If you don't want a second button click to hide it again, just leave out the "else". BTW, the JS could go at the top of the Tpl Chunk. [ed. note: BobRay last edited this post 12 years, 7 months ago.]
              Did I help you? Buy me a beer
              Get my Book: MODX:The Official Guide
              MODX info for everyone: http://bobsguides.com/modx.html
              My MODX Extras
              Bob's Guides is now hosted at A2 MODX Hosting
              • 40092
              • 265 Posts
              This really helps a lot, Bob! smiley

              Hadn't looked into it result-wise, they won't ever be longer than 50 per page. So i will be using it (sort of) the way you describe, probably better for SEO too. ;-)
              But, i also really want to thank Bruno again for (re) introducing me to Angular, i will certainly be using more of that, and your example will help me on a different page.

              Ask one, get more, that's why i ask here ;-)

              Cheers Guys!

                • 3749
                • 24,544 Posts
                I'm glad I could help. smiley
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting