Take a look at this and let me know what you think. You might want to tweak
it to your taste yet it does the job. It does keep both option elements in
synch with each other and with the table navigation.
It does not appear that this use case should be implemented by the framework
- it should be up to the developer regardless of the framework.
While it can handle page state, Click tends to be stateless in most cases.
This is why this example is made with no page state. The interesting points
are in the onInit() method where you keep track of the state of the option
elements with the option.setValue() method; you also keep track of the
option elements when you click on the table navigation via the
table.getControlLink().setParameter() method.
The "state" and "district" object attributes are populated at each request
by the framework, considering them as http request parameters (as I
understand this).
I've never needed this scenario before so I guess it can be done better.
<pre style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
1 package pages;/**
2 * User: florin
3 * Date: Feb 3, 2009
4 * Time: 10:40:10 PM
5 */
6
7 import net.sf.click.ActionListener;
8 import net.sf.click.Control;
9 import net.sf.click.Page;
10 import net.sf.click.control.*;
11 import net.sf.click.extras.control.TableInlinePaginator;
12 import org.apache.log4j.Logger;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 public class StatefulChoice extends Page {
20 static Logger logger = Logger.getLogger(StatefulChoice.class);
21
22 //-- keeps track of the currently selected state and district
23 //-- the state and district will be attached to the table paginator
24 //-- the state and district will be used to keep the state of the
option values
25 public String state;
26 public String district;
27
28
29 private Select states = new Select("state");
30 private Select districts = new Select("district");
31
32 public Form form = new Form("form");
33 public Table schTable = new Table("schools");
34
35 public StatefulChoice() {
36 //-- I use a submit as a temporary hack as this is not part of
the questioin, the submit button is invisible
37 //-- As an alternative, javascript can replace the
functionality of the form, such as resubmitting the page
38 //-- with newly attached parameters (state and district)
39 Submit submit = new Submit("Submit");
40 submit.setStyle("visibility", "hidden");
41 submit.setActionListener(new ActionListener() {
42 public boolean onAction(Control source) {
43 return onSubmit();
44 }
45 });
46 form.add(submit);
47
48 //-- both options will cause the submit button to execute
49 states.setAttribute("onchange",
"document.getElementById('form_Submit').click()");
50 form.add(states);
51
52 //-- add schools table
53 schTable.setClass(Table.CLASS_SIMPLE);
54 schTable.setHoverRows(true);
55 schTable.setPageSize(3);
56 schTable.setShowBanner(true);
57 schTable.setSortable(true);
58 schTable.setPaginator(new TableInlinePaginator(schTable));
59 schTable.setPaginatorAttachment(Table.PAGINATOR_INLINE);
60
61 Column name = new Column("name", "School
Name");
62 schTable.addColumn(name);
63 schTable.addColumn(new Column("city"));
64 schTable.addColumn(new Column("state"));
65 }
66
67 public void onInit() {
68 logger.debug("onInit, state=" + state);
69
70 //-- this for statement will be replaced by your helper classes
71 for (int i = 0; i < _states.length; i++) {
72 states.add(new Option(_states[i], _states[++i]));
73 }
74
75 //-- this is key
76 if (state != null) {
77 //-- set the "selected" option value, keeps its
state
78 states.setValue(state);
79 //-- based on selected state, populate the subselect
80 //-- you may choose to have the subselect be visible at all
times
81 form.add(getDistricts());
82 }
83
84 if (district != null) {
85 //-- attach the option values to the table pagination
86 schTable.getControlLink().setParameter("state",
state);
87
schTable.getControlLink().setParameter("district", district);
88 //-- set the state of the districts option element in the
page
89 districts.setValue(district);
90 addStuffToTable();
91 }
92
93 }
94
95 public Control getSchools() {
96 return null;
97 }
98
99 //-- temporary method, use your own datasource
100 public Select getDistricts() {
101 //-- submit the invisible submit button of the form; see notes
above
102 districts.setAttribute("onchange",
"document.getElementById('form_Submit').click()");
103 districts.add(new Option("", "Please Select
District"));
104
105 // Take your districts from an outside source, the following is
just a temporary hack;
106 if ("GA".equalsIgnoreCase(state)) {
107 String[] _distrs = _d[0];
108 for (int i = 0; i < _distrs.length; i++) {
109 districts.add(new Option(_distrs[i], _distrs[++i]));
110 }
111 } else if ("CA".equalsIgnoreCase(state)) {
112 String[] _distrs = _d[1];
113 for (int i = 0; i < _distrs.length; i++) {
114 districts.add(new Option(_distrs[i], _distrs[++i]));
115 }
116 } else if ("NY".equalsIgnoreCase(state)) {
117 String[] _distrs = _d[2];
118 for (int i = 0; i < _distrs.length; i++) {
119 districts.add(new Option(_distrs[i], _distrs[++i]));
120 }
121 }
122
123 return districts;
124 }
125
126
127 public boolean onSubmit() {
128 logger.debug("Selected State: " + state);
129 logger.debug("Selected District: " + district);
130 System.out.println("StatefulChoice.onSubmit " +
form);
131 //-- do conditional work, only when school is selected
132 return true;
133 }
134
135
136 private static String[] _states = {"", "Please
Select State", "GA", "Georgia", "CA",
"California", "NY", "New York"};
137
138
139 private static String[][] _d = {
140 {"GA_EA", "GA East District",
"GA_SO", "GA South District"},
141 {"CA_OR", "Orange County",
"CA_AL", "Alameda"},
142 {"NY_BR", "Bronx District",
"NY_MH", "Manhattan Slums", "NY_QN",
"Queens Wideland"}
143 };
144
145 //-- this is temporary garbage
146 public void addStuffToTable() {
147 if ("GA".equalsIgnoreCase(state)) {
148 if ("GA_EA".equalsIgnoreCase(district)) {
149 List<Map> list = new ArrayList<Map>();
150 HashMap<String, String> map = new
HashMap<String, String>(7);
151 map.put("name", "School One");
152 map.put("city", "City One");
153 map.put("state", "GA");
154 list.add(map);
155
156 map = new HashMap<String, String>(7);
157 map.put("name", "School 2");
158 map.put("city", "City 2");
159 map.put("state", "GA");
160 list.add(map);
161 map = new HashMap<String, String>(7);
162 map.put("name", "School 3");
163 map.put("city", "City 3");
164 map.put("state", "GA");
165 list.add(map);
166 map = new HashMap<String, String>(7);
167 map.put("name", "School 4");
168 map.put("city", "City 4");
169 map.put("state", "GA");
170 list.add(map);
171 map = new HashMap<String, String>(7);
172 map.put("name", "School 5");
173 map.put("city", "City 5");
174 map.put("state", "GA");
175 list.add(map);
176 map = new HashMap<String, String>(7);
177 map.put("name", "School 6");
178 map.put("city", "City 6");
179 map.put("state", "GA");
180 list.add(map);
181 map = new HashMap<String, String>(7);
182 map.put("name", "School 7");
183 map.put("city", "City 7");
184 map.put("state", "GA");
185 list.add(map);
186
187 schTable.setRowList(list);
188 }
189 }
190
191 if ("CA".equalsIgnoreCase(state)) {
192 if ("CA_AL".equalsIgnoreCase(district)) {
193 List<Map> list = new ArrayList<Map>();
194 HashMap<String, String> map = new
HashMap<String, String>(7);
195 map.put("name", "1 school");
196 map.put("city", "1 city");
197 map.put("state", "ca");
198 list.add(map);
199
200 map = new HashMap<String, String>(7);
201 map.put("name", "2 School 2");
202 map.put("city", "2 City 2");
203 map.put("state", "CA");
204 list.add(map);
205 map = new HashMap<String, String>(7);
206 map.put("name", "3 School 3");
207 map.put("city", "3 City 3");
208 map.put("state", "CA");
209 list.add(map);
210 map = new HashMap<String, String>(7);
211 map.put("name", "4 School 4");
212 map.put("city", "4 City 4");
213 map.put("state", "CA");
214 list.add(map);
215 map = new HashMap<String, String>(7);
216 map.put("name", "5 School 5");
217 map.put("city", "5 City 5");
218 map.put("state", "CA");
219 list.add(map);
220 map = new HashMap<String, String>(7);
221 map.put("name", "6 School 6");
222 map.put("city", "6 City 6");
223 map.put("state", "CA");
224 list.add(map);
225 map = new HashMap<String, String>(7);
226 map.put("name", "7 School 7");
227 map.put("city", "7 City 7");
228 map.put("state", "CA");
229 list.add(map);
230
231 schTable.setRowList(list);
232 }
233 }
234 }
235 }
236
237
</pre>
----------------------------------------------------------------------------------------
AND THE TEMPLATE PAGE
----------------------------------------------------------------------------------------
<pre style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
3 <html>
4 <head>
5 <title>Stateful Choice</title>
6 $imports
7
8 </head>
9 <body>
10 <!-- again, if not a form, you can use client side javascript to
update server page with option data -->
11 $form
12 $schools
13
14 </body>
15 </html>
</pre>
Jay Wang wrote:
>
> Thanks you all for the help!
> I found it hard to implement and decided to let go the paging and sorting
> of my table. This way I have no issue. My page size typically is less than
> 200. I am good for now.
> Jay Wang.
>
>
> florin.g wrote:
>>
>> I looks like I needed to know this myself:
>>
>> table.getControlLink().setParameter("companyId", companyId);
>>
>> For this case, it is the way to go.
>>
>>
>>
>> sabob wrote:
>>>
>>> Hi Jay,
>>>
>>> As Florin suggested you can use a stateful Page, or add the state and
>>> district parameters to the Table controlLink.
>>>
>>> See here for details:
>>> http://incubator.apache.org/click/docs/click-api/net/sf/click/control/Table.html#paging-and-sorting
>>>
>>> Another option is to store the Page state in the session for example:
>>>
>>> public class SchoolPageState implements Serializable {
>>> public String state;
>>> public String district;
>>> }
>>>
>>> public class Schools extends WebSiteTemplate {
>>> public void onInit() {
>>> super.onInit();
>>> restoreState();
>>> ...
>>> }
>>>
>>> public void saveState() {
>>> // store the state in the session
>>> }
>>>
>>> public void restoreState() {
>>> // retrieve the state from the session
>>> }
>>>
>>> public void onRender() {
>>> saveState();
>>> }
>>> }
>>>
>>> kind regards
>>>
>>> bob
>>>
>>>
>>> florin.g wrote:
>>>> By default, your page is stateless - hence your selections are lost as
>>>> you
>>>> navigate the table for the first time.
>>>>
>>>> You need to either use a stateful page [ setStateful(true) in the page
>>>> constructor ] or do some footwork with the url parameters.
>>>>
>>>> To continue use a stateless page, you need to pass the choices made in
>>>> your
>>>> lists as url parameters back to the page when you set the district and
>>>> then
>>>> when you navigate the table. I'd use a client side library such as
>>>> jQuery to
>>>> capture the values of the select objects and append these values to the
>>>> previous/next table navigation urls. When back to the page, you must
>>>> use
>>>> those values to re-configure your lists (state, district and schools).
>>>> Sounds like a lot of work. Go with the stateful page.
>>>>
>>>>
>>>>
>>>> Jay Wang wrote:
>>>>
>>>>> Hi,
>>>>> I have a page where I let user to select a state from a selection list
>>>>> of
>>>>> 50 states and after the selection, a school district selection is
>>>>> populated based on the state selected. The user then proceeds to
>>>>> select a
>>>>> school district. After a district is selected , a table display of
>>>>> schools
>>>>> from that district is shown which should allow user to page through if
>>>>> there are multiple pages. The problem I ran into is that the paging
>>>>> and
>>>>> sorting of table columns does not work and it also messes up the
>>>>> selection
>>>>> as well.
>>>>> Source code is attached here (Schools.java and school.htm
>>>>>
>>>>> Schools.java
>>>>> ------------------------
>>>>> import java.sql.SQLException;
>>>>> import java.util.List;
>>>>> import net.sf.click.control.Column;
>>>>> import net.sf.click.control.Form;
>>>>> import net.sf.click.control.PageLink;
>>>>> import net.sf.click.control.Select;
>>>>> import net.sf.click.control.Table;
>>>>> import net.sf.click.extras.control.LinkDecorator;
>>>>> import net.sf.click.extras.control.TableInlinePaginator;
>>>>> import org.apache.commons.lang.StringUtils;
>>>>> import us.myschoolusa.entity.School;
>>>>> import us.myschoolusa.service.DataManager;
>>>>> import us.myschoolusa.util.Helper;
>>>>>
>>>>> /**
>>>>> *
>>>>> * @author wangj6
>>>>> */
>>>>> public class Schools extends WebSiteTemplate {
>>>>>
>>>>> public Table schTable;
>>>>> public PageLink viewLink;
>>>>> public School school;
>>>>> public Form form;
>>>>> private Select stateSelect;
>>>>> private Select districtSelect;
>>>>>
>>>>> public Schools() {
>>>>>
>>>>>
>>>>> form = new Form("selectForm");
>>>>>
>>>>>
>>>>> stateSelect = new Select("state", "");
>>>>> stateSelect.setAttribute("onchange",
>>>>> "handleChange('selectForm_district', selectForm)");
>>>>> form.add(stateSelect);
>>>>>
>>>>> districtSelect = new Select("district", "");
>>>>> districtSelect.setAttribute("onchange",
>>>>> "selectForm.submit()");
>>>>> form.add(districtSelect);
>>>>>
>>>>> schTable = new Table("schTable");
>>>>>
>>>>> schTable.setClass(Table.CLASS_SIMPLE);
>>>>> schTable.setHoverRows(true);
>>>>> schTable.setPageSize(25);
>>>>> schTable.setShowBanner(true);
>>>>> schTable.setSortable(true);
>>>>> schTable.setPaginator(new TableInlinePaginator(schTable));
>>>>> schTable.setPaginatorAttachment(Table.PAGINATOR_INLINE);
>>>>>
>>>>> Column name = new Column("fullName", "School Name");
>>>>> schTable.addColumn(name);
>>>>> schTable.addColumn(new Column("city"));
>>>>> schTable.addColumn(new Column("state"));
>>>>> Column action = new Column("Action", "");
>>>>> viewLink = new PageLink("view", SchoolDetail.class);
>>>>> viewLink.setParameter("referrer", "/schools.htm");
>>>>> action.setDecorator(new LinkDecorator(schTable, viewLink,
>>>>> "schoolId"));
>>>>> action.setSortable(false);
>>>>> schTable.addColumn(action);
>>>>> }
>>>>>
>>>>> public void onInit(){
>>>>> super.onInit();
>>>>> populateSelect();
>>>>>
>>>>> }
>>>>>
>>>>> private void populateSelect() {
>>>>>
>>>>> try {
>>>>> stateSelect.setOptionList(Helper.getOptionForStates());
>>>>> } catch (SQLException e) {
>>>>> e.printStackTrace();
>>>>> form.setError("error.");
>>>>> }
>>>>>
>>>>> stateSelect.bindRequestValue();
>>>>>
>>>>> if (StringUtils.isEmpty(stateSelect.getValue())) {
>>>>> // No state selected, exit early
>>>>> return;
>>>>> }
>>>>> try {
>>>>>
>>>>>
>>>>> districtSelect.setOptionList(Helper.getOptionForDistrictsByState(stateSelect.getValue()));
>>>>> districtSelect.bindRequestValue();
>>>>> if (StringUtils.isEmpty(districtSelect.getValue())) {
>>>>> // No district selected, exit early
>>>>> return;
>>>>> }
>>>>> List<School> schList =
>>>>> DataManager.selectSchoolsByDistrictId(Integer.parseInt(districtSelect.getValue()));
>>>>> schTable.setRowList(schList);
>>>>>
>>>>> } catch (SQLException e) {
>>>>> e.printStackTrace();
>>>>> }
>>>>> }
>>>>> }
>>>>>
>>>>> schools.htm
>>>>> ----------------------------------
>>>>> <h2>School Directory</h2>
>>>>> <br/>
>>>>> $selectForm<br/>
>>>>> #if (${schTable.getRowList().size()} > 0)
>>>>> $schTable
>>>>> #end
>>>>> <script type="text/javascript">
>>>>> function handleChange(id, form) {
>>>>> var select=document.getElementById(id);
>>>>> if(select != null) {
>>>>> select.selectedIndex=-1;
>>>>> }
>>>>> form.submit();
>>>>> }
>>>>> </script>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>>
>>
>>
>
>
--
View this message in context:
http://n2.nabble.com/need-help-on-select-and-table-controls-tp2222256p2267509.html
Sent from the click-user mailing list archive at Nabble.com.