We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 38004
    • 96 Posts
    Has anyone used this plugin?

    I need my end user to be able to search/sort products by TV e.g manufacturer, category etc..

    catalogSearch is the only add-on i've seen that does this, but there is not documentation for it.

      • 38004
      • 96 Posts
      I've got the basic calls right, but i've got no idea what to put in the templates.

      Without any instructions or advice it's just pure guess work.

      Is there any other way to search by TVs using drop downs?
        • 15083
        • 697 Posts
        getResources lets u filter by TV I think.
        U could write a custom snippet?
          • 38004
          • 96 Posts
          That's no good to the end user. getResources will just display a list of whatever I code it to display. It is not possible for the end user to search this list at all, let alone by TVs such as size, manufacturer etc..

          The catalog snippet is what I need, but I need the developer to provide more information.

          A custom snippet might do it, but not with my skills.

          I'm quite surprised no-one has done something like this before. There are threads on here and it seems anybody wanting this feature just gave up.
            • 38004
            • 96 Posts
            Here are what the instructions say:

            Add snippet "searchForm" to your template. Specify following parameters
            cattpl - ID category template, prodtpl - ID product template (TV from this template will use as fields in search form).

            example
             [[!searchForm? &cattpl=`10` &prodtpl=`11` &tpl=`catSearchForm`]]


            Create page named "catsearch" (must be container). For output search results add snippet
            [[!catSearch? &tpl=`product` &tplid=`11`]] 
            and specify following parameters tpl - name of chunk serving as resource template, tplid - ID of template contained TVs.

            So I added the following:

             [[!searchForm? &cattpl=`32` &prodtpl=`5` &tpl=`catSearchForm`]]
            

            Where 32 is the id of the container called "catsearch"

            5 is the ID of the template i'm using for my products that contains dropdowns

            At id 32 I have created a container called "catsearch" and put the following code in it:

            [[!catSearch? &tpl=`product_list` &tplid=`5`]]


            Here product_list is a template chunk i use when listing products using getResources

            5 is the id of the product template that contains the TVs.

            The behaviour i'm getting is that I can see the search form, but only two of my TVs for that template show up.

            Hitting "search" takes me back to my sites home page, rather than showing me a list of products.

            Here is the searchForm code:

            <?php
            // ????????? ?????? ?????????
            function getResourceTree($modx, $tpl, $parent = NULL, $context = NULL, $level=0) {
              $data = array();
              $c = $modx->newQuery('modResource');
              $c->select('
                `modResource`.*
              ');
              $c->where(array("template" => $tpl));
              if($parent != NULL) {
                $c->where(array("parent" => $parent));
              }elseif($context != NULL) {
                $c->where(array("context_key" => $context, "parent" => 0));
              }
              $resources = $modx->getCollection('modResource',$c);
              
              foreach($resources as $res) {
                $name = str_repeat(":: ", $level).$res->get("pagetitle");
                $data[] = array("id" => $res->get("id"), "name" => $name);
                $data = array_merge($data, getResourceTree($modx, $tpl, $res->get("id"), NULL, $level+1));
              }
              return $data;
            }
            
            function getResourceParents2($modx, $id) {
              $obj = $modx->getObject('modResource', $id);
              $data = array();
              $c = $modx->newQuery('modResource');
              $c->select('
                `modResource`.*
              ');
              if($id != NULL) {
                $c->where(array("id" => $obj->get('parent')));
              } else
                return false;
              $resources = $modx->getCollection('modResource',$c);
              
              foreach($resources as $res) {
                $data[] = $res->get("id");
                $data = array_merge($data, getResourceParents2($modx, $res->get("parent")));
              }
              return $data;
            }
            
            $cattpl = $modx->getOption('cattpl',$scriptProperties,'ResourceItem');
            $prodtpl = $modx->getOption('prodtpl',$scriptProperties,'ResourceItem');
            $tpl = $modx->getOption('tpl',$scriptProperties,'ResourceItem');
            
            $cats = getResourceTree($modx, $cattpl, NULL, 'catalog');
            $catPars = getResourceParents2($modx, $_GET["qwe"]);
            $catPars[] = $_GET["qwe"];
            $catList = '<div><label for="qwe">Search for products</label><select name="qwe" id="qwe">';
            foreach($cats as $cat) {
              if(!empty($_GET["qwe"]) && in_array($cat["id"],$catPars))
                $catList .= '<option value="'.$cat["id"].'" label="' .$cat["name"]. '" rel="selected">' .$cat["name"]. '</option>';
              else
                $catList .= '<option value="'.$cat["id"].'" label="' .$cat["name"]. '">' .$cat["name"]. '</option>';
            }
            $catList .= "</select></div>";
            $catList .= '<div><label for="name">Keyword</label> <input id="name" type="text" name="keyword"';
            if(!empty($_GET["keyword"]))
              $catList .= 'value="'.$_GET["keyword"].'"';
            $catList .= '/></div>';
            
            $TVars = array();
            $c = $modx->newQuery('modTemplateVarTemplate');
            $c->select('
              `modTemplateVarTemplate`.*
            ');
            
            $c->where(array("`modTemplateVarTemplate`.templateid"=>$prodtpl));
            
            $tvids = $modx->getCollection('modTemplateVarTemplate',$c);
            
            foreach($tvids as $tvid){
              $q = $modx->newQuery("modTemplateVar");
              $q->where(array("id"=>$tvid->get("tmplvarid")));
              $tvs = $modx->getCollection("modTemplateVar",$q);
              foreach($tvs as $tv) {
                if($tv->get("type") == "listbox")
                  $TVars[] = array(
            	  "name" => $tv->get("name"),
            	  "caption" => $tv->get("caption"),
            	  "type" => $tv->get("type"),
            	  "id" => $tv->get("id")
                  );
              }
            }
            foreach($tvids as $tvid){
              $q = $modx->newQuery("modTemplateVar");
              $q->where(array("id"=>$tvid->get("tmplvarid")));
              $tvs = $modx->getCollection("modTemplateVar",$q);
              foreach($tvs as $tv) {
                if($tv->get("type") == "text" || $tv->get("type") == "textarea" || $tv->get("type") == "number")
                  $TVars[] = array(
            	  "name" => $tv->get("name"),
            	  "caption" => $tv->get("caption"),
            	  "type" => $tv->get("type"),
            	  "id" => $tv->get("id")
                  );
              }
            }
            
            $ranges = array();
            $output = '<form action="" method="get">';
            
            for($i=0;$i<count($TVars);$i++) {
              if($TVars[$i]["type"]=="number") {
                $output .= '<div>
            		<label for="'.$TVars[$i]["name"].'_f">'.$TVars[$i]["caption"].'</label>
            		?? <input class="input-range" type="text" id="'.$TVars[$i]["name"].'_f" name="'.$TVars[$i]["name"].'_f">
            		?? <input class="input-range" type="text" id="'.$TVars[$i]["name"].'_t" name="'.$TVars[$i]["name"].'_t">
            		</div><div class="range" id="'.$TVars[$i]["name"].'-range"></div>';
                
                $tableName = $modx->getTableName('modTemplateVarResource');
                //$mvq = new xPDOCriteria($modx, "SELECT * FROM ".$tableName." WHERE `tmplvarid`='".$TVars[$i]["id"]."' ORDER BY `value` DESC LIMIT 1");
                $mvq = new xPDOCriteria($modx, "SELECT *, CAST(value AS SIGNED) as int_val FROM ".$tableName." WHERE tmplvarid='".$TVars[$i]["id"]."' ORDER BY int_val DESC LIMIT 1");
                $dc = $modx->getCollection("modTemplateVarResource", $mvq);
                foreach($dc as $c) {
                  $max = $c->get('value'); break;
                }
                
                $ranges[] = array("name" => $TVars[$i]["name"], "max" => $max);
              }
               if($TVars[$i]["type"]=="listbox") {
                 $sRaw = $modx->getObject("modTemplateVar", $TVars[$i]["id"]);
                 $sValue = $sRaw->get('elements');
                 $sOptions = explode("||",$sValue);
                 $output .= '
            	<div>
            	<label for="'.$TVars[$i]["name"].'">'.$TVars[$i]["caption"].'</label>
            	<select name="'.$TVars[$i]["name"].'" id="'.$TVars[$i]["name"].'">
            	<option value="">-- Please select --</option>';
                 foreach($sOptions as $sOption) {
                   if(!empty($_GET[$TVars[$i]["name"]]) && $_GET[$TVars[$i]["name"]]==$sOption)
            	 $output .= '<option value="'.$sOption.'" selected>'.$sOption.'</option>';
                   else
                   	 $output .= '<option value="'.$sOption.'">'.$sOption.'</option>';
                 }
                 $output .= '</select></div>';
               }
            }
            
            $res = $modx->getChunk($tpl,array("data"=>$output, "categories"=>$catList));
            
            $modx->regClientCSS('assets/extra/smoothness/jquery-ui-1.8.16.custom.css');
            $modx->regClientCSS('assets/extra/catsearch.css');
            $modx->regClientStartupScript('assets/extra/jquery.js');
            $modx->regClientStartupScript('assets/extra/jquery-ui.js');
            $modx->regClientStartupScript('assets/extra/catsearch.js');
            foreach($ranges as $range) {
              $smin = 0;
              $smax = $range["max"];
              if(!empty($_GET[$range["name"]."_f"]))
                $smin = $_GET[$range["name"]."_f"];
              if(!empty($_GET[$range["name"]."_t"]))
                $smax = $_GET[$range["name"]."_t"];
              $modx->regClientStartupHTMLBlock('
              <script>
                $(function() {
                  '.$range["name"].'_slider = $( "#'.$range["name"].'-range" ).slider({
            	range: true,
            	min: 0,
            	max: '.$range["max"].',
            	values: [ '.$smin.', '.$smax.' ],
            	slide: function( event, ui ) {
            		$( "#'.$range["name"].'_f" ).val(ui.values[ 0 ]);
            		$( "#'.$range["name"].'_t" ).val(ui.values[ 1 ]);
            	}
                  });
                  $( "#'.$range["name"].'_f" ).val( $( "#'.$range["name"].'-range" ).slider( "values", 0 ));
                  $( "#'.$range["name"].'_t" ).val( $( "#'.$range["name"].'-range" ).slider( "values", 1 ));
            
                  $( "#'.$range["name"].'_f" ).change(function(){
            	v0 = $( "#'.$range["name"].'_f" ).val();
            	v1 = $( "#'.$range["name"].'-range" ).slider( "values", 1 );
            	'.$range["name"].'_slider.slider({values: [v0, v1]});
                  });
                  $( "#'.$range["name"].'_t" ).change(function(){
            	v0 = $( "#'.$range["name"].'-range" ).slider( "values", 0 );
            	v1 = $( "#'.$range["name"].'_t" ).val();
            	'.$range["name"].'_slider.slider({values: [v0, v1]});
                  });
                });
              </script>
              ');
            }
            
            return $res;


            Here is the catSearch code:

            <?php
            function getResourceParents($modx, $parent = NULL) {
              $data = array();
              $c = $modx->newQuery('modResource');
              $c->select('
                `modResource`.*
              ');
              if($parent != NULL) {
                $c->where(array("parent" => $parent));
              } else
                return false;
              $resources = $modx->getCollection('modResource',$c);
              
              foreach($resources as $res) {
                $data[] = $res->get("id");
                $data = array_merge($data, getResourceParents($modx, $res->get("id")));
              }
              return $data;
            }
            
            $output = "";
            $tplid = $modx->getOption('tplid',$scriptProperties,'ResourceItem');
            $tpl = $modx->getOption('tpl',$scriptProperties,'ResourceItem');
            
            // ????????? ????????? ???????
            $params = array();
            foreach($_GET as $key => $value) {
              if($key != "q" && $key != "c" && $value != "")
                $params[$key] = $value;
            }
            if(!count($params)) return;
            
            // ???????? ?????? tv ??? ?????????? ???????
            $TVars = array();
            $c = $modx->newQuery('modTemplateVarTemplate');
            $c->select('
              `modTemplateVarTemplate`.*
            ');
            $c->where(array("templateid"=>$tplid));
            
            $tvids = $modx->getCollection('modTemplateVarTemplate',$c);
            
            foreach($tvids as $tvid){
              $q = $modx->newQuery("modTemplateVar");
              $q->where(array("id"=>$tvid->get("tmplvarid")));
              $tvs = $modx->getCollection("modTemplateVar",$q);
              foreach($tvs as $tv) {
                if($tv->get("type") == "text" || $tv->get("type") == "textarea" || $tv->get("type") == "number")
                  $TVars[] = array(
            	  "name" => $tv->get("name"),
            	  "caption" => $tv->get("caption"),
            	  "type" => $tv->get("type")
                  );
              }
            }
            
            // ???????
            $tableName = $modx->getTableName('modResource');
            $criteria = "SELECT * FROM " . $tableName . " WHERE `template`='".$tplid."'";
            if(!empty($params["qwe"])) {
              $childsArr = getResourceParents($modx, $params["qwe"]);
              $childs = $params["qwe"] . "," . join($childsArr,",");
              $criteria .= " AND `parent` IN (" .$childs. ")";
            }
            if(!empty($params["keyword"])) {
              $criteria .= " AND (";
              $criteria .= "`pagetitle` LIKE '%".$params["keyword"]."%'";
              $criteria .= " OR `longtitle` LIKE '%".$params["keyword"]."%'";
              $criteria .= " OR `description` LIKE '%".$params["keyword"]."%'";
              $criteria .= " OR `introtext` LIKE '%".$params["keyword"]."%'";
              $criteria .= " OR `content` LIKE '%".$params["keyword"]."%'";
              $criteria .= ")";
            }
            
            $q = new xPDOCriteria($modx,$criteria);
            $resources = $modx->getCollection("modResource", $q);
            
            $data = array();
            foreach($resources as $rid=>$resource) {
              $templateVars =& $resource->getMany('TemplateVars');
              $add = true;
              $tvs = array();
              foreach ($templateVars as $tvId => $templateVar) {
                $tvName = $templateVar->get('name');
                $tvType = $templateVar->get('type');
                $tvValue = !empty($processTVs) ? $templateVar->renderOutput($id) : $templateVar->get('value');
                $tvs['tv.'.$tvName] = $tvValue;
                if($tvType == 'number') {
                  if(!empty($params[$tvName."_f"]) && $tvValue < $params[$tvName."_f"])
            	$add = false;
                  if(!empty($params[$tvName."_t"]) && $tvValue > $params[$tvName."_t"])
            	$add = false;
                } elseif($tvType == 'listbox' && !empty($params[$tvName]) && $tvValue!=$params[$tvName]) {
                    $add = false;
                }
              }
              if($add) {
                $data[] = array_merge($resource->toArray(), $tvs);
              }
            }
            
            if(count($data)) {
              foreach($data as $resource) {
                //var_dump($resource); exit;
                $output .= $modx->getChunk($tpl,$resource);
              }
            } else {
              $output = "?? ?????? ??????? ?????? ?? ???????";
            }
            return $output;
              • 15083
              • 697 Posts
              Quote from: x0149128 at Apr 30, 2012, 10:03 AM
              That's no good to the end user.

              I don't follow. Snippets take parameters.
              If getResources can take filtering paramters, simply pass these from "the end user" to the snippet call.
              You can create a form that has your filter options using TV 's
              Pass this into your getResources call?

              [[!getResources? &param='[[*myfilterfield]]' &param2='blah']]

              Would this not work?
                • 15083
                • 697 Posts
                In fact, having had a quick look @ getResources it will provide TV filtering already:
                http://rtfm.modx.com/display/ADDON/getResources

                "Can be used to filter resources by certain TV values. These are entered as [(tvname)(operator)](value). There are two delimiters you can use to combine filter conditions. "

                So you use the syntax:

                &tvFilters='product_name=Blah_blah'

                So make a snippet called "my_user_search_form"

                <?php
                
                if ( !isset($post_var_name) || $post_var_name== "" ) return "No POST value specified";
                if(isset($_POST[$post_var_name])) { return $_POST[$post_var_name]; }
                // Disclaimer, add validation here I am too lazy....
                
                ?>


                So the call to getResources now changes to:
                &tvFilters='product_name=[[!my_user_search_form? &post_var_name='name' ]]'


                So the above will pass a POST varialbe (for example from a form) to your getResources snippet call.
                This allows the end user to supply a filter option.
                This help?



                  • 38004
                  • 96 Posts
                  So with get resources I could have page called products.

                  This would just list everything.

                  Then I could have two or three drop down menus and by selecting something on one of those drop down menus, the list produced by getResources would change?

                  If so that's great.
                    • 38004
                    • 96 Posts
                    @jusmeig

                    Thanks but now i'm well and truly confused.

                    I created a snippet called "my_user_search_form"

                    <?php
                     
                    if ( !isset($post_var_name) || $post_var_name== "" ) return "No POST value specified";
                    if(isset($_POST[$post_var_name])) { return $_POST[$post_var_name]; }
                    // Disclaimer, add validation here I am too lazy....
                     
                    ?>


                    So should my call now be:

                    [[!getResources? &parents=`21` &tpl=`product_list` &includeTVs=`1` &processTVs=`1` &tvPrefix=`` &showHidden=`1` &showUnpublished=`1` &tvFilters='product_name=[[!my_user_search_form? &post_var_name='name' ]]' ]]

                      • 15083
                      • 697 Posts
                      Its difficult for me to say, as im not sure how the user is filtering (IE are they using a form??)
                      My example does not have the form, its assumes you have the form already made.

                      The form might be a field called category
                      <input type="text" name="product_category" value="" />

                      When the user submits the form the value of product_category can be added to your snippet calling using:

                      [[!my_user_search_form? &post_var_name='product_category' ]]


                      THis should make getResources filter your resources by the user entered input.
                      does this make sense?