ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

Thousands of categories - best way to go about it?

March 16, 2010 3:19am

Subscribe [2]
  • #1 / Mar 16, 2010 3:19am

    RealityDesign

    70 posts

    I need to input 3-4 thousand categories, basically most major cities in every country.  The categories are broken in to sub categories such as:

    USA -> New York -> New York City
    or
    USA -> California -> Los Angeles
    etc.

    Now, obviously after a few hundred categories the CP is going to get unwieldy.  After a thousand or so it’s also probably going to begin loading very slowly.  So, how can I change the way the CP deals with the categories?  Ideally I’d like to use a select box, and have it only show parent categories.  Then, based on your selection, only show the children of that parent category.  Then when you’ve selected that child, only show the child of that child, etc.

    Is there an extension that can do this already?  If not, any ideas where to start?  Or is there another way to deal with thousands of categories?

  • #2 / Mar 16, 2010 6:15pm

    RealityDesign

    70 posts

    Well based on the lack of response, I wrote my own AJAX / jQuery to handle showing only the current parent and all of that.  Seems to be working well.

  • #3 / Mar 16, 2010 6:21pm

    Ingmar

    29245 posts

    That sounds interesting, would you care to share your code? I have a little private side project that would ultimately require 2500+ categories, so I’m interested 😉

  • #4 / Mar 16, 2010 7:32pm

    RealityDesign

    70 posts

    It’s a bit messy, but I basically just commented out the categories in the CP, then used AJAX in the SAEF to handle it instead.

    My kind of ghetto javascript for the Ajax (each “level” is a sub-category level…I know there is a more efficient way to do this, I just had to make it quick):

    var xmlhttp;
    
    function getlevel1(str)
    {
    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="http://www.vacationmouse.com/vm.php/ajax/level1/";
    url=url+str;
    url=url+"&sid;="+Math.random();
    xmlhttp.onreadystatechange=stateChanged1;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }
    
    function stateChanged1()
    {
    if (xmlhttp.readyState==4)
    {
    document.getElementById("level1")[removed]=xmlhttp.responseText;
    }
    }
    
    function getlevel2(str)
    {
    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="http://www.vacationmouse.com/vm.php/ajax/level2/";
    url=url+str;
    url=url+"&sid;="+Math.random();
    xmlhttp.onreadystatechange=stateChanged2;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }
    
    function stateChanged2()
    {
    if (xmlhttp.readyState==4)
    {
    document.getElementById("level2")[removed]=xmlhttp.responseText;
    }
    }
    
    function getlevel3(str)
    {
    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="http://www.vacationmouse.com/vm.php/ajax/level3/";
    url=url+str;
    url=url+"&sid;="+Math.random();
    xmlhttp.onreadystatechange=stateChanged3;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }
    
    function stateChanged3()
    {
    if (xmlhttp.readyState==4)
    {
    document.getElementById("level3")[removed]=xmlhttp.responseText;
    }
    }
    
    function getlevel4(str)
    {
    xmlhttp=GetXmlHttpObject();
    if (xmlhttp==null)
      {
      alert ("Browser does not support HTTP Request");
      return;
      }
    var url="http://www.vacationmouse.com/vm.php/ajax/level4/";
    url=url+str;
    url=url+"&sid;="+Math.random();
    xmlhttp.onreadystatechange=stateChanged4;
    xmlhttp.open("GET",url,true);
    xmlhttp.send(null);
    }
    
    function stateChanged4()
    {
    if (xmlhttp.readyState==4)
    {
    document.getElementById("level4")[removed]=xmlhttp.responseText;
    }
    }
    
    function GetXmlHttpObject()
    {
    if (window.XMLHttpRequest)
      {
      // code for IE7+, Firefox, Chrome, Opera, Safari
      return new XMLHttpRequest();
      }
    if (window.ActiveXObject)
      {
      // code for IE6, IE5
      return new ActiveXObject("Microsoft.XMLHTTP");
      }
    return null;
    }

    An example of the template (3rd level sub-category in this case) called by AJAX:

    {exp:query sql="SELECT * FROM exp_categories WHERE parent_id = '{segment_3}' ORDER BY cat_name ASC"}
    {if count == 1}
    <select name="level3">
    <option value="">--</option>
    {/if}
    <option value="{cat_id}">{cat_name}</option>
    {if count == total_results}
    </select>
    {/if}
    {/exp:query}

    And the actual code in the template that is displayed to the user:

    <select name="level0">
    <option value="">--</option>
    {exp:query sql="SELECT * FROM exp_category_groups"}
    <option value="{group_id}">{group_name}</option>
    {/exp:query}
    </select>
    
    <div id="level1">
    </div>
    
    <div id="level2">
    </div>
    
    <div id="level3">
    </div>
    
    <div id="level4">
    </div>
.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases