6c1f41fb7917a57861810431337b400d21714c25
galt
  Thu Jan 30 18:17:24 2020 -0800
Initial check-in for a new top-bar showing the selected facets and their values for easily seeing what has been selected, and de-selecting is easy by clicking there if you want to. Also added an explicit button for clearing the Restrictions, i.e. cdwFile_filter cart var filter.

diff --git src/hg/lib/tablesTables.c src/hg/lib/tablesTables.c
index cebcf2c..d0cacd3 100644
--- src/hg/lib/tablesTables.c
+++ src/hg/lib/tablesTables.c
@@ -382,46 +382,148 @@
 		"$('[name=%s_page]').val('%d');\n"
 		"$('#submit').click();\n"
 		, varPrefix, totalPages);
 
 	    }
 	}
      }
 }
 
 void webFilteredFieldedTable(struct cart *cart, struct fieldedTable *table, 
     char *returnUrl, char *varPrefix,
     int maxLenField, struct hash *tagOutputWrappers, void *wrapperContext,
     boolean withFilters, char *itemPlural, 
     int pageSize, struct fieldedTableSegment *largerContext, struct hash *suggestHash, 
     struct facetField **ffArray, char *visibleFacetList,
-    void (*addFunc)(int))
+    void (*addFunc)(int), char *initialWhere)
 /* Show a fielded table that can be sorted by clicking on column labels and optionally
  * that includes a row of filter controls above the labels .
  * The maxLenField is maximum character length of field before truncation with ...
  * Pass in 0 for no max */
 {
 if (strchr(returnUrl, '?') == NULL)
      errAbort("Expecting returnUrl to include ? in showFieldedTable\nIt's %s", returnUrl);
 
 if (withFilters || visibleFacetList)
     showTableFilterInstructionsEtc(table, itemPlural, largerContext, addFunc, visibleFacetList);
 
+// show top bar with quick-deselects
+if (visibleFacetList)
+    {
+    // left column
+    printf("<div>\n");
+
+    if (!isEmpty(initialWhere))
+	{
+
+	printf("Restricting files to where %s. ", initialWhere);
+
+	printf("&nbsp&nbsp;");
+	printf("<input class='btn btn-secondary' type='button' id='clearRestrictionButton' VALUE=\"Clear Restriction\">");
+	jsOnEventById("click", "clearRestrictionButton",
+	    "$(':input').not(':button, :submit, :reset, :hidden, :checkbox, :radio').val('');\n"
+	    "$('[name=cdwBrowseFiles_page]').val('1');\n"
+	    "$('[name=clearRestriction]').val('1');\n"
+	    "$('#submit').click();\n");
+
+	printf("<br>");
+        }
+
+    htmlPrintf("<dl style='display: inline-block; margin: 0'>\n");
+
+    struct slName *nameList = slNameListFromComma(visibleFacetList);
+    int f;
+    for (f = 0; f < table->fieldCount; ++f) 
+	{
+	struct facetField *field = ffArray[f];
+	if (slNameInListUseCase(nameList, field->fieldName)) // i.e. is this field a visible facet?
+	    {
+	    if (!field->allSelected)  // something selected  TODO is this really the right expression?
+		{
+		htmlPrintf("<span class='card facet-card' style='display: inline-block;'><span class='card-body'>\n");
+		htmlPrintf("<dt style='display: inline-block; margin: 0;'>\n");
+		htmlPrintf("<h6 class='card-title'>%s</h6></dt>\n", field->fieldName);
+
+		// why did this newer way not seem to work? or at least to only affect the dds and not the dts?
+
+		// save old way: style='display: inline; float: left;'
+
+		struct facetVal *val;
+
+		int valuesShown = 0;
+		int valuesNotShown = 0;  // can be used for a click to see-more when there are lots of values
+
+		// Sort values alphabetically
+		// Make a copy to not disturb the original order 
+		struct facetVal *valListCopy = facetsClone(field->valList);
+		slSort(&valListCopy, facetValCmp);
+		
+		for (val = valListCopy; val; val=val->next)
+		    {
+		    boolean specificallySelected = (val->selected && !field->allSelected);
+		    // TODO do we want to stop of valuesShown exceeds FacetFieldLimit? Maybe use that or something else or nothing?
+		    if ((val->selectCount > 0 && (field->showAllValues || valuesShown < FacetFieldLimit))
+			|| specificallySelected)
+			{
+			++valuesShown;
+			char *op = "add";
+			if (specificallySelected)
+			    op = "remove";
+			if (sameString(op, "remove"))
+			    {
+			    printf("<dd class=\"facet\" style='display: inline-block; margin: 0;'>\n");
+			    htmlPrintf("<input type=checkbox value=%s class=cdwFSCheckBox %s>&nbsp;",
+				specificallySelected ? "true" : "false", 
+				specificallySelected ? "checked" : "");
+			    htmlPrintf("<a href='../cgi-bin/cdwWebBrowse?%s=%s|url|&cdwCommand=browseFiles"
+				    "&browseFiles_facet_op=%s|url|"
+				    "&browseFiles_facet_fieldName=%s|url|"
+				    "&browseFiles_facet_fieldVal=%s|url|"
+				    "&cdwBrowseFiles_page=1' "
+				    ">",
+				cartSessionVarName(), cartSessionId(cart),
+				op, field->fieldName, val->val
+				);
+			    htmlPrintf("%s (%d)</a>", val->val, val->selectCount);
+			    printf("</dd>\n");
+			    }
+			}
+		    else if (val->selectCount > 0)
+			{
+			++valuesNotShown;
+			}
+		    }
+		slFreeList(&valListCopy);
+		
+		htmlPrintf("</span></span>\n");
+
+		}
+
+	    }
+	}
+
+    htmlPrintf("</dl>\n");
+    
+    printf("</div><br>\n");
+
+    }
+
 printf("<div class='row'>\n"); // parent container
 
 if (visibleFacetList)
     {
+
     // left column
     printf("<div class='col-xs-6 col-sm-4 col-md-4 col-lg-3 col-xl-3'>\n");
 
     // reset all facet value selections
     char *op = "resetAll";
     htmlPrintf("<a class='btn btn-secondary' href='../cgi-bin/cdwWebBrowse?%s=%s|url|&cdwCommand=browseFiles"
 	    "&browseFiles_facet_op=%s|url|"
 	    "&browseFiles_facet_fieldName=%s|url|"
 	    "&browseFiles_facet_fieldVal=%s|url|"
 	    "&cdwBrowseFiles_page=1' "
 	    ">%s</a><br><br>\n",
 	cartSessionVarName(), cartSessionId(cart),
 	op, "", "",
 	"Clear All"
 	);
@@ -562,31 +664,31 @@
     printf("</div>");
 
 printf("</div>\n"); //close parent container
 }
 
 void webSortableFieldedTable(struct cart *cart, struct fieldedTable *table, 
     char *returnUrl, char *varPrefix,
     int maxLenField, struct hash *tagOutputWrappers, void *wrapperContext)
 /* Display all of table including a sortable label row.  The tagOutputWrappers
  * is an optional way to enrich output of specific columns of the table.  It is keyed
  * by column name and has for values functions of type webTableOutputWrapperType. */
 {
 webFilteredFieldedTable(cart, table, returnUrl, varPrefix, 
     maxLenField, tagOutputWrappers, wrapperContext,
     FALSE, NULL, 
-    slCount(table->rowList), NULL, NULL, NULL, NULL, NULL);
+    slCount(table->rowList), NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
 
 void webTableBuildQuery(struct cart *cart, char *from, char *initialWhere, 
     char *varPrefix, char *fields, boolean withFilters, 
     struct dyString **retQuery, struct dyString **retWhere)
 /* Construct select, from and where clauses in query, keeping an additional copy of where 
  * Returns the SQL query and the SQL where expression as two dyStrings (need to be freed)  */
 {
 struct dyString *query = dyStringNew(0);
 struct dyString *where = dyStringNew(0);
 struct slName *field, *fieldList = commaSepToSlNames(fields);
 boolean gotWhere = FALSE;
 sqlDyStringPrintf(query, "select %-s from %-s", sqlCkIl(fields), sqlCkIl(from));
 if (!isEmpty(initialWhere))
@@ -719,22 +821,22 @@
 if (context.tableSize > pageSize)
     {
     int lastPage = (context.tableSize-1)/pageSize;
     if (page > lastPage)
         page = lastPage;
     context.tableOffset = page * pageSize;
     }
 
 if (!visibleFacetList)
     {
     sqlDyStringPrintf(query, " limit %d offset %d", pageSize, context.tableOffset);
     table = fieldedTableFromDbQuery(conn, query->string);
     }
 
 webFilteredFieldedTable(cart, table, returnUrl, varPrefix, maxFieldWidth, 
-    tagOutWrappers, wrapperContext, withFilters, itemPlural, pageSize, &context, suggestHash, ffArray, visibleFacetList, addFunc);
+    tagOutWrappers, wrapperContext, withFilters, itemPlural, pageSize, &context, suggestHash, ffArray, visibleFacetList, addFunc, initialWhere);
 fieldedTableFree(&table);
 
 dyStringFree(&query);
 dyStringFree(&where);
 }