Fossil SCM
The programmatically-generated input-with-label elements now use an inner LABEL, instead of SPAN, and auto-generated INPUT element IDs to go with the labels (which require an ID).
Commit
b46d11b871ef23d63880a8650592a954ba37f046ae0ecd1b5083c2768a6f0fb6
Parent
695dde004c4e6f5…
2 files changed
+2
-1
+28
-9
+2
-1
| --- src/default_css.txt | ||
| +++ src/default_css.txt | ||
| @@ -1149,9 +1149,10 @@ | ||
| 1149 | 1149 | vertical-align: sub; |
| 1150 | 1150 | } |
| 1151 | 1151 | .input-with-label > input[type=radio] { |
| 1152 | 1152 | vertical-align: sub; |
| 1153 | 1153 | } |
| 1154 | -.input-with-label > span { | |
| 1154 | +.input-with-label > label { | |
| 1155 | + font-weight: initial; | |
| 1155 | 1156 | margin: 0 0.25em 0 0.25em; |
| 1156 | 1157 | vertical-align: middle; |
| 1157 | 1158 | } |
| 1158 | 1159 |
| --- src/default_css.txt | |
| +++ src/default_css.txt | |
| @@ -1149,9 +1149,10 @@ | |
| 1149 | vertical-align: sub; |
| 1150 | } |
| 1151 | .input-with-label > input[type=radio] { |
| 1152 | vertical-align: sub; |
| 1153 | } |
| 1154 | .input-with-label > span { |
| 1155 | margin: 0 0.25em 0 0.25em; |
| 1156 | vertical-align: middle; |
| 1157 | } |
| 1158 |
| --- src/default_css.txt | |
| +++ src/default_css.txt | |
| @@ -1149,9 +1149,10 @@ | |
| 1149 | vertical-align: sub; |
| 1150 | } |
| 1151 | .input-with-label > input[type=radio] { |
| 1152 | vertical-align: sub; |
| 1153 | } |
| 1154 | .input-with-label > label { |
| 1155 | font-weight: initial; |
| 1156 | margin: 0 0.25em 0 0.25em; |
| 1157 | vertical-align: middle; |
| 1158 | } |
| 1159 |
+28
-9
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1296,10 +1296,21 @@ | ||
| 1296 | 1296 | } |
| 1297 | 1297 | |
| 1298 | 1298 | #if INTERFACE |
| 1299 | 1299 | # define webpage_assert(T) if(!(T)){webpage_assert_page(__FILE__,__LINE__,#T);} |
| 1300 | 1300 | #endif |
| 1301 | + | |
| 1302 | +/* | |
| 1303 | +** Returns a pseudo-random input field ID, for use in associating an | |
| 1304 | +** ID-less input field with a label. The memory is owned by the | |
| 1305 | +** caller. | |
| 1306 | +*/ | |
| 1307 | +static char * style_next_input_id(){ | |
| 1308 | + static int inputID = 0; | |
| 1309 | + ++inputID; | |
| 1310 | + return mprintf("input-id-%d", inputID); | |
| 1311 | +} | |
| 1301 | 1312 | |
| 1302 | 1313 | /* |
| 1303 | 1314 | ** Outputs a labeled checkbox element. zWrapperId is an optional ID |
| 1304 | 1315 | ** value for the containing element (see below). zFieldName is the |
| 1305 | 1316 | ** form element name. zLabel is the label for the checkbox. zValue is |
| @@ -1310,12 +1321,13 @@ | ||
| 1310 | 1321 | ** |
| 1311 | 1322 | ** Resulting structure: |
| 1312 | 1323 | ** |
| 1313 | 1324 | ** <span class='input-with-label' title={{zTip}} id={{zWrapperId}}> |
| 1314 | 1325 | ** <input type='checkbox' name={{zFieldName}} value={{zValue}} |
| 1326 | +** id='A RANDOM VALUE' | |
| 1315 | 1327 | ** {{isChecked ? " checked : ""}}/> |
| 1316 | -** <span>{{zLabel}}</span> | |
| 1328 | +** <label for='ID OF THE INPUT FIELD'>{{zLabel}}</label> | |
| 1317 | 1329 | ** </span> |
| 1318 | 1330 | ** |
| 1319 | 1331 | ** zLabel, and zValue are required. zFieldName, zWrapperId, and zTip |
| 1320 | 1332 | ** are may be NULL or empty. |
| 1321 | 1333 | ** |
| @@ -1325,24 +1337,26 @@ | ||
| 1325 | 1337 | */ |
| 1326 | 1338 | void style_labeled_checkbox(const char * zWrapperId, |
| 1327 | 1339 | const char *zFieldName, const char * zLabel, |
| 1328 | 1340 | const char * zValue, int isChecked, |
| 1329 | 1341 | const char * zTip){ |
| 1342 | + char * zLabelID = style_next_input_id(); | |
| 1330 | 1343 | CX("<span class='input-with-label'"); |
| 1331 | 1344 | if(zTip && *zTip){ |
| 1332 | 1345 | CX(" title='%h'", zTip); |
| 1333 | 1346 | } |
| 1334 | 1347 | if(zWrapperId && *zWrapperId){ |
| 1335 | 1348 | CX(" id='%s'",zWrapperId); |
| 1336 | 1349 | } |
| 1337 | - CX("><input type='checkbox' "); | |
| 1350 | + CX("><input type='checkbox' id='%s' ", zLabelID); | |
| 1338 | 1351 | if(zFieldName && *zFieldName){ |
| 1339 | 1352 | CX("name='%s' ",zFieldName); |
| 1340 | 1353 | } |
| 1341 | 1354 | CX("value='%T'%s/>", |
| 1342 | 1355 | zValue ? zValue : "", isChecked ? " checked" : ""); |
| 1343 | - CX("<span>%h</span></span>", zLabel); | |
| 1356 | + CX("<label for='%s'>%h</label></span>", zLabelID, zLabel); | |
| 1357 | + fossil_free(zLabelID); | |
| 1344 | 1358 | } |
| 1345 | 1359 | |
| 1346 | 1360 | /* |
| 1347 | 1361 | ** Outputs a SELECT list from a compile-time list of integers. |
| 1348 | 1362 | ** The vargs must be a list of (const char *, int) pairs, terminated |
| @@ -1372,12 +1386,12 @@ | ||
| 1372 | 1386 | ** zTooltip is an optional value for the SELECT's title attribute. |
| 1373 | 1387 | ** |
| 1374 | 1388 | ** The structure of the emitted HTML is: |
| 1375 | 1389 | ** |
| 1376 | 1390 | ** <span class='input-with-label' title={{zToolTip}} id={{zWrapperId}}> |
| 1377 | -** <span>{{zLabel}}</span> | |
| 1378 | -** <select>...</select> | |
| 1391 | +** <label for='SELECT ELEMENT ID'>{{zLabel}}</span> | |
| 1392 | +** <select id='RANDOM ID' name={{zFieldName}}>...</select> | |
| 1379 | 1393 | ** </span> |
| 1380 | 1394 | ** |
| 1381 | 1395 | ** Example: |
| 1382 | 1396 | ** |
| 1383 | 1397 | ** style_select_list_int("my-grapes", "my_grapes", "Grapes", |
| @@ -1389,11 +1403,13 @@ | ||
| 1389 | 1403 | */ |
| 1390 | 1404 | void style_select_list_int(const char * zWrapperId, |
| 1391 | 1405 | const char *zFieldName, const char * zLabel, |
| 1392 | 1406 | const char * zToolTip, int selectedVal, |
| 1393 | 1407 | ... ){ |
| 1408 | + char * zLabelID = style_next_input_id(); | |
| 1394 | 1409 | va_list vargs; |
| 1410 | + | |
| 1395 | 1411 | va_start(vargs,selectedVal); |
| 1396 | 1412 | CX("<span class='input-with-label'"); |
| 1397 | 1413 | if(zToolTip && *zToolTip){ |
| 1398 | 1414 | CX(" title='%h'",zToolTip); |
| 1399 | 1415 | } |
| @@ -1400,13 +1416,13 @@ | ||
| 1400 | 1416 | if(zWrapperId && *zWrapperId){ |
| 1401 | 1417 | CX(" id='%s'",zWrapperId); |
| 1402 | 1418 | } |
| 1403 | 1419 | CX(">"); |
| 1404 | 1420 | if(zLabel && *zLabel){ |
| 1405 | - CX("<span>%h</span>", zLabel); | |
| 1421 | + CX("<label label='%s'>%h</label>", zLabelID, zLabel); | |
| 1406 | 1422 | } |
| 1407 | - CX("<select name='%s'>",zFieldName); | |
| 1423 | + CX("<select name='%s' id='%s'>",zFieldName, zLabelID); | |
| 1408 | 1424 | while(1){ |
| 1409 | 1425 | const char * zOption = va_arg(vargs,char *); |
| 1410 | 1426 | int v; |
| 1411 | 1427 | if(NULL==zOption){ |
| 1412 | 1428 | break; |
| @@ -1422,10 +1438,11 @@ | ||
| 1422 | 1438 | CX("</option>\n"); |
| 1423 | 1439 | } |
| 1424 | 1440 | CX("</select>\n"); |
| 1425 | 1441 | CX("</span>\n"); |
| 1426 | 1442 | va_end(vargs); |
| 1443 | + fossil_free(zLabelID); | |
| 1427 | 1444 | } |
| 1428 | 1445 | |
| 1429 | 1446 | /* |
| 1430 | 1447 | ** The C-string counterpart of style_select_list_int(), this variant |
| 1431 | 1448 | ** differs only in that its variadic arguments are C-strings in pairs |
| @@ -1447,10 +1464,11 @@ | ||
| 1447 | 1464 | */ |
| 1448 | 1465 | void style_select_list_str(const char * zWrapperId, |
| 1449 | 1466 | const char *zFieldName, const char * zLabel, |
| 1450 | 1467 | const char * zToolTip, char const * zSelectedVal, |
| 1451 | 1468 | ... ){ |
| 1469 | + char * zLabelID = style_next_input_id(); | |
| 1452 | 1470 | va_list vargs; |
| 1453 | 1471 | |
| 1454 | 1472 | va_start(vargs,zSelectedVal); |
| 1455 | 1473 | if(!zSelectedVal){ |
| 1456 | 1474 | zSelectedVal = __FILE__/*some string we'll never match*/; |
| @@ -1462,13 +1480,13 @@ | ||
| 1462 | 1480 | if(zWrapperId && *zWrapperId){ |
| 1463 | 1481 | CX(" id='%s'",zWrapperId); |
| 1464 | 1482 | } |
| 1465 | 1483 | CX(">"); |
| 1466 | 1484 | if(zLabel && *zLabel){ |
| 1467 | - CX("<span>%h</span>", zLabel); | |
| 1485 | + CX("<label for='%s'>%h</label>", zLabelID, zLabel); | |
| 1468 | 1486 | } |
| 1469 | - CX("<select name='%s'>",zFieldName); | |
| 1487 | + CX("<select name='%s' id='%s'>",zFieldName, zLabelID); | |
| 1470 | 1488 | while(1){ |
| 1471 | 1489 | const char * zLabel = va_arg(vargs,char *); |
| 1472 | 1490 | const char * zVal; |
| 1473 | 1491 | if(NULL==zLabel){ |
| 1474 | 1492 | break; |
| @@ -1484,10 +1502,11 @@ | ||
| 1484 | 1502 | CX("</option>\n"); |
| 1485 | 1503 | } |
| 1486 | 1504 | CX("</select>\n"); |
| 1487 | 1505 | CX("</span>\n"); |
| 1488 | 1506 | va_end(vargs); |
| 1507 | + fossil_free(zLabelID); | |
| 1489 | 1508 | } |
| 1490 | 1509 | |
| 1491 | 1510 | |
| 1492 | 1511 | /* |
| 1493 | 1512 | ** The first time this is called, it emits code to install and |
| 1494 | 1513 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1296,10 +1296,21 @@ | |
| 1296 | } |
| 1297 | |
| 1298 | #if INTERFACE |
| 1299 | # define webpage_assert(T) if(!(T)){webpage_assert_page(__FILE__,__LINE__,#T);} |
| 1300 | #endif |
| 1301 | |
| 1302 | /* |
| 1303 | ** Outputs a labeled checkbox element. zWrapperId is an optional ID |
| 1304 | ** value for the containing element (see below). zFieldName is the |
| 1305 | ** form element name. zLabel is the label for the checkbox. zValue is |
| @@ -1310,12 +1321,13 @@ | |
| 1310 | ** |
| 1311 | ** Resulting structure: |
| 1312 | ** |
| 1313 | ** <span class='input-with-label' title={{zTip}} id={{zWrapperId}}> |
| 1314 | ** <input type='checkbox' name={{zFieldName}} value={{zValue}} |
| 1315 | ** {{isChecked ? " checked : ""}}/> |
| 1316 | ** <span>{{zLabel}}</span> |
| 1317 | ** </span> |
| 1318 | ** |
| 1319 | ** zLabel, and zValue are required. zFieldName, zWrapperId, and zTip |
| 1320 | ** are may be NULL or empty. |
| 1321 | ** |
| @@ -1325,24 +1337,26 @@ | |
| 1325 | */ |
| 1326 | void style_labeled_checkbox(const char * zWrapperId, |
| 1327 | const char *zFieldName, const char * zLabel, |
| 1328 | const char * zValue, int isChecked, |
| 1329 | const char * zTip){ |
| 1330 | CX("<span class='input-with-label'"); |
| 1331 | if(zTip && *zTip){ |
| 1332 | CX(" title='%h'", zTip); |
| 1333 | } |
| 1334 | if(zWrapperId && *zWrapperId){ |
| 1335 | CX(" id='%s'",zWrapperId); |
| 1336 | } |
| 1337 | CX("><input type='checkbox' "); |
| 1338 | if(zFieldName && *zFieldName){ |
| 1339 | CX("name='%s' ",zFieldName); |
| 1340 | } |
| 1341 | CX("value='%T'%s/>", |
| 1342 | zValue ? zValue : "", isChecked ? " checked" : ""); |
| 1343 | CX("<span>%h</span></span>", zLabel); |
| 1344 | } |
| 1345 | |
| 1346 | /* |
| 1347 | ** Outputs a SELECT list from a compile-time list of integers. |
| 1348 | ** The vargs must be a list of (const char *, int) pairs, terminated |
| @@ -1372,12 +1386,12 @@ | |
| 1372 | ** zTooltip is an optional value for the SELECT's title attribute. |
| 1373 | ** |
| 1374 | ** The structure of the emitted HTML is: |
| 1375 | ** |
| 1376 | ** <span class='input-with-label' title={{zToolTip}} id={{zWrapperId}}> |
| 1377 | ** <span>{{zLabel}}</span> |
| 1378 | ** <select>...</select> |
| 1379 | ** </span> |
| 1380 | ** |
| 1381 | ** Example: |
| 1382 | ** |
| 1383 | ** style_select_list_int("my-grapes", "my_grapes", "Grapes", |
| @@ -1389,11 +1403,13 @@ | |
| 1389 | */ |
| 1390 | void style_select_list_int(const char * zWrapperId, |
| 1391 | const char *zFieldName, const char * zLabel, |
| 1392 | const char * zToolTip, int selectedVal, |
| 1393 | ... ){ |
| 1394 | va_list vargs; |
| 1395 | va_start(vargs,selectedVal); |
| 1396 | CX("<span class='input-with-label'"); |
| 1397 | if(zToolTip && *zToolTip){ |
| 1398 | CX(" title='%h'",zToolTip); |
| 1399 | } |
| @@ -1400,13 +1416,13 @@ | |
| 1400 | if(zWrapperId && *zWrapperId){ |
| 1401 | CX(" id='%s'",zWrapperId); |
| 1402 | } |
| 1403 | CX(">"); |
| 1404 | if(zLabel && *zLabel){ |
| 1405 | CX("<span>%h</span>", zLabel); |
| 1406 | } |
| 1407 | CX("<select name='%s'>",zFieldName); |
| 1408 | while(1){ |
| 1409 | const char * zOption = va_arg(vargs,char *); |
| 1410 | int v; |
| 1411 | if(NULL==zOption){ |
| 1412 | break; |
| @@ -1422,10 +1438,11 @@ | |
| 1422 | CX("</option>\n"); |
| 1423 | } |
| 1424 | CX("</select>\n"); |
| 1425 | CX("</span>\n"); |
| 1426 | va_end(vargs); |
| 1427 | } |
| 1428 | |
| 1429 | /* |
| 1430 | ** The C-string counterpart of style_select_list_int(), this variant |
| 1431 | ** differs only in that its variadic arguments are C-strings in pairs |
| @@ -1447,10 +1464,11 @@ | |
| 1447 | */ |
| 1448 | void style_select_list_str(const char * zWrapperId, |
| 1449 | const char *zFieldName, const char * zLabel, |
| 1450 | const char * zToolTip, char const * zSelectedVal, |
| 1451 | ... ){ |
| 1452 | va_list vargs; |
| 1453 | |
| 1454 | va_start(vargs,zSelectedVal); |
| 1455 | if(!zSelectedVal){ |
| 1456 | zSelectedVal = __FILE__/*some string we'll never match*/; |
| @@ -1462,13 +1480,13 @@ | |
| 1462 | if(zWrapperId && *zWrapperId){ |
| 1463 | CX(" id='%s'",zWrapperId); |
| 1464 | } |
| 1465 | CX(">"); |
| 1466 | if(zLabel && *zLabel){ |
| 1467 | CX("<span>%h</span>", zLabel); |
| 1468 | } |
| 1469 | CX("<select name='%s'>",zFieldName); |
| 1470 | while(1){ |
| 1471 | const char * zLabel = va_arg(vargs,char *); |
| 1472 | const char * zVal; |
| 1473 | if(NULL==zLabel){ |
| 1474 | break; |
| @@ -1484,10 +1502,11 @@ | |
| 1484 | CX("</option>\n"); |
| 1485 | } |
| 1486 | CX("</select>\n"); |
| 1487 | CX("</span>\n"); |
| 1488 | va_end(vargs); |
| 1489 | } |
| 1490 | |
| 1491 | |
| 1492 | /* |
| 1493 | ** The first time this is called, it emits code to install and |
| 1494 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1296,10 +1296,21 @@ | |
| 1296 | } |
| 1297 | |
| 1298 | #if INTERFACE |
| 1299 | # define webpage_assert(T) if(!(T)){webpage_assert_page(__FILE__,__LINE__,#T);} |
| 1300 | #endif |
| 1301 | |
| 1302 | /* |
| 1303 | ** Returns a pseudo-random input field ID, for use in associating an |
| 1304 | ** ID-less input field with a label. The memory is owned by the |
| 1305 | ** caller. |
| 1306 | */ |
| 1307 | static char * style_next_input_id(){ |
| 1308 | static int inputID = 0; |
| 1309 | ++inputID; |
| 1310 | return mprintf("input-id-%d", inputID); |
| 1311 | } |
| 1312 | |
| 1313 | /* |
| 1314 | ** Outputs a labeled checkbox element. zWrapperId is an optional ID |
| 1315 | ** value for the containing element (see below). zFieldName is the |
| 1316 | ** form element name. zLabel is the label for the checkbox. zValue is |
| @@ -1310,12 +1321,13 @@ | |
| 1321 | ** |
| 1322 | ** Resulting structure: |
| 1323 | ** |
| 1324 | ** <span class='input-with-label' title={{zTip}} id={{zWrapperId}}> |
| 1325 | ** <input type='checkbox' name={{zFieldName}} value={{zValue}} |
| 1326 | ** id='A RANDOM VALUE' |
| 1327 | ** {{isChecked ? " checked : ""}}/> |
| 1328 | ** <label for='ID OF THE INPUT FIELD'>{{zLabel}}</label> |
| 1329 | ** </span> |
| 1330 | ** |
| 1331 | ** zLabel, and zValue are required. zFieldName, zWrapperId, and zTip |
| 1332 | ** are may be NULL or empty. |
| 1333 | ** |
| @@ -1325,24 +1337,26 @@ | |
| 1337 | */ |
| 1338 | void style_labeled_checkbox(const char * zWrapperId, |
| 1339 | const char *zFieldName, const char * zLabel, |
| 1340 | const char * zValue, int isChecked, |
| 1341 | const char * zTip){ |
| 1342 | char * zLabelID = style_next_input_id(); |
| 1343 | CX("<span class='input-with-label'"); |
| 1344 | if(zTip && *zTip){ |
| 1345 | CX(" title='%h'", zTip); |
| 1346 | } |
| 1347 | if(zWrapperId && *zWrapperId){ |
| 1348 | CX(" id='%s'",zWrapperId); |
| 1349 | } |
| 1350 | CX("><input type='checkbox' id='%s' ", zLabelID); |
| 1351 | if(zFieldName && *zFieldName){ |
| 1352 | CX("name='%s' ",zFieldName); |
| 1353 | } |
| 1354 | CX("value='%T'%s/>", |
| 1355 | zValue ? zValue : "", isChecked ? " checked" : ""); |
| 1356 | CX("<label for='%s'>%h</label></span>", zLabelID, zLabel); |
| 1357 | fossil_free(zLabelID); |
| 1358 | } |
| 1359 | |
| 1360 | /* |
| 1361 | ** Outputs a SELECT list from a compile-time list of integers. |
| 1362 | ** The vargs must be a list of (const char *, int) pairs, terminated |
| @@ -1372,12 +1386,12 @@ | |
| 1386 | ** zTooltip is an optional value for the SELECT's title attribute. |
| 1387 | ** |
| 1388 | ** The structure of the emitted HTML is: |
| 1389 | ** |
| 1390 | ** <span class='input-with-label' title={{zToolTip}} id={{zWrapperId}}> |
| 1391 | ** <label for='SELECT ELEMENT ID'>{{zLabel}}</span> |
| 1392 | ** <select id='RANDOM ID' name={{zFieldName}}>...</select> |
| 1393 | ** </span> |
| 1394 | ** |
| 1395 | ** Example: |
| 1396 | ** |
| 1397 | ** style_select_list_int("my-grapes", "my_grapes", "Grapes", |
| @@ -1389,11 +1403,13 @@ | |
| 1403 | */ |
| 1404 | void style_select_list_int(const char * zWrapperId, |
| 1405 | const char *zFieldName, const char * zLabel, |
| 1406 | const char * zToolTip, int selectedVal, |
| 1407 | ... ){ |
| 1408 | char * zLabelID = style_next_input_id(); |
| 1409 | va_list vargs; |
| 1410 | |
| 1411 | va_start(vargs,selectedVal); |
| 1412 | CX("<span class='input-with-label'"); |
| 1413 | if(zToolTip && *zToolTip){ |
| 1414 | CX(" title='%h'",zToolTip); |
| 1415 | } |
| @@ -1400,13 +1416,13 @@ | |
| 1416 | if(zWrapperId && *zWrapperId){ |
| 1417 | CX(" id='%s'",zWrapperId); |
| 1418 | } |
| 1419 | CX(">"); |
| 1420 | if(zLabel && *zLabel){ |
| 1421 | CX("<label label='%s'>%h</label>", zLabelID, zLabel); |
| 1422 | } |
| 1423 | CX("<select name='%s' id='%s'>",zFieldName, zLabelID); |
| 1424 | while(1){ |
| 1425 | const char * zOption = va_arg(vargs,char *); |
| 1426 | int v; |
| 1427 | if(NULL==zOption){ |
| 1428 | break; |
| @@ -1422,10 +1438,11 @@ | |
| 1438 | CX("</option>\n"); |
| 1439 | } |
| 1440 | CX("</select>\n"); |
| 1441 | CX("</span>\n"); |
| 1442 | va_end(vargs); |
| 1443 | fossil_free(zLabelID); |
| 1444 | } |
| 1445 | |
| 1446 | /* |
| 1447 | ** The C-string counterpart of style_select_list_int(), this variant |
| 1448 | ** differs only in that its variadic arguments are C-strings in pairs |
| @@ -1447,10 +1464,11 @@ | |
| 1464 | */ |
| 1465 | void style_select_list_str(const char * zWrapperId, |
| 1466 | const char *zFieldName, const char * zLabel, |
| 1467 | const char * zToolTip, char const * zSelectedVal, |
| 1468 | ... ){ |
| 1469 | char * zLabelID = style_next_input_id(); |
| 1470 | va_list vargs; |
| 1471 | |
| 1472 | va_start(vargs,zSelectedVal); |
| 1473 | if(!zSelectedVal){ |
| 1474 | zSelectedVal = __FILE__/*some string we'll never match*/; |
| @@ -1462,13 +1480,13 @@ | |
| 1480 | if(zWrapperId && *zWrapperId){ |
| 1481 | CX(" id='%s'",zWrapperId); |
| 1482 | } |
| 1483 | CX(">"); |
| 1484 | if(zLabel && *zLabel){ |
| 1485 | CX("<label for='%s'>%h</label>", zLabelID, zLabel); |
| 1486 | } |
| 1487 | CX("<select name='%s' id='%s'>",zFieldName, zLabelID); |
| 1488 | while(1){ |
| 1489 | const char * zLabel = va_arg(vargs,char *); |
| 1490 | const char * zVal; |
| 1491 | if(NULL==zLabel){ |
| 1492 | break; |
| @@ -1484,10 +1502,11 @@ | |
| 1502 | CX("</option>\n"); |
| 1503 | } |
| 1504 | CX("</select>\n"); |
| 1505 | CX("</span>\n"); |
| 1506 | va_end(vargs); |
| 1507 | fossil_free(zLabelID); |
| 1508 | } |
| 1509 | |
| 1510 | |
| 1511 | /* |
| 1512 | ** The first time this is called, it emits code to install and |
| 1513 |