108ce8a6eca325ddc6e949e271e262e91b596fd9
tdreszer
  Mon Nov 22 12:02:43 2010 -0800
Made freeText search instead of drop downs for track search advanced when cv.ra reports 'searchable freeText'.  This is useful for labVersion among others.
diff --git src/hg/hgTracks/searchTracks.c src/hg/hgTracks/searchTracks.c
index 9ba149d..5539603 100644
--- src/hg/hgTracks/searchTracks.c
+++ src/hg/hgTracks/searchTracks.c
@@ -305,35 +305,63 @@
     #define PRINT_BUTTON(name,value,msg,js) printf("<input type='submit' name='%s' value='%s' style='font-size:.7em;' title='%s' onclick='%s'>", (name), (value), (msg), (js));
         hPrintf("<tr><td>\n");
         if(numMetadataSelects > 2 || i >= 2)
             {
             safef(buf, sizeof(buf), "return delSearchSelect(this, %d);", i + 1);
             PRINT_BUTTON(TRACK_SEARCH, "-", "delete this row", buf);
             }
         else
             hPrintf("&nbsp;");
         hPrintf("</td><td>\n");
         safef(buf, sizeof(buf), "return addSearchSelect(this, %d);", i + 1);
         PRINT_BUTTON(TRACK_SEARCH, "+", "add another row after this row", buf);
 
         hPrintf("</td><td>and&nbsp;</td><td colspan=3 nowrap>\n");
         safef(buf, sizeof(buf), "%s%i", METADATA_NAME_PREFIX, i + 1);
+    #ifdef CV_SEARCH_SUPPORTS_FREETEXT
+        cgiDropDownWithTextValsAndExtra(buf, mdbVarLabels, mdbVars,count,mdbVar[i],"class='mdbVar' style='font-size:.9em;' onchange='findTracksMdbVarChanged2(this);'");
+        // TODO: move to lib since hgTracks and hgApi share
+        enum mdbCvSearchable searchBy = mdbCvSearchMethod(mdbVar[i]);
+        if (searchBy == cvsSearchByMultiSelect)
+            {
+            // TO BE IMPLEMENTED
+            }
+        else if (searchBy == cvsSearchBySingleSelect)
+            {
+            safef(buf, sizeof(buf), "%s%i", METADATA_VALUE_PREFIX, i + 1);
+            hPrintf("</td><td align='right' id='isLike%d' style='width:10px;'>is</td><td nowrap id='%s' style='max-width:600px;'>\n",i + 1,buf);
+            len = getTermArray(conn, &labels, &terms, mdbVar[i]);
+            cgiMakeDropListFull(buf, labels, terms, len, mdbVal[i], "class='mdbVal single' style='min-width:200px; font-size:.9em;' onchange='findTracksSearchButtonsEnable(true);'");
+            }
+        else if (searchBy == cvsSearchByFreeText)
+            {
+            safef(buf, sizeof(buf), "%s%i", METADATA_VALUE_PREFIX, i + 1);
+            hPrintf("</td><td align='right' id='isLike%d' style='width:10px;'>contains</td><td nowrap id='%s' style='max-width:600px;'>\n",i + 1,buf);
+            hPrintf("<input type='text' name='%s' value='%s' class='mdbVal freeText' onkeyup='findTracksSearchButtonsEnable(true);' style='max-width:310px; width:310px; font-size:.9em;'>",
+                    buf,(mdbVal[i] ? mdbVal[i]: ""));
+            }
+        else if (searchBy == cvsSearchByDateRange || searchBy == cvsSearchByIntegerRange)
+            {
+            // TO BE IMPLEMENTED
+            }
+    #else//ifndef CV_SEARCH_SUPPORTS_FREETEXT
         cgiDropDownWithTextValsAndExtra(buf, mdbVarLabels, mdbVars,count,mdbVar[i],"class='mdbVar' style='font-size:.9em;' onchange='findTracksMdbVarChanged(this);'");
-        hPrintf("</td><td nowrap style='max-width:600px;'>is\n");
+        hPrintf("</td><td align='right' style='width:10px;'>is</td><td nowrap style='max-width:600px;'>is\n");
         len = getTermArray(conn, &labels, &terms, mdbVar[i]);
         safef(buf, sizeof(buf), "%s%i", METADATA_VALUE_PREFIX, i + 1);
         cgiMakeDropListFull(buf, labels, terms, len, mdbVal[i], "class='mdbVal' style='min-width:200px; font-size:.9em;' onchange='findTracksSearchButtonsEnable(true);'");
+    #endif///ndef CV_SEARCH_SUPPORTS_FREETEXT
         hPrintf("<span id='helpLink%d'>help</span></td>\n", i + 1);
         hPrintf("</tr>\n");
         }
 
     hPrintf("<tr><td colspan='%d' align='right' style='height:10px; max-height:10px;'>&nbsp;</td></tr>", cols);
     //hPrintf("<tr><td colspan='%d' align='right' class='lineOnTop' style='height:20px; max-height:20px;'>&nbsp;</td></tr>", cols);
 
 return numMetadataSelects;
 }
 
 static struct slRef *simpleSearchForTracksstruct(struct trix *trix,char **descWords,int descWordCount)
 // Performs the simple search and returns the found tracks.
 {
 struct slRef *tracks = NULL;
 
@@ -355,35 +383,82 @@
 {
 int tracksFound = 0;
 struct slRef *tracks = NULL;
 
     if(!isEmpty(nameSearch) || descSearch != NULL || groupSearch != NULL || numMetadataNonEmpty)
         {
         // First do the metaDb searches, which can be done quickly for all tracks with db queries.
         struct hash *matchingTracks = newHash(0);
         struct slName *el, *metaTracks = NULL;
         int i;
 
         for(i = 0; i < numMetadataSelects; i++)
             {
             if(!isEmpty(mdbVal[i]))
                 {
+            #ifdef CV_SEARCH_SUPPORTS_FREETEXT
+                enum mdbCvSearchable searchBy = mdbCvSearchMethod(mdbVar[i]);
+                struct slName *tmp = NULL;
+                // If select is by free text then like
+                if (searchBy == cvsSearchByMultiSelect)
+                    {
+                    // TO BE IMPLEMENTED
+                    // The mdbVal[1] will hve to be filled cartOptionalSlNameList(cart,???)
+                    struct slName *choices = (struct slName *)mdbVal[i];
+                    if (slCount(choices) == 1)
+                        {
+                        tmp = mdbObjSearch(conn, mdbVar[i], choices->name, "is", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
+                        }
+                    else if(choices != NULL)
+                        {
+                        // Then slNames will need to be assembled into a string in the form of 'a','b','c'
+                        struct dyString *dyList = dyStringNew(256);
+                        dyStringPrintf(dyList,"'%s'",choices->name);
+                        struct slName *choice = choices->next;
+                        for(;choice!=NULL;choice=choice->next)
+                            dyStringPrintf(dyList,",'%s'",choice->name);
+                        tmp = mdbObjSearch(conn, mdbVar[i], dyStringContents(dyList), "in", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
+                        dyStringFree(&dyList);
+                        }
+                    }
+                else if (searchBy == cvsSearchBySingleSelect)
+                    {
+                    tmp = mdbObjSearch(conn, mdbVar[i], mdbVal[i], "is", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
+                    }
+                else if (searchBy == cvsSearchByFreeText)
+                    {
+                    tmp = mdbObjSearch(conn, mdbVar[i], mdbVal[i], "like", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
+                    }
+                else if (searchBy == cvsSearchByDateRange || searchBy == cvsSearchByIntegerRange)
+                    {
+                    // TO BE IMPLEMENTED
+                    // Requires new mdbObjSearch API and more than one mdbVal[i]
+                    }
+                if (tmp != NULL)
+                    {
+                    if(metaTracks == NULL)
+                        metaTracks = tmp;
+                    else
+                        metaTracks = slNameIntersection(metaTracks, tmp);
+                    }
+            #else///ifndif CV_SEARCH_SUPPORTS_FREETEXT
                 struct slName *tmp = mdbObjSearch(conn, mdbVar[i], mdbVal[i], "is", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
                 if(metaTracks == NULL)
                     metaTracks = tmp;
                 else
                     metaTracks = slNameIntersection(metaTracks, tmp);
+            #endif///ndef CV_SEARCH_SUPPORTS_FREETEXT
                 }
             }
         for (el = metaTracks; el != NULL; el = el->next)
             hashAddInt(matchingTracks, el->name, 1);
 
         struct group *group;
         for (group = groupList; group != NULL; group = group->next)
             {
             if(groupSearch == NULL || sameString(group->name, groupSearch))
                 {
                 if (group->trackList != NULL)
                     {
                     struct trackRef *tr;
                     for (tr = group->trackList; tr != NULL; tr = tr->next)
                         {
@@ -768,31 +843,31 @@
 hPrintf("<input type='text' name='%s' id='simpleSearch' class='submitOnEnter' value='%s' style='max-width:1000px; width:100%%;' onkeyup='findTracksSearchButtonsEnable(true);'>\n",
         TRACK_SEARCH_SIMPLE,descSearch == NULL ? "" : descSearch);
 if (simpleSearch && descSearch)
     searchTermsExist = TRUE;
 
 hPrintf("</td></tr><td style='max-height:4px;'></td></tr></table>");
 //hPrintf("</td></tr></table>");
 hPrintf("<input type='submit' name='%s' id='searchSubmit' value='search' style='font-size:.8em;'>\n", TRACK_SEARCH);
 hPrintf("<input type='button' name='clear' value='clear' class='clear' style='font-size:.8em;' onclick='findTracksClear();'>\n");
 hPrintf("<input type='submit' name='submit' value='cancel' class='cancel' style='font-size:.8em;'>\n");
 hPrintf("</div>\n");
 
 // Advanced tab
 hPrintf("<div id='advancedTab' style='width:inherit;'>\n"
         "<table cellSpacing=0 style='width:inherit; font-size:.9em;'>\n");
-cols = 7;
+cols = 8;
 
 // Track Name contains
 hPrintf("<tr><td colspan=3></td>");
 hPrintf("<td nowrap><b style='max-width:100px;'>Track&nbsp;Name:</b></td>");
 hPrintf("<td align='right'>contains</td>\n");
 hPrintf("<td colspan='%d'>", cols - 4);
 hPrintf("<input type='text' name='%s' id='nameSearch' class='submitOnEnter' value='%s' onkeyup='findTracksSearchButtonsEnable(true);' style='min-width:326px; font-size:.9em;'>",
         TRACK_SEARCH_ON_NAME, nameSearch == NULL ? "" : nameSearch);
 hPrintf("</td></tr>\n");
 
 // Description contains
 hPrintf("<tr><td colspan=2></td><td align='right'>and&nbsp;</td>");
 hPrintf("<td><b style='max-width:100px;'>Description:</b></td>");
 hPrintf("<td align='right'>contains</td>\n");
 hPrintf("<td colspan='%d'>", cols - 4);