title: With jQuery UI autocomplete results dependant upon other input values
body: <p>I am using the autocomplete feature of jQuery UI to create a passive database of associative values. I have three inputs: Lens Type, Lens Design and Lens Material. </p>
  
  <p>All three values are autocomplete, and upon form submit if there are values unique to those inputs they are stored in the database. </p>
  
  <p>What I want to do is return autocomplete values for each input based upon the known input of the previous input. So for example Lens Type a only has Lens Design input's: c,d,g. Where as if Lens type is set to b then autocomplete would return a,b,e,f.</p>
  
  <p>How would I do this with jQuery UI autocomplete? I already know how to write the database and server side logic but the autocomplete frontend has be stumped.</p>
  
  <p><strong>Edit:</strong>
  I have worked out a hardcoded method of doing this by the using following java-script:</p>
  
  <pre><code>            $('input.autocompleteme').each( function() {
              var $input = $(this);
              $input.autocomplete({ 
                  source: function( request, response ) {
  
                      var fieldName = $input.attr('id');
  
                      if ( fieldName.indexOf( "Right" ) !== -1 ) {
                          var lensSide = "Right";
                      }else{
                          var lensSide = "Left";
                      }
  
                      var LensType = $("#" + "Patient" + lensSide + "EyeLensType").attr("value");
                      var LensDesign = $("#" + "Patient" + lensSide + "EyeLensDesign").attr("value");
                      var LensMaterial = $("#" + "Patient" + lensSide + "EyeLensMaterial").attr("value");
                      var LensCoating = $("#" + "Patient" + lensSide + "EyeLensCoating").attr("value");
                      var LensTints = $("#" + "Patient" + lensSide + "EyeLensTints").attr("value");
  
                      var serverUrl = "/autocomplete.json?field=" + fieldName + "&amp;LensType=" + LensType + "&amp;LensDesign=" + LensDesign + "&amp;LensMaterial=" + LensMaterial + "&amp;LensCoating=" + LensCoating + "&amp;LensTints=" + LensTints;
                      var term = request.term;
  
                      lastXhr = $.getJSON( serverUrl, request, function( data, status, xhr ) {
                          response( data );
                      });
                  },
                  minLength: 2, 
              });
          });
  </code></pre>
  
  <p>This submits a url to a cakephp function that looks similar to:</p>
  
  <pre><code>    function admin_autocomplete(){
      Controller::loadModel('AutoField');
  
      $param      = $this-&gt;params["url"]["term"];
      $fieldName  = $this-&gt;params["url"]["field"];
      $hasParent  = false;
      $output     = array();
  
      if ($param == ''){
          $this-&gt;set("output", NULL);
          return;
      }
  
      switch ($fieldName){
  
          case "PatientRightEyeLensType":
          case "PatientLeftEyeLensType":
              $fieldName = "LensType";
          break;
  
          case "PatientRightEyeLensDesign":
          case "PatientLeftEyeLensDesign":
              $fieldName = "LensDesign";
              $hasParent = "LensType";
          break;
  
          case "PatientRightEyeLensMaterial":
          case "PatientleftEyeLensMaterial":
              $fieldName = "LensMaterial";
              $hasParent = "LensDesign";
          break;
  
          case "PatientRightEyeLensCoating":
          case "PatientLeftEyeLensCoating":
              $fieldName = "LensCoating";
              $hasParent = "LensMaterial";
          break;
  
          case "PatientRightEyeLensTints":
          case "PatientLeftEyeLensTints":
              $fieldName = "LensTints";
              $hasParent = "LensCoating";
          break;
  
          default:
              die("Field Name is not known");
          break;
      }
  
      if ($hasParent === false){ // This is the root of the tree.
  
          $query = array(
              "conditions" =&gt; array(
                  "type" =&gt; $fieldName,
                  "parent_id" =&gt; NULL,
                  "value REGEXP '^$param'"
              ),
              "fields" =&gt; array(
                  "value"
              ),
          );
  
          $results = $this-&gt;AutoField-&gt;find("all", $query);
  
      }else{
  
          $parentValue = $this-&gt;params["url"][$hasParent];
          $query = array(
              "conditions" =&gt; array(
                  "type" =&gt; $hasParent,
                  "value" =&gt; $parentValue,
              ),
              "fields" =&gt; array(
                  "id",
              )
          );
  
          $results = $this-&gt;AutoField-&gt;find("all", $query);
          $parentIds = "";
          foreach ($results as $parentId){
              $parentIds .= $parentId["AutoField"]["id"] . ",";
          }
  
          $parentIds = substr_replace($parentIds ,"",-1);
  
          $query = array(
              "conditions" =&gt; array(
                  "type" =&gt; $fieldName,
                  "parent_id IN ($parentIds)",
                  "value REGEXP '^$param'"
              ),
              "fields" =&gt; array(
                  "value"
              ),
          );
  
          $results = $this-&gt;AutoField-&gt;find("all", $query);
  
      }
  
      foreach ($results as $result){
          $output[] = $result["AutoField"]["value"];
      }
  
      $this-&gt;set("output", $output); 
  
  }
  </code></pre>
  
  <p>My Mysql database looks like the following:</p>
  
  <pre><code>--
  -- Table structure for table `auto_fields`
  --
  
  CREATE TABLE IF NOT EXISTS `auto_fields` (
    `id` int(11) unsigned NOT NULL auto_increment,
    `created` datetime default NULL,
    `modified` datetime default NULL,
    `parent_id` int(11) default NULL,
    `type` varchar(100) default NULL,
    `value` varchar(150) default NULL,
    `count` int(11) NOT NULL default '0',
    PRIMARY KEY  (`id`)
  ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
  
  --
  -- Dumping data for table `auto_fields`
  --
  
  INSERT INTO `auto_fields` (`id`, `created`, `modified`, `parent_id`, `type`, `value`, `count`) VALUES
  (1, '2012-04-12 10:51:00', '2012-04-12 10:51:02', NULL, 'LensType', 'Progressive', 0),
  (2, '2012-04-12 10:51:00', '2012-04-12 10:51:00', NULL, 'LensType', 'Bifocal', 0),
  (3, '2012-04-12 11:55:46', '2012-04-12 11:55:46', 1, 'LensDesign', 'AAA', 0),
  (4, '2012-04-12 11:55:46', '2012-04-12 11:55:46', 1, 'LensDesign', 'BBB', 0);
  </code></pre>
  
  <p>I am sure someone with better Javascript skills than myself would be able to write that side of the UI interaction so that it doesn't require hard coding of inherited variables.</p>
  
  <p>For me this works as expected with the inheritance being mapped by the switch in the php function. If I can figure out the javascript front end I may write this into a cakephp helper and component.</p>