32f3679e82b8a42fe2c532219fcfb35be6b1ed28 kent Tue Feb 24 10:53:27 2015 -0800 Adding context parameter to wraps. Minor polish here and there. diff --git src/hg/lib/tablesTables.c src/hg/lib/tablesTables.c index a57c2bc..7b1a444 100644 --- src/hg/lib/tablesTables.c +++ src/hg/lib/tablesTables.c @@ -17,32 +17,30 @@ struct fieldedTable *fieldedTableFromDbQuery(struct sqlConnection *conn, char *query) /* Return fieldedTable from a database query */ { struct sqlResult *sr = sqlGetResult(conn, query); char **fields; int fieldCount = sqlResultFieldArray(sr, &fields); struct fieldedTable *table = fieldedTableNew(query, fields, fieldCount); char **row; int i = 0; while ((row = sqlNextRow(sr)) != NULL) fieldedTableAdd(table, row, fieldCount, ++i); sqlFreeResult(&sr); return table; } -typedef void webTableOutputWrapperType(char *tag, char *val); - static void showTableFilterInstructionsEtc(struct fieldedTable *table, char *itemPlural, struct fieldedTableSegment *largerContext) /* 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; printf(" %d %s found. ", matchCount, itemPlural); cgiMakeButton("submit", "update"); printf("<BR>\n"); printf("First row of table below, above labels, can be used to filter individual fields. "); @@ -110,31 +108,31 @@ /* Sort on field */ if (!isEmpty(orderFields)) { boolean doReverse = FALSE; char *field = orderFields; if (field[0] == '-') { field += 1; doReverse = TRUE; } fieldedTableSortOnField(table, field, doReverse); } } static void showTableDataRows(struct fieldedTable *table, int pageSize, int maxLenField, - struct hash *tagOutputWrappers) + struct hash *tagOutputWrappers, void *wrapperContext) /* Render data rows into HTML */ { int count = 0; struct fieldedRow *row; for (row = table->rowList; row != NULL; row = row->next) { if (++count > pageSize) break; printf("<TR>\n"); int fieldIx = 0; for (fieldIx=0; fieldIx<table->fieldCount; ++fieldIx) { char shortVal[maxLenField+1]; char *val = emptyForNull(row->row[fieldIx]); int valLen = strlen(val); @@ -144,31 +142,31 @@ { memcpy(shortVal, val, maxLenField-3); shortVal[maxLenField-3] = 0; strcat(shortVal, "..."); val = shortVal; } } webPrintLinkCellStart(); boolean printed = FALSE; if (tagOutputWrappers != NULL && !isEmpty(val)) { char *field = table->fields[fieldIx]; webTableOutputWrapperType *printer = hashFindVal(tagOutputWrappers, field); if (printer != NULL) { - printer(field, val); + printer(table, row, field, val, wrapperContext); printed = TRUE; } } if (!printed) printf("%s", val); webPrintLinkCellEnd(); } printf("</TR>\n"); } } 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. */ @@ -183,79 +181,80 @@ printf("Displaying page "); char pageVar[64]; safef(pageVar, sizeof(pageVar), "%s_page", varPrefix); cgiMakeIntVar(pageVar, curPage+1, 3); printf(" of %d", totalPages); } } } void webFilteredFieldedTable(struct cart *cart, struct fieldedTable *table, char *returnUrl, char *varPrefix, - int maxLenField, struct hash *tagOutputWrappers, + int maxLenField, struct hash *tagOutputWrappers, void *wrapperContext, boolean withFilters, char *itemPlural, int pageSize, struct fieldedTableSegment *largerContext) /* 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); /* Set up our table within table look. */ webPrintLinkTableStart(); /* Draw optional filters cells ahead of column labels*/ if (withFilters) showTableFilterControlRow(table, cart, varPrefix, maxLenField); showTableSortingLabelRow(table, cart, varPrefix, returnUrl); -showTableDataRows(table, pageSize, maxLenField, tagOutputWrappers); +showTableDataRows(table, pageSize, maxLenField, tagOutputWrappers, wrapperContext); /* Get rid of table within table look */ webPrintLinkTableEnd(); if (largerContext != NULL) showTablePaging(table, cart, varPrefix, largerContext, pageSize); } void webSortableFieldedTable(struct cart *cart, struct fieldedTable *table, char *returnUrl, char *varPrefix, - int maxLenField, struct hash *tagOutputWrappers) + 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, + maxLenField, tagOutputWrappers, wrapperContext, FALSE, NULL, slCount(table->rowList), NULL); } void webFilteredSqlTable(struct cart *cart, struct sqlConnection *conn, char *fields, char *from, char *initialWhere, - char *returnUrl, char *varPrefix, int maxFieldWidth, struct hash *tagOutWrappers, + char *returnUrl, char *varPrefix, int maxFieldWidth, + struct hash *tagOutWrappers, void *wrapperContext, boolean withFilters, char *itemPlural, int pageSize) /* Given a query to the database in conn that is basically a select query broken into * separate clauses, construct and display an HTML table around results. This HTML table has * column names that will sort the table, and optionally (if withFilters is set) * it will also allow field-by-field wildcard queries on a set of controls it draws above * the labels. * Much of the functionality rests on the call to webFilteredFieldedTable. This function * does the work needed to bring in sections of potentially huge results sets into * the fieldedTable. */ { /* Construct select, from and where clauses in query, keeping an additional copy of where */ struct dyString *query = dyStringNew(0); struct dyString *where = dyStringNew(0); struct slName *field, *fieldList = commaSepToSlNames(fields); boolean gotWhere = FALSE; @@ -343,23 +342,23 @@ int page = 0; struct fieldedTableSegment context = { .tableSize=resultsSize}; if (resultsSize > pageSize) { page = cartUsualInt(cart, pageVar, 0) - 1; if (page < 0) page = 0; int lastPage = (resultsSize-1)/pageSize; if (page > lastPage) page = lastPage; context.tableOffset = page * pageSize; dyStringPrintf(query, " limit %d offset %d", pageSize, context.tableOffset); } struct fieldedTable *table = fieldedTableFromDbQuery(conn, query->string); -webFilteredFieldedTable(cart, table, returnUrl, varPrefix, maxFieldWidth, tagOutWrappers, - withFilters, itemPlural, pageSize, &context); +webFilteredFieldedTable(cart, table, returnUrl, varPrefix, maxFieldWidth, + tagOutWrappers, wrapperContext, withFilters, itemPlural, pageSize, &context); fieldedTableFree(&table); dyStringFree(&query); dyStringFree(&where); }