We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22673
    • 72 Posts
    I would like to create a search using select inputs rather than typing a search word into a text input.
    If there were 3 select (dropdown) inputs, the search would only bring back results that contained ALL 3 selected inputs.

    Simplesearch using select inputs would't work as this would bring back results with ANY of the 3 selected inputs.

    Is there a way of doing this with getResources? [ed. note: paramaniac last edited this post 14 years, 10 months ago.]
      • 4172
      • 5,888 Posts
      Can you give us an example and more details in which fields to search and what are the contents of this fields and your select-inputs?
        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 22673
        • 72 Posts
        Sure, in my case the user is searching for holidays. The search filters are TVs as follows:

        Location
        - The Alps
        - USA
        - Turkey
        - Morocco
        - Brazil

        Type
        - Cross country
        - SIV/Acro
        - Adventure
        - Beginners
        - Low airtime

        Cost
        - £200 - £300/week
        - £300 - £400/week
        - £400 - £500/week
        - £500 - £600/week
        - £600+/week

        Each holiday has one option selected from each of the TVs above.

        The search form displays each of the 3 filters as select boxes with their options. The user selects an option for each one. When they submit the form, the results are those holidays which have ALL of the user's selected options. Not just one of the user's selected options.

        I hope this makes sense!
          • 4172
          • 5,888 Posts
          you can try this snippet:

          <?php
          
          //[[filterResources? &tvNames=`cb1,cb2`]]
          
          //$tvNames = 'cb1,cb2';
          //$debug = 1;
          
          $tmplVarTbl = $modx->getTableName('modTemplateVar');
          $tmplVarResourceTbl = $modx->getTableName('modTemplateVarResource');
          
          $tvNames = explode(',', $tvNames);
          
          $c = $modx->newQuery('modResource');
          $columns = $modx->getSelectColumns('modResource', 'modResource', 'res_', array('id'));
          $c->select($columns);
          
          foreach ($tvNames as $cGroup => $tvName) {
          
              $tvValue = $_REQUEST[$tvName];
              $tvName = $modx->quote($tvName);
              
              if (is_array($tvValue)){
                  $conjunction= xPDOQuery::SQL_AND;
                  foreach ($tvValue as $value){
                      $c->where("EXISTS (SELECT 1 FROM {$tmplVarResourceTbl} tvr JOIN {$tmplVarTbl} tv ON CONCAT('||',tvr.value,'||') LIKE '%||{$value}||%' AND tv.name = {$tvName} AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id)",$conjunction, null, $cGroup);    
                      $conjunction= xPDOQuery::SQL_OR;
                  }
              }
              else{
                  $c->where("EXISTS (SELECT 1 FROM {$tmplVarResourceTbl} tvr JOIN {$tmplVarTbl} tv ON CONCAT('||',tvr.value,'||') LIKE '%||{$tvValue}||%' AND tv.name = {$tvName} AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id)",xPDOQuery::SQL_AND, null, $cGroup);        
              }
          
          }
          
          
          
          $c->prepare();
          if ($debug) {
              echo $c->toSql().'<br />';
          }
          
          $sql = $c->toSql();
          /* hmm.. funktioniert irgendwie nicht
          if ($collection = $modx->getCollection($c)){
          foreach ($collection as $object){
          print_r($object->toArray());
          $ids[] = $object->get('res_id'); 
          }  
          }
          */
          //dann eben so:
          $stmt = $modx->query($sql);
          if ($stmt) {
              while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                  $ids[] = $row['res_id'];
              }
          }
          
          
          $scriptProperties['resources'] = implode(',', $ids);
          if ($debug) {
              echo 'IDs: '. $scriptProperties['resources'].'<br />';
          }
          
          if (!empty($ids)){
              return $modx->runSnippet('getResources', $scriptProperties);
          }
          


          The snippet looks a bit complicated, because it handles also multiselects or checkboxes and uses the OR-conjunction between there arrays. This part isn't relevant for your situation.


          Give your select-boxes the same names as your TVs and call it this way:

          [[!filterResources? &tvNames=`Location,Type,Cost`]]


          You can add all getResources-properties to this snippet-call like:

          &tpl=`yourGetResourcesTpl` and all that.

          If you want to have your select-boxes autocreated from your TV-options you can try this snippet:

          <?php
          //[[getoptions? &tpl=`mySelectBoxChunk` &tvname=`Location` &name=`Location`]]
           
          $tv = $modx->getObject('modTemplateVar',array('name'=>$tvname));
          $options = explode('||',$tv->get('elements'));
           
          foreach ($options as $option){
              $opt = explode ('==',$option);
              $ph['value'] = count($opt)>1 ? $opt[1]: $opt[0];
              $ph['text'] = $opt[0];
              $ph['name'] = !empty($asArray) ? $name.'[]' : $name;
              $ph['checked'] = ''; 
              $ph['selected'] = '';
              
              if ((is_array($_REQUEST[$name]) && in_array($ph['value'],$_REQUEST[$name])) || $_REQUEST[$name] == $ph['value']){
          
                  $ph['checked'] = 'checked="checked"'; 
                  $ph['selected'] = 'selected="selected"';      
                 
              }
          
              $output .= $modx->getChunk($tpl,$ph);
          }
           
          return $output;
          
          [ed. note: Bruno17 last edited this post 14 years, 10 months ago.]
            -------------------------------

            you can buy me a beer, if you like MIGX

            http://webcmsolutions.de/migx.html

            Thanks!
            • 22673
            • 72 Posts
            Hi bruno. This looks good and thanks for you help! However could you explain how to pass the values of the selectboxes to the [[filterResources]] snippet?

            I tried this but I think it's completely wrong:

            <form action="[[~[[*id]]]]" method="GET">
              <select name="tvLocation">
                <option value="The Alps">The Alps</option>
                <option value="USA">USA</option>
                <option value="Turkey">Turkey</option>
                <option value="Morocco">Morocco</option>
                <option value="Brazil">Brazil</option>
              </select>
              <select name="tvType">
                <option value="Cross Country">Cross Country</option>
                <option value="SIV/Acro">SIV/Acro</option>
                <option value="Adventure">Adventure</option>
                <option value="Beginners">Beginners</option>
                <option value="Low airtime">Low airtime</option>
              </select>
              <select name="tvCost">
                <option value="£200 - £300/week">£200 - £300/week</option>
                <option value="£300 - £400/week">£300 - £400/week</option>
                <option value="£400 - £500/week">£400 - £500/week</option>
                <option value="£500 - £600/week">£500 - £600/week</option>
                <option value="£600+/week">£600+/week</option>
              </select>
              <input type="submit" value="Submit" />
            </form>
            
            [[filterResources? &tvNames=`tvLocation,tvType,tvCost` &tpl=`tplResult`]]
              • 4172
              • 5,888 Posts
              call the snippet uncached and try using post as method

              <form method="POST">
                <select name="tvLocation">
                  <option value="The Alps">The Alps</option>
                  <option value="USA">USA</option>
                  <option value="Turkey">Turkey</option>
                  <option value="Morocco">Morocco</option>
                  <option value="Brazil">Brazil</option>
                </select>
                <select name="tvType">
                  <option value="Cross Country">Cross Country</option>
                  <option value="SIV/Acro">SIV/Acro</option>
                  <option value="Adventure">Adventure</option>
                  <option value="Beginners">Beginners</option>
                  <option value="Low airtime">Low airtime</option>
                </select>
                <select name="tvCost">
                  <option value="£200 - £300/week">£200 - £300/week</option>
                  <option value="£300 - £400/week">£300 - £400/week</option>
                  <option value="£400 - £500/week">£400 - £500/week</option>
                  <option value="£500 - £600/week">£500 - £600/week</option>
                  <option value="£600+/week">£600+/week</option>
                </select>
                <input type="submit" value="Submit" />
              </form>
               
              [[!filterResources? &tvNames=`tvLocation,tvType,tvCost` &tpl=`tplResult`]]
              


              what do you get with:
              [[!filterResources? &tvNames=`tvLocation,tvType,tvCost` &tpl=`tplResult` &debug=`1`]]

                -------------------------------

                you can buy me a beer, if you like MIGX

                http://webcmsolutions.de/migx.html

                Thanks!
                • 22673
                • 72 Posts
                The snippet just shows all the results without submitting the form. When I browse to the page, all results are shown along with the following debug info:

                SELECT `modResource`.`id` AS `res_id` FROM `modx_site_content` AS `modResource` WHERE ( EXISTS (SELECT 1 FROM `modx_site_tmplvar_contentvalues` tvr JOIN `modx_site_tmplvars` tv ON CONCAT('||',tvr.value,'||') LIKE '%||||%' AND tv.name = 'tvLocation' AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id) AND EXISTS (SELECT 1 FROM `modx_site_tmplvar_contentvalues` tvr JOIN `modx_site_tmplvars` tv ON CONCAT('||',tvr.value,'||') LIKE '%||||%' AND tv.name = 'tvType' AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id) AND EXISTS (SELECT 1 FROM `modx_site_tmplvar_contentvalues` tvr JOIN `modx_site_tmplvars` tv ON CONCAT('||',tvr.value,'||') LIKE '%||||%' AND tv.name = 'tvCost' AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id) ) IDs: 
                  • 5811
                  • 1,717 Posts
                  You could also use AdvSearch with a queryHook.

                  See this demo as example. The documentation about queryHook is available on this page.
                    • 4172
                    • 5,888 Posts
                    I've upgraded the snippet above, to run getResources only, when there are IDs.

                    And you will need to add &parents=`-1` to the snippet-call:

                    [[!filterResources? &tvNames=`tvLocation,tvType,tvCost` &tpl=`tplResult` &parents=`-1`]]



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

                      you can buy me a beer, if you like MIGX

                      http://webcmsolutions.de/migx.html

                      Thanks!
                      • 22673
                      • 72 Posts
                      Thanks Bruno! It seems to work great. I will be using this for my next project.

                      A quick question, how do I specify the folder/parent which contains my resources if it needs to be set as `-1` and the folder/parent isn't id number 1?