We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 40086
    • 14 Posts
    Hey Guys,

    I'm trying to figure out the best way to do this. I'm building a site for a client that has a search filter, with 3 drop downs, above every page that allows the user to browse videos/pages base on their search criteria. Each video/page will have a video and keywords associated with it. Once a user enters their criteria they will be taken to a page that displays all the results.

    Can this be done using getResources and template variables?

    Modx Revolution 2.2.14

    Example Code:

    <h2>Browse Classes</h2>
                 <form class="filter-form">
                      <select name="class-type">
                          <option value="">Class</option>
                          <option value="Wake Up">Wake Up</option>
                          <option value="Slow">Slow</option>
                          <option value="JY">JY</option>
                          <option value="Power">Power</option>
                      </select>
                      <select name="skill-level">
                          <option value="">Skill</option>
                          <option value="Beginner">Beginner</option>
                          <option value="Intermediate">Intermediate</option>
                          <option value="Advanced">Advanced</option>
                      </select>
                      <select name="duration">
                          <option value="">Duration</option>
                          <option value="120 min">120 min</option>
                          <option value="240 min">240 min</option>
                          <option value="360 min">360 min</option>
                      </select>
                      <input type="submit" class="submit-btn" value="Search"/>
                 </form>   		




    Thanks,
    Stalwil30
      • 20371
      • 58 Posts
      You sure can..

      Of course you need to create the template variables, class-type, skill-level, and duration.

      You'd probably want to use the FormIt plugin to help handle the form. The formit docs are pretty straight forward.. to hilight the important bit though.. you want to call [[!FormItRetriever]] on whatever page receives the submitted form, to convert your form fields into place holders like [[!+class-type]].

      You'd then call getResources.. I'm paraphrasing here but the important bit would look like:

        [[!FormItRetriever]]
        [[!getResources? 
          &parents=`[[*id]]` 
          &tpl=`myRowTpl`
          &tvFilters=`class-type==[[!+fi.class-type]],skill-level==[[!+fi.skill-level]],duration==[[!+fi.duration]]`
        ]]
      


      There's other ways to do this and it might look a lot tidier with a custom snippet, but I think this is the MODx way to do this..
        • 3749
        • 24,544 Posts
        That should definitely work, but it will be painfully slow if you have a lot of videos because of the way TVs are stored and the number of levels of processing involved.

        It would be *way* faster to extend the modResource object with something like ClassExtender and create the three options as fields in a custom database table. The three options would appear as drop-downs on the Create/Edit Resource page.

        You'd need a snippet to do the search, but ClassExtender's getExtResources snippet might do the job. The advantage would be that you'd get all results in a single query rather than potentially dozens of them with the data in TVs.

        The down side of doing that is that it would be more difficult to modify the options in the future than it would be with TVs.

        http://bobsguides.com/classextender-class.html
          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
          • 40086
          • 14 Posts
          Thanks Mr5o1! How do i display all the resources on the page by default before the filters are applied? Also, in the actually getResources call whenever i add 3 tv filters it stops working but when i just add 1 it starts to work again. Any ideas why?
            • 20371
            • 58 Posts
            Re: 3 filters not working, its hard to know based on the information I have. You need to debug by checking what the call to getResources actually looks like. Do that by outputting the parameters to HTML, something like this:

            [[!FormItRetriever]]
            [[!getResources?
              &parents=`[[*id]]`
              &tpl=`myRowTpl`
              &tvFilters=`class-type==[[!+fi.class-type]],skill-level==[[!+fi.skill-level]],duration==[[!+fi.duration]]`
            ]]
            <!--
            class-type==[[!+fi.class-type]],skill-level==[[!+fi.skill-level]],duration==[[!+fi.duration]]
            -->
            


            That way you can 'view source' to see what parameters are being passed, and see where you've gone wrong.

            Re: default values.. that's a little tricker. Once again a custom snippet might be the cleanest, but you could do it with setPlaceholders plugin. That call to FormItRetriever is just reading the $_POST data (from the form submission), and setting the $_POST values as placeholders. setPlaceholders can do that too, with the additional logic to set the placeholder to a wildcard '%' if the $_POST value doesn't exist.

            [[!setPlaceholders?
              &ph=`
                class-type == post.class-type !! "%" ||
                skill-level == post.skill-level !! "%" ||
                duration == post.duration !! "%"
              `
            ]]
            [[!getResources?
              &parents=`[[*id]]`
              &tpl=`myRowTpl`
              &tvFilters=`class-type==[[!+class-type]],skill-level==[[!+skill-level]],duration==[[!+duration]]`
            ]]
            <!--
            class-type==[[!+class-type]],skill-level==[[!+skill-level]],duration==[[!+duration]]
            -->
            


            A different method would be a custom snippet. If you create a snippet called 'myFilters' like so:

            $output = array();
            if (isset($_POST['class-type'])) $output[] = 'class-type==' . $_POST['class-type'];
            if (isset($_POST['skill-level'])) $output[] = 'skill-level==' . $_POST['skill-level'];
            if (isset($_POST['duration'])) $output[] = 'duration==' . $_POST['duration'];
            $output = implode(',', $output);
            return $output;
            


            Then you'd leave out the setPlaceholders / FormItRetriever and just call getResources like this:

            [[!getResources?
              &parents=`[[*id]]`
              &tpl=`myRowTpl`
              &tvFilters=`[[!myFilters]]`
            ]]
            <!--
            [[!myFilters]]
            -->
            


            Just keep in mind I haven't actually tried any of this code.. you'll have to debug :p
              • 47211
              • 6 Posts
              Hi.
              The only problem I can see with all solutions is the following: how display result with some selected values left "all"
              Example:
              instead of <select name="class-type">
              <option value="">Class</option>
              <option value="Wake Up">Wake Up</option>
              <option value="Slow">Slow</option>
              <option value="JY">JY</option>
              <option value="Power">Power</option>
              </select>
              we should have
              <select name="class-type">
              <option value="">All</option>
              <option value="">Class</option>
              <option value="Wake Up">Wake Up</option>
              <option value="Slow">Slow</option>
              <option value="JY">JY</option>
              <option value="Power">Power</option>
              </select>
                • 20371
                • 58 Posts

                <select name="class-type">
                <option value="%">All</option>
                <option value="">Class</option>
                <option value="Wake Up">Wake Up</option>
                <option value="Slow">Slow</option>
                <option value="JY">JY</option>
                <option value="Power">Power</option>
                </select> 
                


                Just pass "%" as the value for 'All'. the % sign is the wildcard for getResources tvFilters, so passing % will match all values for that tv.

                If you're going to leave the "Class" option in the dropdown, then you'll need to refactor the examples above.
                  • 47211
                  • 6 Posts
                  Thanks!!! Just missed this one - "%".