Hobione's Weblog

Living & Breathing in Web 2.0 Era

dataTable and radio button in JSF

Scenerio: Wanted to render the same radio button group for all rows in the table so that only one button can be selected at a time.  There seem to be no easy solution to that simple problem!

DataTable and RadioButton

Reason: The above plan apparently doesn’t work, because <h:selectOneRadio> renders an HTML “table” by itself, and that “messes up” the other “table” that the <h:dataTable> tag renders.

Solution:  One work around would be to use TomaHawk but instead of mixing two JSF implementations I went ahead to use command link.

Commnad Link2nd SoulutionThe key to getting this to work is to define the selectOneRadio component outside of the table. Then by setting the layout attribute to spread and using the ice:radio components inside the dataTable it gives you the rough layout/functionality.


<h2>Main Page</h2>
<ice:form>
 <ice:panelGroup id="tablePanel">

 <ice:selectOneRadio id="trainingClassRadio"
 value="#{testBean.selectedClass}"
 partialSubmit="true"
 valueChangeListener="#{testBean.radioChanged}"
 layout="spread">
 <f:selectItems value="#{testBean.radioItems}"/>
 </ice:selectOneRadio>

 <ice:dataTable var="class" value="#{testBean.trainingClassList}"
 varStatus="classStatus">
 <ice:column>
 <f:facet name="header">
 <ice:outputText value=""/>
 </f:facet>
 <ice:radio for="trainingClassRadio"
 index="#{classStatus.index}"/>
 </ice:column>

 <ice:column>
 <f:facet name="header">
 <ice:outputText value="Class Name"/>
 </f:facet>
 <ice:outputText value="#{class.className}"/>
 </ice:column>
 <ice:column>
 <f:facet name="header">
 <ice:outputText value="Class Number"/>
 </f:facet>
 <ice:outputText value="#{class.classNum}"/>
 </ice:column>
 <ice:column>
 <f:facet name="header">
 <ice:outputText value="Class Description"/>
 </f:facet>
 <ice:outputText value="#{class.classDesc}"/>
 </ice:column>
 </ice:dataTable>
 </ice:panelGroup>

 <ice:panelGrid columns="2">
 <ice:outputText value="Selected Row - Class Name:"/>
 <ice:outputText value="#{testBean.selectedTraining.className}"/>
 <ice:outputText value="Selected Row - Class Number:"/>
 <ice:outputText value="#{testBean.selectedTraining.classNum}"/>
 <ice:outputText value="Selected Row - Class Description"/>
 <ice:outputText value="#{testBean.selectedTraining.classDesc}"/>
 </ice:panelGrid>

 </ice:form>

Advertisements

May 29, 2009 Posted by | Java Server Faces | 13 Comments

JSF: f:selectItem vs. javax.faces.model.SelectItem

Let me explain what works and then I will tell you what not works. ListModel has a list type of javax.faces.model.SelectItem:


public class TrainingSessionsListModel extends ListModel{

 private List<SelectItem> availableSlotSelectItems;

 public List<SelectItem> getSessionNumberSelectItems() {

 if (this.sessionNumberSelectItems == null){
    sessionNumberSelectItems = new ArrayList();
    for(int i = 100; i < 1000; i++){
       SelectItem selectItem = new SelectItem(i,Integer.toString(i));
       sessionNumberSelectItems.add(selectItem);
    }
 }
 return sessionNumberSelectItems;
 }
 }

&#91;/sourcecode&#93;
<p style="margin-bottom:12pt;">xhtml now referring to the above list model class to get the list and set the value to TrainingSessionsDTO.sessionNumber property:</p>


<td>
 <ice:selectOneMenu id="sessionNumber" partialSubmit="true" value="#{
trainingSessionsListModel.TrainingSessionsDTO.sessionNumber}" required="true">

<f:selectItem itemLabel="#{msgs.select}" itemValue="" />
 <f:selectItems value="#{trainingSessionsListModel.sessionNumberSelectItems}"/>

 </ice:selectOneMenu></td>

Here is the transfer object with getter and setter.

 public class TrainingSessionsDTO extends TransferSupport implements Transfer,
 Serializable {

 String sessionNumber;

 //getter and setter .......

 }

sessionNumber

The above works fine, no problem but if I change the xhtml to these it wont work.

<ice:selectOneMenu id="sessionNumber" partialSubmit="true" value="#{
trainingSessionsListModel.TrainingSessionsDTO.sessionNumber}" required="true">
 <f:selectItem itemLabel="#{msgs.select}" itemValue="" />

 <f:selectItem itemLabel="100" value="100" />
 <f:selectItem itemLabel="200" value="200" />
 <f:selectItem itemLabel="300" value="300" />
 </ice:selectOneMenu></td>

Exception:
java.lang.String cannot be cast to javax.faces.model.SelectItem

Solution:

<f:selectItem itemLabel="100" itemValue="100" />
<f:selectItem itemLabel="200" itemValue="200" />
<f:selectItem itemLabel="300" itemValue="300" />

The value is meant to send in a SelectItem object and not a String. This should eliminate the exception you are seeing. Here is my beautiful finished work (form and datatable):
trainingsessionform

May 1, 2009 Posted by | Java Server Faces | 4 Comments