src/hg/lib/hui.c 1.182
1.182 2009/04/01 21:51:32 tdreszer
Enable javascript validation of selected integer and double input controls.
Index: src/hg/lib/hui.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/lib/hui.c,v
retrieving revision 1.181
retrieving revision 1.182
diff -b -B -U 4 -r1.181 -r1.182
--- src/hg/lib/hui.c 19 Mar 2009 21:48:50 -0000 1.181
+++ src/hg/lib/hui.c 1 Apr 2009 21:51:32 -0000 1.182
@@ -2358,13 +2358,15 @@
if(count == 1)
printf("<B>Filter by %s</B> (select multiple items)<BR>\n",filterBy->title);
else
printf("<B>%s</B><BR>\n",filterBy->title);
- int openSize = min(20,slCount(filterBy->slValues)+1);
- int size = (filterBy->slChoices == NULL || slCount(filterBy->slChoices) == 1 ? 1 : openSize); //slCount(filterBy->slValues)+1); // slChoice ??
-//#define MULTI_SELECT_WITH_JS "<SELECT name='%s.filterBy.%s' multiple=true size=%d onfucus='this.size=%d;' onblur='var ix; for(ix=this.selectedIndex+1;ix<this.options.length;ix++) {if(this.options[ix].selected) break;} if(ix == this.options.length) this.size=1; return true;'><BR>\n"
-#define MULTI_SELECT_WITH_JS "<SELECT name='%s.filterBy.%s' multiple=true size=%d onclick='this.size=%d;'class='normalText filterBy'><BR>\n"
- printf(MULTI_SELECT_WITH_JS,tdb->tableName,filterBy->column,size,openSize);
+ int fullSize = slCount(filterBy->slValues)+1;
+ int openSize = min(20,fullSize);
+ int closedSize = (filterBy->slChoices == NULL || slCount(filterBy->slChoices) == 1 ? 1 : openSize); //slCount(filterBy->slValues)+1); // slChoice ??
+//#define MULTI_SELECT_WITH_JS "<div class='multiSelectContainer'><SELECT name='%s.filterBy.%s' multiple=true size=%d openSize=%d style='display: none' onclick='multiSelectClick(this,%d);' onblur='multiSelectBlur(this,%d);' class='normalText filterBy'></div><BR>\n"
+// printf(MULTI_SELECT_WITH_JS,tdb->tableName,filterBy->column,closedSize,openSize,openSize,openSize);
+#define MULTI_SELECT_WITH_JS "<SELECT name='%s.filterBy.%s' multiple=true size=%d onclick='multiSelectClick(this,%d);' onblur='multiSelectBlur(this);' class='filterBy'><BR>\n"
+ printf(MULTI_SELECT_WITH_JS,tdb->tableName,filterBy->column,closedSize,openSize);
printf("<OPTION%s>All</OPTION>\n",(filterBy->slChoices == NULL || slNameInList(filterBy->slChoices,"All")?" SELECTED":"") );
struct slName *slValue;
if(filterBy->useIndex)
{
@@ -2384,23 +2386,16 @@
printf("<OPTION%s>%s</OPTION>\n",(filterBy->slChoices != NULL && slNameInList(filterBy->slChoices,slValue->name)?" SELECTED":""),slValue->name);
}
}
// The following is needed to make msie scroll to selected option.
- //printf("<script type='text/javascript'>$(document).ready(function () { $( 'select[name^=%s.filterBy.]' ).children('option[selected]').each( function(i) { this.selected=true; }); });</script>\n",tdb->tableName);
printf("<script type='text/javascript'>onload=function(){ $( 'select[name^=%s.filterBy.]' ).children('option[selected]').each( function(i) { this.selected=true; }); }</script>\n",tdb->tableName);
puts("</TR></TABLE>");
return;
}
-#define COLOR_BG_DEFAULT "#FFFEE8"
-#define COLOR_BG_ALTDEFAULT "#FFF9D2"
-#define COLOR_BG_GHOST "#EEEEEE"
-#define COLOR_BG_PALE "#F8F8F8"
#define COLOR_BG_DEFAULT_IX 0
#define COLOR_BG_ALTDEFAULT_IX 1
-#define COLOR_DARKGREEN "#008800"
-#define COLOR_DARKBLUE "#000088"
#define DIVIDING_LINE "<TR valign=\"CENTER\" line-height=\"1\" BGCOLOR=\"%s\"><TH colspan=\"5\" align=\"CENTER\"><hr noshade color=\"%s\" width=\"100%%\"></TD></TR>\n"
#define DIVIDER_PRINT(color) printf(DIVIDING_LINE,COLOR_BG_DEFAULT,(color))
static char *checkBoxIdMakeForTrack(struct trackDb *tdb,char *tagX,char *tagY,char *tagZ,membership_t *membership)
@@ -3008,64 +3003,68 @@
(void) wigFetchSmoothingWindowWithCart(cart,tdb,name, &smoothingWindow);
(void) wigFetchYLineMarkWithCart(cart,tdb,name, &yLineMarkOnOff);
wigFetchYLineMarkValueWithCart(cart,tdb,name, &yLineMark);
-puts("<TABLE BORDER=0><TR><TD ALIGN=LEFT>");
-printf("<b>Type of graph: </b>");
+printf("<TABLE BORDER=0>");
+
+printf("<TR valign=center><th align=right>Type of graph:</th><td align=left>");
snprintf( option, sizeof(option), "%s.%s", name, LINEBAR );
wiggleGraphDropDown(option, lineBar);
-puts("</TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
-
-puts("<b>y = 0.0 line: </b>");
-snprintf(option, sizeof(option), "%s.%s", name, HORIZGRID );
-wiggleGridDropDown(option, horizontalGrid);
-puts(" </TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
+if(boxed)
+ {
+ printf("</td><td align=right colspan=2>");
+ printf("<A HREF=\"%s\" TARGET=_blank>Graph configuration help</A>",WIGGLE_HELP_PAGE);
+ }
+puts("</td></TR>");
-printf("<b>Track height: </b>");
+printf("<TR valign=center><th align=right>Track height:</th><td align=left colspan=3>");
snprintf(option, sizeof(option), "%s.%s", name, HEIGHTPER );
-cgiMakeIntVar(option, defaultHeight, 5);
-printf(" pixels (range: %d to %d)",
+cgiMakeIntVarWithLimits(option, defaultHeight, "Track height",0, minHeightPixels, maxHeightPixels);
+printf("pixels (range: %d to %d)",
minHeightPixels, maxHeightPixels);
-puts("</TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
+puts("</TD></TR>");
-printf("<b>Vertical viewing range</b>: \n<b>min: </b>");
+printf("<TR valign=center><th align=right>Vertical viewing range:</th><td align=left> min: ");
snprintf(option, sizeof(option), "%s.%s", name, MIN_Y );
-cgiMakeDoubleVar(option, minY, 6);
-printf(" <b>max: </b>");
+cgiMakeDoubleVarWithLimits(option, minY, "Range min", 0, tDbMinY, tDbMaxY);
+printf("</td><td align=leftv colspan=2>max: ");
snprintf(option, sizeof(option), "%s.%s", name, MAX_Y );
-cgiMakeDoubleVar(option, maxY, 6);
+cgiMakeDoubleVarWithLimits(option, maxY, "Range max", 0, tDbMinY, tDbMaxY);
printf(" (range: %g to %g)",
tDbMinY, tDbMaxY);
-puts("</TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
+puts("</TD></TR>");
-printf("<b>Data view scaling: </b>");
+printf("<TR valign=center><th align=right>Data view scaling:</th><td align=left colspan=3>");
snprintf(option, sizeof(option), "%s.%s", name, AUTOSCALE );
wiggleScaleDropDown(option, autoScale);
-puts("</TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
+puts("</TD></TR>");
-printf("<b>Windowing function: </b>");
+printf("<TR valign=center><th align=right>Windowing function:</th><td align=left>");
snprintf(option, sizeof(option), "%s.%s", name, WINDOWINGFUNCTION );
wiggleWindowingDropDown(option, windowingFunction);
-puts("</TD></TR><TR><TD ALIGN=LEFT COLSPAN=2>");
-printf("<b>Smoothing window: </b>");
+printf("<th align=right>Smoothing window:</th><td align=left>");
snprintf(option, sizeof(option), "%s.%s", name, SMOOTHINGWINDOW );
wiggleSmoothingDropDown(option, smoothingWindow);
-puts(" pixels</TD></TR><TR><TD ALIGN=LEFT COLSPAN=1>");
+puts(" pixels</TD></TR>");
-puts("<b>Draw indicator line at y = </b> ");
+printf("<TR valign=center><td align=right><b>Draw y indicator lines:</b><td align=left colspan=2>");
+printf("at y = 0.0:");
+snprintf(option, sizeof(option), "%s.%s", name, HORIZGRID );
+wiggleGridDropDown(option, horizontalGrid);
+printf(" at y =");
snprintf(option, sizeof(option), "%s.%s", name, YLINEMARK );
-cgiMakeDoubleVar(option, yLineMark, 6);
-printf(" ");
+cgiMakeDoubleVarWithLimits(option, yLineMark, "Indicator at Y", 0, tDbMinY, tDbMaxY);
+printf("</td><td align=left>");
snprintf(option, sizeof(option), "%s.%s", name, YLINEONOFF );
wiggleYLineMarkDropDown(option, yLineMarkOnOff);
if(boxed)
- printf("</TD><TD align=\"RIGHT\">");
-else
puts("</TD></TR></TABLE>");
-printf("<A HREF=\"%s\" TARGET=_blank>Graph configuration help</A>",WIGGLE_HELP_PAGE);
-if(boxed)
+else
+ {
puts("</TD></TR></TABLE>");
+ printf("<A HREF=\"%s\" TARGET=_blank>Graph configuration help</A>",WIGGLE_HELP_PAGE);
+ }
cfgEndBox(boxed);
}
@@ -3120,12 +3119,29 @@
printf("</SELECT></P>\n");
}
}
+static boolean getScoreLimits(struct trackDb *tdb, char *scoreName,char *defaults,char**min,char**max)
+{ // returns TRUE if limits exist and sets the string pointer (because they may be float or int)
+char scoreLimitName[128];
+safef(scoreLimitName, sizeof(scoreLimitName), "%s%s", scoreName, _LIMITS);
+char *setting = trackDbSettingClosestToHomeOrDefault(tdb, scoreLimitName,defaults);
+if(setting)
+ {
+ *min = strSwapChar(cloneString(setting),':',0);
+ *max = cloneString(*min + strlen(*min) + 1);
+ return TRUE;
+ }
+ *min = NULL;
+ *max = NULL;
+ return FALSE;
+}
+
void scoreCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title, int maxScore, boolean boxed)
/* Put up UI for filtering bed track based on a score */
{
char option[256];
+int val=0;
boolean compositeLevel = isNameAtCompositeLevel(tdb,name);
boolean scoreFilterOk = (trackDbSettingClosestToHome(tdb, NO_SCORE_FILTER) == NULL);
boolean gotScoreMin = (trackDbSettingClosestToHome(tdb, SCORE_MIN) != NULL);
@@ -3146,13 +3162,25 @@
min = cartUsualStringClosestToHome(cart, tdb, compositeLevel, SCORE_FILTER _MIN, min);
max = cartUsualStringClosestToHome(cart, tdb, compositeLevel, SCORE_FILTER _MAX, max);
puts("<B>Filter score range: min:</B>");
safef(option, sizeof(option), "%s.%s", name, SCORE_FILTER _MIN);
- cgiMakeTextVar(option,(atoi(min)<0?"0":min), 4);
+ val = atoi(min);
+ if( val < 0)
+ val = 0;
+ char *rangeMin=NULL;
+ char *rangeMax=NULL;
+ getScoreLimits(tdb,SCORE_FILTER,"0:1000",&rangeMin,&rangeMax);
+ cgiMakeIntVarInRange(option, val, "Minimum score",0,rangeMin,rangeMax);
+
puts("<B>max:</B>");
safef(option, sizeof(option), "%s.%s", name, SCORE_FILTER _MAX);
- cgiMakeTextVar(option,(atoi(max)>1000?"1000":max), 4);
- puts("(0 to 1000)");
+ val = atoi(max);
+ if( val > 1000)
+ val = 1000;
+ cgiMakeIntVarInRange(option, val, "Maximum score",0,rangeMin,rangeMax);
+ printf("(%s to %s)\n",rangeMin,rangeMax);
+ freeMem(rangeMin);
+ freeMem(rangeMax);
}
else
{
/* initial value of score theshold is 0, unless
@@ -3166,9 +3194,10 @@
else if(scoreVal > 1000)
scoreVal = 1000;
printf("<b>Show only items with score at or above:</b> ");
snprintf(option, sizeof(option), "%s.%s", name,SCORE_FILTER);
- cgiMakeIntVar(option, cartUsualIntClosestToHome(cart, tdb, compositeLevel, SCORE_FILTER, scoreVal), 11);
+ val = cartUsualIntClosestToHome(cart, tdb, compositeLevel, SCORE_FILTER, scoreVal);
+ cgiMakeIntVarWithLimits(option, val, "Minimum score",0, 0,maxScore);
printf(" (range: 0 to %d)", maxScore);
}
}
@@ -3192,12 +3221,14 @@
safef(option, sizeof(option), "%s.filterTopScorersCt", name);
scoreFilterCt = cartUsualStringClosestToHome(cart, tdb, compositeLevel, "filterTopScorersCt", words[1]);
puts(" <B> Show only items in top-scoring </B>");
- cgiMakeTextVar(option, scoreFilterCt, 5);
+ cgiMakeIntVarWithLimits(option,atoi(scoreFilterCt),"Top-scoring count",0,1,100000);
/* Only check size of table if track does not have subtracks */
- if (!compositeLevel)
- printf(" (range: 1 to 100000, total items: %d)",getTableSize(db, tdb->tableName));
+ if ( !compositeLevel && hTableExists(db, tdb->tableName))
+ printf(" (range: 1 to 100,000 total items: %d)\n",getTableSize(db, tdb->tableName));
+ else
+ printf(" (range: 1 to 100,000)\n");
}
cfgEndBox(boxed);
}
@@ -3252,21 +3283,8 @@
cfgEndBox(boxed);
}
-static void showScoreLimits(struct trackDb *tdb, char *preText,char *scoreName,char *defaults)
-{
-char scoreLimitName[64];
-safef(scoreLimitName, sizeof(scoreLimitName), "%s%s", scoreName, _LIMITS);
-char *setting = trackDbSettingClosestToHomeOrDefault(tdb, scoreLimitName,defaults);
-if(setting)
- {
- char *min = strSwapChar(cloneString(setting),':',0);
- char *max = min + strlen(min) + 1;
- printf("%s(%s to %s)",(preText!=NULL?preText:""),min,max);
- freeMem(min);
- }
-}
static boolean showScoreFilter(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed,
boolean compositeLevel,char *name, char *title, char *label,
char *scoreName,char *defaults,char *limitsDefault)
/* Shows a score filter control with minimum value and optional range */
@@ -3282,11 +3300,24 @@
}
printf("<TR><TD align='right'><B>%s:</B><TD align='left'>",label);
char varName[256];
safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MIN);
- cgiMakeTextVar(varName, cartUsualStringClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), setting), 4);
- showScoreLimits(tdb,"<TD align='left' colspan=3> ",scoreName,limitsDefault);
+ double val = cartUsualDoubleClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), atof(setting));
+ char *rangeMin=NULL;
+ char *rangeMax=NULL;
+ getScoreLimits(tdb, scoreName,limitsDefault,&rangeMin,&rangeMax);
+ cgiMakeDoubleVarInRange(varName,val, label, 0,rangeMin, rangeMax);
+ if(rangeMin && rangeMax)
+ printf("<TD align='left' colspan=3> (%s to %s)",rangeMin, rangeMax);
+ else if(rangeMin)
+ printf("<TD align='left' colspan=3> (minimum %s)",rangeMin);
+ else if(rangeMax)
+ printf("<TD align='left' colspan=3> (maximum %s)",rangeMax);
+ else
+ printf("<TD align='left' colspan=3> ");
puts("</TR>");
+ freeMem(rangeMin);
+ freeMem(rangeMax);
return TRUE;
}
return FALSE;
}
@@ -3434,17 +3465,25 @@
}
else
puts("<TR><TD align='right'><B>Minimum score:</B><TD align='left'>");
safef(varName, sizeof(varName), "%s.%s%s", name, SCORE_FILTER,_MIN);
- cgiMakeTextVar(varName, cartUsualStringClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), min), 4);
+ int val = cartUsualIntClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), atoi(min));
+ char *rangeMin=NULL;
+ char *rangeMax=NULL;
+ getScoreLimits(tdb, SCORE_FILTER,"0:1000",&rangeMin,&rangeMax);
+
+ cgiMakeIntVarInRange(varName, val, "Minimum score", 0, rangeMin, rangeMax);
if(max != NULL)
{
puts("<TD align='right'><B>max:</B><TD align='left'>");
safef(varName, sizeof(varName), "%s.%s%s", name, SCORE_FILTER,_MAX);
- cgiMakeTextVar(varName, cartUsualStringClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), max), 4);
+ val = cartUsualIntClosestToHome(cart, tdb, compositeLevel, varName + (strlen(name) + 1), atoi(max));
+ cgiMakeIntVarInRange(varName, val, "Maximum score", 0, rangeMin, rangeMax);
freeMem(min);
}
- showScoreLimits(tdb, "<TD align='left' colspan=3> ",SCORE_FILTER,"0:1000");
+ printf("<TD align='left' colspan=3> (%s to %s)",rangeMin,rangeMax);
+ freeMem(rangeMin);
+ freeMem(rangeMax);
puts("</TR>");
if(trackDbSettingClosestToHome(tdb, SCORE_MIN) != NULL)
{
printf("<TR><TD align='right'colspan=5>");
@@ -4497,21 +4536,8 @@
puts ("</TABLE>");
}
return TRUE;
}
-static void commonCssStyles()
-/* Defines a few common styles to use through CSS */
-{
- printf("<style type='text/css'>");
- printf(".trDrag {background-color:%s;} .pale {background-color:%s;}",COLOR_BG_GHOST,COLOR_BG_PALE);
- printf(".greenRoof {border-top: 3px groove %s;}",COLOR_DARKGREEN);
- //printf(".greenFloor {border-bottom: 3px ridge %s;}",COLOR_DARKGREEN); // Unused
- //printf(".hiddenRoof {border-top: 0px solid %s;}",COLOR_BG_ALTDEFAULT); // Doesn't work
- //printf(".hiddenFloor {border-bottom: 0px solid %s;}",COLOR_BG_ALTDEFAULT); // Doesn't work
- printf(".greenBox {border: 5px outset %s;}",COLOR_DARKGREEN);
- printf(".blueBox {border: 4px inset %s;}",COLOR_DARKBLUE);
- puts("</style>");
-}
void hCompositeUi(char *db, struct cart *cart, struct trackDb *tdb,
char *primarySubtrack, char *fakeSubmit, char *formName)
/* UI for composite tracks: subtrack selection. If primarySubtrack is
@@ -4525,9 +4551,8 @@
boolean isMatrix = dimensionsExist(tdb);
if(trackDbSetting(tdb, "dragAndDrop") != NULL)
jsIncludeFile("jquery.tablednd.js", NULL);
-commonCssStyles();
jsIncludeFile("hui.js",NULL);
puts("<P>");
if (slCount(tdb->subtracks) < MANY_SUBTRACKS && !hasSubgroups)