You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Mike Quentel <mq...@4dm-inc.com> on 2009/05/22 17:09:08 UTC

synchronising selectOneChoice and table

Using JSF 1.2 and Trinidad...

Having issues syncing selectOneChoice and table values; I would like to have
the user's selection from the selectOneChoice to dynamically update the data
appearing in a table on the same page.  Having issues syncing these items; I
also wonder if there is a better approach than what I'm trying to currently
use...still new to JSF.

I have a table <tr:table> that gets populated via a SQL query whose results
fill a Vector of Hashtables, where key=column name and value=value for that
column.  In other words, each Hashtable represents a row from the query.  

A backend java bean Data Access Object does the assembly of Hashtable
objects into a Vector in this manner: 

        Statement statement = dbConnection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()) {
          Hashtable<String, String> rowHt = new Hashtable<String, String>();
          for (int i = 1; i < resultSet.getMetaData().getColumnCount(); i++)
{
            String fn = resultSet.getMetaData().getColumnName(i);
            Object rslt = resultSet.getObject(i);
            String rsltString = "";
            if (rslt != null) {
              rsltString = rslt.toString();
            } else {
              rsltString = "";
            }
            rowHt.put(fn, rsltString);
          }
          result.add(rowHt);
        }
        statement.close();

The Façade Backing Bean then provides the Vector to the JSF page via this
method: 

  public Vector<Hashtable> getPropertyRights(){
    if (this.propertyRights == null) {
      this.propertyRights = new PropertyRights().getPropertyRights();
    }
    return this.propertyRights;
  }

The JSF table output looks like this: 

        <tr:table value="#{propertyRightBean.propertyRights}" var="row"
rowBandingInterval="1">
          <tr:column headerText="Station" sortProperty="station_name"
sortable="true">
            <tr:outputText value="#{row.station_name}"></tr:outputText>
          </tr:column>
          <tr:column headerText="River System" sortProperty="river_system"
sortable="true">
            <tr:outputText value="#{row.river_system}"></tr:outputText>
          </tr:column>
         ...
        </tr:table>

Additionally, there are selectOneChoice <tr:selectOneChoice> items that are
dynamically populated: 

<tr:selectOneChoice label="Station" id="stationSelectOneChoice"
valueChangeListener="#{propertyRightBean.setSelectedStationListener}"
autoSubmit="true" immediate="true">
  <f:selectItems value="#{propertyRightBean.stationOptions}"/>
</tr:selectOneChoice>
<tr:selectOneChoice label="Property Type" id="propertyTypeSelectOneChoice"
unselectedLabel="(all)"
valueChangeListener="#{propertyRightBean.setSelectedPropertyTypeListener}"
autoSubmit="true" immediate="true">
  <f:selectItems value="#{propertyRightBean.propertyTypeOptions}"/>
</tr:selectOneChoice>

In order to provide the options for each selectOneChoice, the Façade Backing
Bean uses the following: 

    private ArrayList<SelectItem> propertyTypeOptions = null;
    private ArrayList<SelectItem> stationOptions = null;

    public ArrayList<SelectItem> getPropertyTypeOptions() {
      this.propertyTypeOptions =
getPopulatedOptions(this.propertyTypeOptions, "property_type");
      return this.propertyTypeOptions;
    }

    public ArrayList<SelectItem> getStationOptions() {
      this.stationOptions = getPopulatedOptions(this.stationOptions,
"station_name");
      return this.stationOptions;
    }

  public ArrayList<SelectItem> getPopulatedOptions(ArrayList<SelectItem>
options, String hashKey) {
    if (options == null) {
      options = new ArrayList<SelectItem>();
    } else {
      options.clear();
    }
    for (int i = 0; i < propertyRights.size(); i++) {
      SelectItem si = new SelectItem();
      Object valueObj = propertyRights.get(i).get(hashKey);
      String value = null;
      if (valueObj != null) {
        value = propertyRights.get(i).get(hashKey).toString();
      } else {
        value = "9999";
      }
      si.setLabel(value);
      si.setValue(value);
      options.add(si);
    }
    return options;
  }

So, what I'm trying to do is make it so when the user selects an item in any
selectOneChoice list, that after the on-select event, the selected value is
used to do a query against the database (ie, the selected value becomes part
of a where clause).  Perhaps this might be better done via a query against a
table in memory (the Vector of Hashtables)?

I'm beginning to suspect this approach is un-optimal at best and wrong at
worst...need advice, please.  I do not understand how to bind the
controls...but would the "binding" tag attribute for selectOneChoice, or for
table, be a better way to sync these items based on user selections?  Do you
have an example of this sort of functionality (ie, user selecting a choice,
then the selection causing a table to be updated)?

Many thanks for your advice on this.

Cheers,

Mike Quentel



RE: synchronising selectOneChoice and table

Posted by Mike Quentel <mq...@4dm-inc.com>.
Thank you for the advice.

I used the information on Partial Page Rendering (PPR) information described
at 

http://myfaces.apache.org/trinidad/devguide/ppr.html

In particular, using the partialTriggers attribute in the table tag to
specify which selectOneChoice IDs that the table depends on.

I mistakenly thought that "PPR" was only a feature of being able to use AJAX
to submit part of the page; PPR actually refers to the kind of functionality
I was attempting to do in synchronising the selectOneChoice items with the
table.  Perhaps this section of the Developer Guide should include the words
"synchronising widget events and dependencies"; just my opinion....

Also, I store a separate collection to represent the table, based on queries
that filter via the selectOneChoice events.

Thanks,

Mike Quentel

-----Original Message-----
From: Marco G 
Sent: 22 May 2009 13:53
To: users@myfaces.apache.org
Subject: Re: synchronising selectOneChoice and table



Mike Quentel-3 wrote:
> 
> <tr:selectOneChoice label="Station" id="stationSelectOneChoice"
> valueChangeListener="#{propertyRightBean.setSelectedStationListener}"
> autoSubmit="true" immediate="true">
>   <f:selectItems value="#{propertyRightBean.stationOptions}"/>
> </tr:selectOneChoice>
> <tr:selectOneChoice label="Property Type" id="propertyTypeSelectOneChoice"
> unselectedLabel="(all)"
> valueChangeListener="#{propertyRightBean.setSelectedPropertyTypeListener}"
> autoSubmit="true" immediate="true">
>   <f:selectItems value="#{propertyRightBean.propertyTypeOptions}"/>
> </tr:selectOneChoice>
> 

You didn't provide the methods, which are called by the
valueChangeListeners. You either have to call
"RequestContext.getCurrentInstance().addPartialTarget(UIComponent);" there
or add partialTriggers-attribute to the tr:table to get the table refreshed
by change of the selectOneChoice.
-- 
View this message in context:
http://www.nabble.com/synchronising-selectOneChoice-and-table-tp23672409p236
75286.html
Sent from the MyFaces - Users mailing list archive at Nabble.com.


Re: synchronising selectOneChoice and table

Posted by Marco Grimm-2 <Ma...@rz-service-mannheim.de>.

Mike Quentel-3 wrote:
> 
> <tr:selectOneChoice label="Station" id="stationSelectOneChoice"
> valueChangeListener="#{propertyRightBean.setSelectedStationListener}"
> autoSubmit="true" immediate="true">
>   <f:selectItems value="#{propertyRightBean.stationOptions}"/>
> </tr:selectOneChoice>
> <tr:selectOneChoice label="Property Type" id="propertyTypeSelectOneChoice"
> unselectedLabel="(all)"
> valueChangeListener="#{propertyRightBean.setSelectedPropertyTypeListener}"
> autoSubmit="true" immediate="true">
>   <f:selectItems value="#{propertyRightBean.propertyTypeOptions}"/>
> </tr:selectOneChoice>
> 

You didn't provide the methods, which are called by the
valueChangeListeners. You either have to call
"RequestContext.getCurrentInstance().addPartialTarget(UIComponent);" there
or add partialTriggers-attribute to the tr:table to get the table refreshed
by change of the selectOneChoice.
-- 
View this message in context: http://www.nabble.com/synchronising-selectOneChoice-and-table-tp23672409p23675286.html
Sent from the MyFaces - Users mailing list archive at Nabble.com.