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("  "); + 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> ", + 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); }