Problem Solution Discussion Loading a Database Record into a Form

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

18.5.1 Problem

You want t o display a form but init ialize it using t he cont ent s of a dat abase record. This allows you t o present a record-edit ing form .

18.5.2 Solution

Generat e t he form as you usually would, but inst ead of using t he usual default s, set t he form elem ent s t o t he values of colum ns in t he dat abase record.

18.5.3 Discussion

The form field generat ion exam ples shown in earlier sect ions have eit her supplied no default value or have used t he default value as specified in an ENUM or SET colum n definit ion as t he field default . That s m ost appropriat e for present ing a blank form t hat you expect t he user t o fill in. However, for applicat ions t hat present a web-based int erface for record edit ing, it s m ore likely t hat youd want t o fill in t he form using t he cont ent of an exist ing record for t he init ial values. This sect ion discusses how t o do t hat . The exam ples shown here illust rat e how t o generat e an edit ing form for records from t he cow_order t able. Norm ally, you would allow t he user t o specify which record t o edit . For sim plicit y, assum e t he use of t he record t hat has an id value of 1 , w it h t he follow ing cont ent s: mysql SELECT FROM cow_order WHERE id = 1\G 1. row id: 1 color: Black White size: large accessories: cow bell,nose ring cust_name: Farmer Brown cust_street: 123 Elm St. cust_city: Katy cust_state: TX To generat e a form wit h cont ent s t hat correspond t o a dat abase record, use t he colum n values for t he elem ent default s as follows: • For input elem ent s such as radio but t ons or checkboxes, add a checked at t ribut e t o each list it em t hat m at ches t he colum n value. • For select elem ent s such as pop- up m enus or scrolling list s, add a selected at t ribut e t o each list it em t hat m at ches t he colum n value. • For t ext fields represent ed as input elem ent s of t ype text , set t he value at t ribut e t o t he corresponding colum n value. For exam ple, a 60-charact er field for cust_name can be present ed init ialized t o Farmer Brown like t his: input type=text name=cust_name value=Farmer Brown size=60 To present a textarea elem ent inst ead, set t he body t o t he colum n value. To creat e a field 40 colum ns wide and 3 rows high, writ e it like t his: textarea name=cust_name cols=40 rows=3 Farmer Brown textarea • I n a record- edit ing sit uat ion, it s a good idea t o include a unique value in t he form so t hat you can t ell which record t he form cont ent s represent when t he user subm it s it . A hidden field is one way t o do t his. I t s value is not displayed t o t he user, but t he browser ret urns it wit h t he rest of t he field values. Our sam ple record has an id colum n wit h a value of 1 , so t he hidden field looks like t his: input type=hidden name=id value=1 The following exam ples show how t o produce a form wit h id represent ed as a hidden field, color as a pop- up m enu, size as a set of radio but t ons, and accessories as a set of checkboxes. The cust om er inform at ion values are represent ed as t ext input boxes, except t hat cust_state is a single- pick scrolling list . You could m ake ot her choices, of course, such as t o present t he sizes as a pop- up m enu rat her t han as radio but t ons. The script s for t he exam ples in t his sect ion are nam ed edit _cow.pl, edit _cow.j sp, and so fort h. The following procedure out lines how t o load t he sam ple cow_table record int o an edit ing form for a CGI .pm -based script : 1. Ret rieve t he colum n values for t he record t hat you want t o load int o t he form : 2. my id = 1; select record number 1 3. my color, size, accessories, 4. cust_name, cust_street, cust_city, cust_state = 5. dbh-selectrow_array 6. SELECT 7. color, size, accessories, 8. cust_name, cust_street, cust_city, cust_state 9. FROM cow_order WHERE id = ?, undef, id; 10. Begin t he form : print start_form -action = url ; 11. Generat e t he hidden field cont aining t he id value t hat uniquely ident ifies t he cow_order r ecor d: print hidden -name = id, -value = id, -override = 1; The override argum ent forces CGI .pm t o use t he value specified in t he value argum ent as t he hidden field value. This is because CGI .pm norm ally t ries t o use values present in t he script execut ion environm ent t o init ialize form fields, even if you provide values in t he field-generat ing calls. CGI .pm does t his t o m ake it easier t o redisplay a form wit h t he values t he user j ust subm it t ed. For exam ple, if you find t hat a form has been filled in incorrect ly, you can redisplay it and ask t he user t o correct any problem s. To m ake sure t hat a form elem ent cont ains t he value you specify, it s necessary t o override t his behavior. 12. Creat e t he fields t hat describe t he cow figurine specificat ions. These fields are generat ed t he sam e way as described in Recipe 18.3 and Recipe 18.4 , except t hat t he default values com e from t he cont ent s of record 1. The code here present s color as a pop- up m enu, size as a set of radio but t ons, and accessories as a set of checkboxes. Not e t hat it split s t he accessories value at com m as t o produce an array of values, because t he colum n value m ight nam e several accessory it em s: 13. my color_ref = dbh-selectcol_arrayref 14. SELECT color FROM cow_color ORDER BY color; 15. 16. print br , Cow color:, br ; 17. print popup_menu -name = color, 18. -values = color_ref, 19. -default = color, 20. -override = 1; 21. 22. my size_info = get_enumorset_info dbh, cow_order, size; 23. 24. print br , Cow figurine size:, br ; 25. print radio_group -name = size, 26. -values = size_info-{values}, 27. -default = size, 28. -override = 1, 29. -linebreak = 1; 30. 31. my acc_info = get_enumorset_info dbh, cow_order, accessories; 32. my acc_val = defined accessories 33. ? split ,, accessories 34. : ; 35. 36. print br , Cow accessory items:, br ; 37. print checkbox_group -name = accessories, 38. -values = acc_info-{values}, 39. -default = \acc_val, 40. -override = 1, -linebreak = 1; 41. Creat e t he cust om er inform at ion fields. These are represent ed as t ext input fields, except t he st at e, w hich is show n here as a single- pick scrolling list : 42. print br , Customer name:, br ; 43. print textfield -name = cust_name, 44. -value = cust_name, 45. -override = 1, 46. -size = 60; 47. 48. print br , Customer street address:, br ; 49. print textfield -name = cust_street, 50. -value = cust_street, 51. -override = 1, 52. -size = 60; 53. 54. print br , Customer city:, br ; 55. print textfield -name = cust_city, 56. -value = cust_city, 57. -override = 1, 58. -size = 60; 59. 60. my state_values; 61. my state_labels; 62. my sth = dbh-prepare SELECT abbrev, name FROM states ORDER BY name; 63. sth-execute ; 64. while my abbrev, name = sth-fetchrow_array 65. { 66. push state_values, abbrev; save each value in an array 67. state_labels{abbrev} = name; map each value to its label 68. } 69. 70. print br , Customer state:, br ; 71. print scrolling_list -name = cust_state, 72. -values = \state_values, 73. -labels = \state_labels, 74. -default = cust_state, 75. -override = 1, -size = 6; display 6 items at a time 76. Creat e a form subm ission but t on and t erm inat e t he form : 77. print br , 78. submit -name = choice, -value = Submit Form, end_form ; The sam e general procedure applies t o ot her API s. For exam ple, in a JSP page, you can fet ch t he record t o be edit ed and ext ract it s cont ent s int o scalar variables like t his: c:set var=id value=1 sql:query var=rs dataSource={conn} SELECT id, color, size, accessories, cust_name, cust_street, cust_city, cust_state FROM cow_order WHERE id = ? sql:param value={id} sql:query c:set var=row value={rs.rows[0]} c:set var=id value={row.id} c:set var=color value={row.color} c:set var=size value={row.size} c:set var=accessories value={row.accessories} c:set var=cust_name value={row.cust_name} c:set var=cust_street value={row.cust_street} c:set var=cust_city value={row.cust_city} c:set var=cust_state value={row.cust_state} Then use t he values t o init ialize t he various form elem ent s, such as: • The hidden field for t he I D value: input type=hidden name=id value=c:out value={id} • The color pop- up m enu: sql:query var=rs dataSource={conn} SELECT color FROM cow_color ORDER BY color sql:query br Cow color:br select name=color c:forEach var=row items={rs.rows} option value=c:out value={row.color} c:if test={row.color == color}selected=selectedc:if c:out value={row.color} option c:forEach select • The cust_name t ext field: • br Customer name:br • input type=text name=cust_name • value=c:out value={cust_name} size=60 For PHP or Pyt hon, creat e t he form using t he ut ilit y funct ions developed in Recipe 18.3 and Recipe 18.4 . See t he cow_edit .php and cow_edit .py script s for det ails.

18.6 Collecting Web Input