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(&quot;state&quot;);
30       private Select districts = new Select(&quot;district&quot;);
31   
32       public Form form = new Form(&quot;form&quot;);
33       public Table schTable = new Table(&quot;schools&quot;);
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(&quot;Submit&quot;);
40           submit.setStyle(&quot;visibility&quot;, &quot;hidden&quot;);
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(&quot;onchange&quot;,
&quot;document.getElementById(&apos;form_Submit&apos;).click()&quot;);
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(&quot;name&quot;, &quot;School
Name&quot;);
62           schTable.addColumn(name);
63           schTable.addColumn(new Column(&quot;city&quot;));
64           schTable.addColumn(new Column(&quot;state&quot;));
65       }
66   
67       public void onInit() {
68           logger.debug(&quot;onInit, state=&quot; + state);
69   
70           //-- this for statement will be replaced by your helper classes
71           for (int i = 0; i &lt; _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 &quot;selected&quot; 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(&quot;state&quot;,
state);
87              
schTable.getControlLink().setParameter(&quot;district&quot;, 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(&quot;onchange&quot;,
&quot;document.getElementById(&apos;form_Submit&apos;).click()&quot;);
103          districts.add(new Option(&quot;&quot;, &quot;Please Select
District&quot;));
104  
105          // Take your districts from an outside source, the following is
just a temporary hack;
106          if (&quot;GA&quot;.equalsIgnoreCase(state)) {
107              String[] _distrs = _d[0];
108              for (int i = 0; i &lt; _distrs.length; i++) {
109                  districts.add(new Option(_distrs[i], _distrs[++i]));
110              }
111          } else if (&quot;CA&quot;.equalsIgnoreCase(state)) {
112              String[] _distrs = _d[1];
113              for (int i = 0; i &lt; _distrs.length; i++) {
114                  districts.add(new Option(_distrs[i], _distrs[++i]));
115              }
116          } else if (&quot;NY&quot;.equalsIgnoreCase(state)) {
117              String[] _distrs = _d[2];
118              for (int i = 0; i &lt; _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(&quot;Selected State: &quot; + state);
129          logger.debug(&quot;Selected District: &quot; + district);
130          System.out.println(&quot;StatefulChoice.onSubmit &quot; +
form);
131          //-- do conditional work, only when school is selected
132          return true;
133      }
134  
135  
136      private static String[] _states = {&quot;&quot;, &quot;Please
Select State&quot;, &quot;GA&quot;, &quot;Georgia&quot;, &quot;CA&quot;,
&quot;California&quot;, &quot;NY&quot;, &quot;New York&quot;};
137  
138  
139      private static String[][] _d = {
140              {&quot;GA_EA&quot;, &quot;GA East District&quot;,
&quot;GA_SO&quot;, &quot;GA South District&quot;},
141              {&quot;CA_OR&quot;, &quot;Orange County&quot;,
&quot;CA_AL&quot;, &quot;Alameda&quot;},
142              {&quot;NY_BR&quot;, &quot;Bronx District&quot;,
&quot;NY_MH&quot;, &quot;Manhattan Slums&quot;, &quot;NY_QN&quot;,
&quot;Queens Wideland&quot;}
143      };
144  
145      //-- this is temporary garbage
146      public void addStuffToTable() {
147          if (&quot;GA&quot;.equalsIgnoreCase(state)) {
148              if (&quot;GA_EA&quot;.equalsIgnoreCase(district)) {
149                  List&lt;Map&gt; list = new ArrayList&lt;Map&gt;();
150                  HashMap&lt;String, String&gt; map = new
HashMap&lt;String, String&gt;(7);
151                  map.put(&quot;name&quot;, &quot;School One&quot;);
152                  map.put(&quot;city&quot;, &quot;City One&quot;);
153                  map.put(&quot;state&quot;, &quot;GA&quot;);
154                  list.add(map);
155  
156                  map = new HashMap&lt;String, String&gt;(7);
157                  map.put(&quot;name&quot;, &quot;School 2&quot;);
158                  map.put(&quot;city&quot;, &quot;City 2&quot;);
159                  map.put(&quot;state&quot;, &quot;GA&quot;);
160                  list.add(map);
161                  map = new HashMap&lt;String, String&gt;(7);
162                  map.put(&quot;name&quot;, &quot;School 3&quot;);
163                  map.put(&quot;city&quot;, &quot;City 3&quot;);
164                  map.put(&quot;state&quot;, &quot;GA&quot;);
165                  list.add(map);
166                  map = new HashMap&lt;String, String&gt;(7);
167                  map.put(&quot;name&quot;, &quot;School 4&quot;);
168                  map.put(&quot;city&quot;, &quot;City 4&quot;);
169                  map.put(&quot;state&quot;, &quot;GA&quot;);
170                  list.add(map);
171                  map = new HashMap&lt;String, String&gt;(7);
172                  map.put(&quot;name&quot;, &quot;School 5&quot;);
173                  map.put(&quot;city&quot;, &quot;City 5&quot;);
174                  map.put(&quot;state&quot;, &quot;GA&quot;);
175                  list.add(map);
176                  map = new HashMap&lt;String, String&gt;(7);
177                  map.put(&quot;name&quot;, &quot;School 6&quot;);
178                  map.put(&quot;city&quot;, &quot;City 6&quot;);
179                  map.put(&quot;state&quot;, &quot;GA&quot;);
180                  list.add(map);
181                  map = new HashMap&lt;String, String&gt;(7);
182                  map.put(&quot;name&quot;, &quot;School 7&quot;);
183                  map.put(&quot;city&quot;, &quot;City 7&quot;);
184                  map.put(&quot;state&quot;, &quot;GA&quot;);
185                  list.add(map);
186  
187                  schTable.setRowList(list);
188              }
189          }
190  
191          if (&quot;CA&quot;.equalsIgnoreCase(state)) {
192              if (&quot;CA_AL&quot;.equalsIgnoreCase(district)) {
193                  List&lt;Map&gt; list = new ArrayList&lt;Map&gt;();
194                  HashMap&lt;String, String&gt; map = new
HashMap&lt;String, String&gt;(7);
195                  map.put(&quot;name&quot;, &quot;1 school&quot;);
196                  map.put(&quot;city&quot;, &quot;1 city&quot;);
197                  map.put(&quot;state&quot;, &quot;ca&quot;);
198                  list.add(map);
199  
200                  map = new HashMap&lt;String, String&gt;(7);
201                  map.put(&quot;name&quot;, &quot;2 School 2&quot;);
202                  map.put(&quot;city&quot;, &quot;2 City 2&quot;);
203                  map.put(&quot;state&quot;, &quot;CA&quot;);
204                  list.add(map);
205                  map = new HashMap&lt;String, String&gt;(7);
206                  map.put(&quot;name&quot;, &quot;3 School 3&quot;);
207                  map.put(&quot;city&quot;, &quot;3 City 3&quot;);
208                  map.put(&quot;state&quot;, &quot;CA&quot;);
209                  list.add(map);
210                  map = new HashMap&lt;String, String&gt;(7);
211                  map.put(&quot;name&quot;, &quot;4 School 4&quot;);
212                  map.put(&quot;city&quot;, &quot;4 City 4&quot;);
213                  map.put(&quot;state&quot;, &quot;CA&quot;);
214                  list.add(map);
215                  map = new HashMap&lt;String, String&gt;(7);
216                  map.put(&quot;name&quot;, &quot;5 School 5&quot;);
217                  map.put(&quot;city&quot;, &quot;5 City 5&quot;);
218                  map.put(&quot;state&quot;, &quot;CA&quot;);
219                  list.add(map);
220                  map = new HashMap&lt;String, String&gt;(7);
221                  map.put(&quot;name&quot;, &quot;6 School 6&quot;);
222                  map.put(&quot;city&quot;, &quot;6 City 6&quot;);
223                  map.put(&quot;state&quot;, &quot;CA&quot;);
224                  list.add(map);
225                  map = new HashMap&lt;String, String&gt;(7);
226                  map.put(&quot;name&quot;, &quot;7 School 7&quot;);
227                  map.put(&quot;city&quot;, &quot;7 City 7&quot;);
228                  map.put(&quot;state&quot;, &quot;CA&quot;);
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    &lt;html&gt;
4    &lt;head&gt;
5        &lt;title&gt;Stateful Choice&lt;/title&gt;
6        $imports
7    
8    &lt;/head&gt;
9    &lt;body&gt;
10       &lt;!-- again, if not a form, you can use client side javascript to
update server page with option data --&gt;
11       $form
12       $schools
13   
14   &lt;/body&gt;
15   &lt;/html&gt;
</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.

Reply via email to