8ddabffbe58063f2094af1d0fdb45721afcec97c
angie
  Wed Mar 4 13:21:47 2015 -0800
Moved the smarts about changing clade/org/db out of cartJson.c & hgAi.c and
into CladeOrgDbMixin.js & hgAiModel.js.  Now the CGI sends the full tree of
clades, genomes and dbs, and the model instantaneously updates when the user
changes clade, org or db, and tells the CGI exactly what info it needs instead
of relying on the CGI to send a special mix.
refs #14579

diff --git src/hg/hgAi/hgAi.c src/hg/hgAi/hgAi.c
index 5b0bfd1..c3a4533 100644
--- src/hg/hgAi/hgAi.c
+++ src/hg/hgAi/hgAi.c
@@ -23,62 +23,30 @@
 #include "textOut.h"
 #include "trackHub.h"
 #include "web.h"
 #include "annoFormatTab.h"
 #include "annoGratorQuery.h"
 
 /* Global Variables */
 struct cart *cart = NULL;             /* CGI and other variables */
 
 #define QUERY_SPEC "hgai_querySpec"
 #define DO_QUERY "hgai_doQuery"
 
 //#*** duplicated from hgVai... put in some anno*.h?
 #define NO_MAXROWS 0
 
-static void writeDbMetadata(struct cartJson *cj, struct hash *paramHash)
-/* Send all the info that we'll need for working with a specific assembly db. */
-{
-struct hash *gtdbParamHash = hashNew(0);
-hashAdd(gtdbParamHash, "fields", newJsonString("track,table,shortLabel,parent,subtracks"));
-cartJsonGetGroupedTrackDb(cj, gtdbParamHash);
-//#*** TODO: move jsonStringEscape inside jsonWriteString
-char *encoded = jsonStringEscape(cartOptionalString(cart, QUERY_SPEC));
-jsonWriteString(cj->jw, QUERY_SPEC, encoded);
-}
-
-static void changeDb(struct cartJson *cj, struct hash *paramHash)
-/* The user has changed db; send groups, tracks, tables etc. for the new db. */
-{
-cartJsonChangeDb(cj, paramHash);
-writeDbMetadata(cj, paramHash);
-}
-
-static void changeOrg(struct cartJson *cj, struct hash *paramHash)
-/* The user has changed org/genome; send groups, tracks, tables etc. for the new default db. */
-{
-cartJsonChangeOrg(cj, paramHash);
-writeDbMetadata(cj, paramHash);
-}
-
-static void changeClade(struct cartJson *cj, struct hash *paramHash)
-/* The user has changed clade; send groups, tracks, tables etc. for the new default db. */
-{
-cartJsonChangeClade(cj, paramHash);
-writeDbMetadata(cj, paramHash);
-}
-
 static void makeTrackLabel(struct trackDb *tdb, char *table, char *label, size_t labelSize)
 /* Write tdb->shortLabel into label if table is the same as tdb->track; otherwise, write shortLabel
  * followed by table name in parens. */
 {
 if (sameString(table, tdb->track))
     safecpy(label, labelSize, tdb->shortLabel);
 else
     safef(label, labelSize, "%s (%s)", tdb->shortLabel, table);
 }
 
 static void getFields(struct cartJson *cj, struct hash *paramHash)
 /* Print out the fields of the tables in comma-sep tables param. */
 {
 char *tableStr = cartJsonRequiredParam(paramHash, "tables", cj->jw, "getFields");
 if (! tableStr)
@@ -111,34 +79,35 @@
                 jsonWriteString(cj->jw, NULL, col->name);
             jsonWriteListEnd(cj->jw);
             jsonWriteObjectEnd(cj->jw);
             }
         }
     else
         warn("No tdb for %s", table->name);
     }
 jsonWriteObjectEnd(cj->jw);
 slFreeList(&tables);
 }
 
 void doCartJson()
 /* Perform UI commands to update the cart and/or retrieve cart vars & metadata. */
 {
+// When cart is brand new, we need to set db in the cart because several cartJson functions
+// require it to be there.
+if (! cartOptionalString(cart, "db"))
+    cartSetString(cart, "db", hDefaultDb());
 struct cartJson *cj = cartJsonNew(cart);
-cartJsonRegisterHandler(cj, "changeDb", changeDb);
-cartJsonRegisterHandler(cj, "changeOrg", changeOrg);
-cartJsonRegisterHandler(cj, "changeClade", changeClade);
 cartJsonRegisterHandler(cj, "getFields", getFields);
 cartJsonExecute(cj);
 }
 
 static struct pipeline *configTextOut(struct jsonElement *queryObj, int *pSavedStdout)
 // Set up a textOut pipeline according to output file options in queryObj.
 {
 char *fileName = "";
 char *compressType = textOutCompressNone;
 struct jsonElement *outFileOptions = jsonFindNamedField(queryObj, QUERY_SPEC, "outFileOptions");
 if (outFileOptions)
     {
     boolean doFile = jsonOptionalBooleanField(outFileOptions, "doFile", FALSE);
     if (doFile)
         {