c:set var=dateList value={rs.rowsByIndex[0]} c:forEach var=date items={dateList}
input type=radio name=date value=c:out value={date}
c:out value={date} br c:forEach
Of course, if your API m akes it reasonably easy t o perform dat e calculat ions, it likely will be m ore efficient t o generat e t he list of dat es on t he client side wit hout sending a query t o t he
MySQL server.
18.4 Creating Multiple-Pick Form Elements from Database Content
18.4.1 Problem
A form needs t o present a field t hat offers t he user a set of opt ions and allows any num ber of t hem t o be select ed.
18.4.2 Solution
Use a m ult iple-pick list elem ent , such as a set of checkboxes or a scrolling list .
18.4.3 Discussion
Mult iple-pick form elem ent s allow you t o present m ult iple choices, any num ber of which can be select ed, or possibly even none of t hem . For our exam ple scenario in which cust om ers
order cow figurines online, t he m ult iple-pick elem ent is represent ed by t he set of accessory it em s t hat are available. The
accessory
colum n in t he
cow_order
t able is represent ed as a
SET
, so t he allowable and default values can be obt ained from t he following query:
mysql SHOW COLUMNS FROM cow_order LIKE accessories\G 1. row
Field: accessories Type: setcow bell,horns,nose ring,tail ribbon
Null: YES Key:
Default: cow bell,horns Extra:
This set of it em s can reasonably be represent ed as eit her a set of checkboxes or as a m ult iple- pick scrolling list . I n bot h cases, t he
cow bell
and
horns
it em s should be select ed init ially, because each is present in t he colum ns default value. I will discuss t he HTML synt ax
for t hese elem ent s, t hen show how t o generat e t hem from wit hin script s. The m at erial in t his sect ion relies heavily on
Recipe 18.3 , which discusses radio but t ons, pop- up m enus, and
single-pick scrolling list s. I assum e youve already read t hat sect ion.
•
Ch e ck box e s
A group of checkboxes is sim ilar t o a group of radio but t ons in t hat it consist s of
input
elem ent s t hat all have t he sam e
name
at t ribut e. However, t he
type
at t ribut e is
checkbox
rat her t han
radio
, and you can specify
checked
for as m any it em s in t he group as you want t o be select ed by default . I f no it em s are m arked
as
checked
, none are select ed init ially. The following checkbox set shows t he cow accessory it em s wit h t he first t wo it em s select ed by default :
input type=checkbox name=accessories value=cow bell checked=checked cow bell
input type=checkbox name=accessories value=horns checked=checked horns
input type=checkbox name=accessories value=nose ring nose ring
input type=checkbox name=accessories value=tail ribbon tail ribbon
•
CScr ollin g list
A m ult iple- pick scrolling list is const ruct ed in m uch t he sam e m anner as it s single-pick count erpart . The differences are t hat you include a
multiple
at t ribut e in t he opening
select
t ag, and t he default value behavior is different . For a single- pick list , you can add
selected
t o at m ost one it em , and t he first it em is select ed by default in t he absence of an explicit
selected
at t ribut e. Wit h a m ult iple-pick list , you can add a
selected
at t ribut e t o as m any of t he it em s as you like, and no it em s are select ed by default in t he absence of
selected
at t ribut es. I f t he set of cow accessories is represent ed as a m ult iple-pick scrolling list wit h
cow bell
and
horns
select ed init ially, it looks like t his: select name=accessories size=3 multiple=multiple
option value=cow bell selected=selectedcow belloption option value=horns selected=selectedhornsoption
option value=nose ringnose ringoption option value=tail ribbontail ribbonoption
select
I n CGI .pm - based Perl script s, you creat e checkbox set s or scrolling list s by invoking
checkbox_group
or
scrolling_list
. These funct ions t ake
name
,
values
,
labels
, and
default
argum ent s, j ust like t heir single- pick cousins. But because m ult iple it em s can be select ed init ially, CGI .pm allows t he
default
ar gum ent t o be specified as eit her a scalar value or a reference t o an array of values. I t also accept s t he
argum ent nam e
defaults
as a synonym for
default
.
To get t he list of legal values for a
SET
colum n, w e can do t he sam e t hing as in Recipe 18.3
for
ENUM
colum ns—t hat is, call a ut ilit y rout ine t hat ret urns t he colum n m et adat a: my acc_info = get_enumorset_info dbh, cow_order, accessories;
However, t he default value for a
SET
colum n is not in a form t hat is direct ly usable for form elem ent generat ion. MySQL represent s
SET
default values as a com m a- separat ed list of it em s. For exam ple, t he default for t he
accessories
colum n is
cow bell,horns
. That doesnt m at ch t he list - of- values form at t hat t he CGI .pm funct ions expect , so it s necessary t o split t he default value at t he com m as t o obt ain an array. The
following expression shows how t o do so, t aking int o account t he possibilit y t hat t he default value m ight be
undef NULL
: my acc_def = defined acc_info-{default}
? split ,, acc_info-{default} : ;
Aft er split t ing t he default value, pass t he result ing array by reference t o whichever of t he list - generat ing funct ions you want t o use:
print checkbox_group -name = accessories, -values = acc_info-{values},
-default = \acc_def, -linebreak = 1; display buttons vertically
print scrolling_list -name = accessories, -values = acc_info-{values},
-default = \acc_def, -size = 3, display 3 items at a time
-multiple = 1; create multiple-pick list
When you use
SET
values like t his t o creat e list elem ent s, t he values are displayed in t he order t hey are list ed in t he colum n definit ion. That m ay not correspond t o t he order in which
you want t hem t o appear; if not , sort t he values appropriat ely. For PHP and Pyt hon, we can creat e ut ilit y funct ions t o generat e m ult iple- pick it em s. Theyll
have t he following invocat ion synt ax: make_checkbox_group name, values, labels, default, vertical
make_scrolling_list name, values, labels, default, size, multiple The
name
,
values
, and
labels
argum ent s t o t hese funct ions are sim ilar t o t hose of t he PHP and Pyt hon single-pick ut ilit y rout ines described in
Recipe 18.3 .
make_checkbox_group
t ak es a
vertical
argum ent t hat indicat es t hat t he it em s should be st acked vert ically rat her t han horizont ally if it s t rue.
make_scrolling_list
has already been described in Recipe 18.3
for producing
single-pick list s; t o use it here, t he
multiple
argum ent should be t rue t o produce a m ult iple-pick list . For bot h funct ions, t he
default
argum ent can be an array of m ult iple values if several it em s should be select ed init ially.
make_checkbox_group
looks like t his shown here in Pyt hon; t he PHP version is sim ilar :
def make_checkbox_group name, values, labels, default, vertical: if type values not in types.ListType, types.TupleType:
return make_checkbox_group: values argument must be a list if type labels not in types.ListType, types.TupleType:
return make_checkbox_group: labels argument must be a list if len values = len labels:
return make_checkbox_group: value and label list size mismatch if type default not in types.ListType, types.TupleType:
default = [ default ] convert scalar to list str =
for i in range len values: value = values[i]
label = labels[i] make sure value and label are strings
if type value is not types.StringType: value = `value`
if type label is not types.StringType: label = `label`
select the item if it corresponds to one of the default values checked =
for d in default: if type d is not types.StringType:
d = `d` if value == d:
checked = checked=\checked\ break
if type name is not types.StringType: name = `name`
str = str + \ input type=\checkbox\ name=\s\ value=\s\s s
\ cgi.escape name, 1,
cgi.escape value, 1, checked,
cgi.escape label, 1 if vertical:
str = str + br display items vertically str = str + \n
return str
To fet ch t he cow accessory inform at ion and present it using checkboxes, do t his: import re needed for re.split
acc_info = get_enumorset_info conn, cow_order, accessories if acc_info[default] == None:
acc_def = else:
acc_def = re.split ,, acc_info[default] print make_checkbox_group accessories,
acc_info[values], acc_info[values],
acc_def, 1 display items vertically
To display a scrolling list inst ead, invoke
make_scrolling_list
: print make_scrolling_list accessories,
acc_info[values], acc_info[values],
acc_def, 3, display 3 items at a time
1 create multiple-pick list
I n PHP, fet ch t he accessory inform at ion, t hen present checkboxes or a scrolling list as follows: acc_info = get_enumorset_info conn_id, cow_order, accessories;
acc_def = explode ,, acc_info[default]; print make_checkbox_group accessories[ ],
acc_info[values], acc_info[values],
acc_def, TRUE; display items vertically
print make_scrolling_list accessories[ ], acc_info[values],
acc_info[values], acc_def,
3, display 3 items at a time TRUE; create multiple-pick list
Not e t hat t he field nam e in t he PHP exam ples is specified as
accessories[ ]
r at her t han as
accessories
. I n PHP, you m ust add
[ ]
t o t he nam e if you w ant t o allow a field t o have m ult iple values. I f you om it t he
[ ]
, t he user w ill be able t o select m ult iple it em s while filling in t he form , but PHP will ret urn only one of t hem t o your script . This issue
will com e up again when we discuss how t o process t he cont ent s of subm it t ed form s in Recipe
18.6 .
I n JSP pages, t he
getEnumOrSetValues
funct ion used earlier t o get t he value list for t he
size
colum n an
ENUM
can also be used for t he
accessory
colum n a
SET
. The colum n definit ion and default value are in t he second and fift h colum n of t he
SHOW COLUMNS
query t hat ret urns inform at ion about t he
accessory
colum n. Run t he query, parse t he t ype definit ion int o a list of values nam ed
values
, and put t he default value in
defList
like t his:
sql:query var=rs dataSource={conn} SHOW COLUMNS FROM cow_order LIKE accessories
sql:query c:set var=typeDef scope=page value={rs.rowsByIndex[0][1]}
getEnumOrSetValues pageContext, typeDef, values; c:set var=defList scope=page value={rs.rowsByIndex[0][4]}
For a
SET
colum n, t he
defList
value m ight cont ain m ult iple values, separat ed by com m as. I t needs no special t reat m ent ; t he JSTL
c:forEach
t ag knows how t o it erat e over such a st ring, so t he default values for a checkbox set can be init ialized as follow s:
c:forEach var=val items={values} input type=checkbox name=accessories
value=c:out value={val} c:forEach var=default items={defList}
c:if test={val == default}checked=checkedc:if c:forEach
c:out value={val} br c:forEach
For a m ult iple-pick scrolling list , do t his: select name=accessories size=3 multiple=multiple
c:forEach var=val items={values} option
value=c:out value={val} c:forEach var=default items={defList}
c:if test={val == default}selected=selectedc:if c:forEach
c:out value={val} option c:forEach
select
18.5 Loading a Database Record into a Form