0cc76b8a1e9ab5b02f12e7463893dc324760e838 galt Thu Jun 8 20:53:26 2017 -0700 cdwWebBrowse: Adding navigation first prev next last links. Also made it reset the page number back to 1 if anything changed such as: clear search button pressed, search changed, filters changed. FYI sort-change already took care of resetting the page number. diff --git src/hg/lib/tablesTables.c src/hg/lib/tablesTables.c index 9c860be..9fd88d0 100644 --- src/hg/lib/tablesTables.c +++ src/hg/lib/tablesTables.c @@ -27,49 +27,49 @@ while ((row = sqlNextRow(sr)) != NULL) fieldedTableAdd(table, row, fieldCount, ++i); sqlFreeResult(&sr); return table; } static void showTableFilterInstructionsEtc(struct fieldedTable *table, char *itemPlural, struct fieldedTableSegment *largerContext, void (*addFunc)(void)) /* Print instructional text, and basic summary info on who passes filter, and a submit * button just in case user needs it */ { /* Print info on matching */ int matchCount = slCount(table->rowList); if (largerContext != NULL) // Need to page? matchCount = largerContext->tableSize; + cgiMakeButton("submit", "search"); -printf("   "); + +printf("  "); +cgiMakeOnClickButton("clearButton", +"$(':input').not(':button, :submit, :reset, :hidden, :checkbox, :radio').val('');\n" +"$('[name=cdwBrowseFiles_page]').val('1');\n" +"$('#submit').click();\n" +, "clear search"); +printf("<br>"); printf("%d %s found. ", matchCount, itemPlural); if (addFunc) addFunc(); printf("<BR>\n"); printf("You can further filter search results field by field below. "); printf("Wildcard * and ? characters are allowed in text fields. "); printf(">min or <max are allowed in numerical fields.<BR>\n"); -printf("<a id='resetLink' href='#' >Reset all filters</a>\n"); -jsInlineF( -"$(function() {\n" -" $('#resetLink').click( function() { " -" $(':input').not(':button, :submit, :reset, :hidden, :checkbox, :radio').val('');\n" -" $('#submit').click();\n" -" });" -"});\n"); } static void printSuggestScript(char *id, struct slName *suggestList) /* Print out a little javascript to wrap auto-suggester around control with given ID */ { struct dyString *dy = dyStringNew(256); dyStringPrintf(dy,"$(document).ready(function() {\n"); dyStringPrintf(dy," $('#%s').autocomplete({\n", id); dyStringPrintf(dy," delay: 100,\n"); dyStringPrintf(dy," minLength: 0,\n"); dyStringPrintf(dy," source: ["); char *separator = ""; struct slName *suggest; for (suggest = suggestList; suggest != NULL; suggest = suggest->next) { @@ -80,30 +80,43 @@ dyStringPrintf(dy," });\n"); dyStringPrintf(dy,"});\n"); jsInline(dy->string); dyStringFree(&dy); } static void printWatermark(char *id, char *watermark) /* Print light text filter prompt as watermark. */ { jsInlineF( "$(function() {\n" " $('#%s').watermark(\"%s\");\n" "});\n", id, watermark); } +static void resetPageNumberOnChange(char *id) +/* On change, reset page number to 1. */ +{ +jsInlineF( +"$(function() {\n" +" $('form').delegate('#%s','change keyup paste',function(e){\n" +" $('[name=cdwBrowseFiles_page]').val('1');\n" +" });\n" +"});\n" +, id); +} + + static void showTableFilterControlRow(struct fieldedTable *table, struct cart *cart, char *varPrefix, int maxLenField, struct hash *suggestHash) /* Assuming we are in table already drow control row. * The suggestHash is keyed by field name. If something is there we'll assume * it's value is slName list of suggestion values */ { /* Include javascript and style we need */ webIncludeResourceFile("jquery-ui.css"); jsIncludeFile("jquery.js", NULL); jsIncludeFile("jquery.plugins.js", NULL); jsIncludeFile("jquery-ui.js", NULL); jsIncludeFile("jquery.watermark.js", NULL); int i; printf("<TR>"); @@ -130,30 +143,34 @@ #ifdef ACTUALLY_WORKS /* This way does work last I checked and is just a line of code. * Getting an id= property on the input tag though isn't possible this way. */ cartMakeTextVar(cart, varName, "", size + 1); #endif /* Print input control getting previous value from cart. Set an id= * so auto-suggest can find this control. */ char *oldVal = cartUsualString(cart, varName, ""); printf("<INPUT TYPE=TEXT NAME=\"%s\" id=\"%s\" SIZE=%d VALUE=\"%s\">\n", varName, varName, size+1, oldVal); /* Write out javascript to initialize autosuggest on control */ printWatermark(varName, " filter "); + + /* Write out javascript to reset page number to 1 if filter changes */ + resetPageNumberOnChange(varName); + if (suggestHash != NULL) { struct slName *suggestList = hashFindVal(suggestHash, field); if (suggestList != NULL) { printSuggestScript(varName, suggestList); } } webPrintLinkCellEnd(); } printf("</TR>"); } @@ -273,57 +290,102 @@ } } static void showTablePaging(struct fieldedTable *table, struct cart *cart, char *varPrefix, struct fieldedTableSegment *largerContext, int pageSize) /* If larger context exists and is bigger than current display, then draw paging controls. */ { /* Handle paging if any */ if (largerContext != NULL) // Need to page? { if (pageSize < largerContext->tableSize) { int curPage = largerContext->tableOffset/pageSize; int totalPages = (largerContext->tableSize + pageSize - 1)/pageSize; + + char id[256]; + if ((curPage + 1) > 1) + { + // first page + safef(id, sizeof id, "%s_first", varPrefix); + printf("<a href='#' id='%s' style='font-size: 150%%;'>⏮</a>", id); + jsOnEventByIdF("click", id, + "$('[name=%s_page]').val('1');\n" + "$('#submit').click();\n" + , varPrefix); + printf(" "); + + // prev page + safef(id, sizeof id, "%s_prev", varPrefix); + printf("<a href='#' id='%s' style='font-size: 150%%;'>⏪</a>", id); + jsOnEventByIdF("click", id, + "$('[name=%s_page]').val('%d');\n" + "$('#submit').click();\n" + , varPrefix, (curPage+1)-1); + printf(" "); + } + + printf("Displaying page "); char pageVar[64]; safef(pageVar, sizeof(pageVar), "%s_page", varPrefix); cgiMakeIntVar(pageVar, curPage+1, 3); printf(" of %d", totalPages); + + if ((curPage + 1) < totalPages) + { + // next page + printf(" "); + safef(id, sizeof id, "%s_next", varPrefix); + printf("<a href='#' id='%s' style='font-size: 150%%;' >⏩</a>", id); + jsOnEventByIdF("click", id, + "$('[name=%s_page]').val('%d');\n" + "$('#submit').click();\n" + , varPrefix, (curPage+1)+1); + + // last page + printf(" "); + safef(id, sizeof id, "%s_last", varPrefix); + printf("<a href='#' id='%s' style='font-size: 150%%;' >⏭</a>", id); + jsOnEventByIdF("click", id, + "$('[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, void (*addFunc)(void) ) /* 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) showTableFilterInstructionsEtc(table, itemPlural, largerContext, addFunc); /* Set up our table within table look. */ webPrintLinkTableStart(); /* Draw optional filters cells ahead of column labels*/ if (withFilters) showTableFilterControlRow(table, cart, varPrefix, maxLenField, suggestHash); showTableSortingLabelRow(table, cart, varPrefix, returnUrl); showTableDataRows(table, pageSize, maxLenField, tagOutputWrappers, wrapperContext); /* Get rid of table within table look */ webPrintLinkTableEnd();