Board index JavaServer Faces General Newbie alert: multiple selectionMode not working?

Newbie alert: multiple selectionMode not working?

Components, Ajax Framework, Utilities and More.


Posts: 10
Hello,

I'm using Netbeans 6.9 / Glassfish 3.0.1 / Mojarra 2.0.2 (FCS b10) / PrimeFaces 2.2RC2-SNAPSHOT (10/11/2010) / Google Chrome 9.0.576.0.

I'm trying to use a dataTable with multiple selectionMode with checkboxes. The table appears correctly, I can make selections (the checkboxes are selected), but the selection is not sent to the server... Obviously something is wrong.

This is what I get after clicking the view button:
Image

This is what Fiddler sees:
Image

This is my xhtml code. It is basically the code from the showcase example. I only added the <html>, <h:head>, <h:body> tags and removed the radiobutton selection example code.

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.prime.com.tr/ui">

    <h:head>
        <title>PrimefacesTest</title>
        <link type="text/css" rel="stylesheet" href="resources/skins/redmond/skin.css" />
    </h:head>

    <h:body>

 <h:form prependId="false">

    <p:dataTable var="car" value="#{tableBean2.cars}" paginator="true" rows="10"
                 selection="#{tableBean2.selectedCars}">

        <f:facet name="header">
            Checkbox Based Selection
        </f:facet>

        <p:column selectionMode="multiple" />

        <p:column headerText="Model">
            <h:outputText value="#{car.model}" />
        </p:column>

        <p:column headerText="Year">
            <h:outputText value="#{car.year}" />
        </p:column>

        <p:column headerText="Manufacturer">
            <h:outputText value="#{car.manufacturer}" />
        </p:column>

        <p:column headerText="Color">
            <h:outputText value="#{car.color}" />
        </p:column>

        <f:facet name="footer">
            <p:commandButton value="View" image="ui-icon ui-icon-search"
                             update="displayMulti" oncomplete="multiCarDialog.show()"/>
        </f:facet>
    </p:dataTable>

    <p:dialog header="Car Detail" widgetVar="multiCarDialog"
              width="250" height="300" showEffect="explode" hideEffect="explode">

        <p:dataList id="displayMulti"
                value="#{tableBean2.selectedCars}" var="selectedCar">
            Model: #{selectedCar.model}, Year: #{selectedCar.year}
        </p:dataList>

    </p:dialog>

</h:form>
     
    </h:body>
</html>


This is my java code. It is basically the code from the showcase example. I only added the ManagedBean and ViewScoped annotations.

package org.primefaces.examples.view;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.primefaces.examples.domain.Car;

@ManagedBean(name="tableBean2")
@ViewScoped
public class TableBean2 implements Serializable {

   private final static String[] colors;

   private final static String[] manufacturers;

   static {
      colors = new String[10];
      colors[0] = "Black";
      colors[1] = "White";
      colors[2] = "Green";
      colors[3] = "Red";
      colors[4] = "Blue";
      colors[5] = "Orange";
      colors[6] = "Silver";
      colors[7] = "Yellow";
      colors[8] = "Brown";
      colors[9] = "Maroon";

      manufacturers = new String[10];
      manufacturers[0] = "Mercedes";
      manufacturers[1] = "BMW";
      manufacturers[2] = "Volvo";
      manufacturers[3] = "Audi";
      manufacturers[4] = "Renault";
      manufacturers[5] = "Opel";
      manufacturers[6] = "Volkswagen";
      manufacturers[7] = "Chrysler";
      manufacturers[8] = "Ferrari";
      manufacturers[9] = "Ford";
   }

   private List<Car> cars;

   private Car selectedCar;

   private Car[] selectedCars;

   public TableBean2() {
      cars = new ArrayList<Car>();

      populateRandomCars(cars, 50);
   }

   public Car[] getSelectedCars() {
      return selectedCars;
   }
   public void setSelectedCars(Car[] selectedCars) {
      this.selectedCars = selectedCars;
   }

   public Car getSelectedCar() {
      return selectedCar;
   }

   public void setSelectedCar(Car selectedCar) {
      this.selectedCar = selectedCar;
   }

   private void populateRandomCars(List<Car> list, int size) {
      for(int i = 0 ; i < size ; i++)
         list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));
   }

   public List<Car> getCars() {
      return cars;
   }

   private int getRandomYear() {
      return (int) (Math.random() * 50 + 1960);
   }

   private String getRandomColor() {
      return colors[(int) (Math.random() * 10)];
   }

   private String getRandomManufacturer() {
      return manufacturers[(int) (Math.random() * 10)];
   }

   private String getRandomModel() {
      return UUID.randomUUID().toString().substring(0, 8);
   }
}



There are a few strange things however:
* The exact same thing works in IE9 (but only when 'prependId="false' is set on the <form> tag).
* The showcase page works in Chrome and IE9.

Any suggestions?

Thxs,
E.


Posts: 723
Location: United States
You need to add a f:view tag to get good results in Chrome:

<html ...>
<f:view contentType="text/html">

//Your page here

</f:view>
</html>



Posts: 10
Hey thanks. Now it works :D Do you have any pointers to an explanation why this is needed? It's very nice that it works now, but I would like to know why ;)

Thanks again.


Posts: 10
OK, the reason why this is needed is mentioned in the primefaces user guide...

6. With facelets some components like charts do not work in Safari or Chrome but there's no problem with Firefox.
The common reason is the response mimeType when using with PrimeFaces with facelets.
You need to make sure responseType is "text/html".
With facelets you can use the <f:view contentType="text/html"> to enforce this setting.

And it is also mentioned in a post of Dec 15, 2009:
http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=930&start=0

I've added the <f:view> tag to my template.

eth

Posts: 4
Hello,

since I'm facing a similar problem and this thread isn't closed, I'm posting it here.

The situation:
I've copied the multiple selection (using a checkbox column) example from the showcase and it didn't work (empty selection array, regardless of any selected elements). After finding this thread I've added the f:view tag to my page, but the behavior didn't change.

The testing environment is GlassFish 3.1, JBoss 5.1 (pimped to support JSF 2), IE8, SRWare Iron 9 (based on Chromium just like Google Chrome), Firefox 3.6. All browsers showed the same behavior: the selection attribute in a request is empty.

The backing bean:
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class TableBean implements Serializable {

   public static class Car implements Serializable {

      private String model;
      private int year;
      private String manufacturer;
      private String color;

      public Car(String model, int year, String manufacturer, String color) {
         this.model = model;
         this.year = year;
         this.manufacturer = manufacturer;
         this.color = color;
      }

      /**
       * @return the model
       */
      public String getModel() {
         return model;
      }

      /**
       * @param model the model to set
       */
      public void setModel(String model) {
         this.model = model;
      }

      /**
       * @return the year
       */
      public int getYear() {
         return year;
      }

      /**
       * @param year the year to set
       */
      public void setYear(int year) {
         this.year = year;
      }

      /**
       * @return the manufacturer
       */
      public String getManufacturer() {
         return manufacturer;
      }

      /**
       * @param manufacturer the manufacturer to set
       */
      public void setManufacturer(String manufacturer) {
         this.manufacturer = manufacturer;
      }

      /**
       * @return the color
       */
      public String getColor() {
         return color;
      }

      /**
       * @param color the color to set
       */
      public void setColor(String color) {
         this.color = color;
      }
   }

   private final static String[]   colors;

   private final static String[]   manufacturers;

   static {
      colors = new String[10];
      colors[0] = "Black";
      colors[1] = "White";
      colors[2] = "Green";
      colors[3] = "Red";
      colors[4] = "Blue";
      colors[5] = "Orange";
      colors[6] = "Silver";
      colors[7] = "Yellow";
      colors[8] = "Brown";
      colors[9] = "Maroon";

      manufacturers = new String[10];
      manufacturers[0] = "Mercedes";
      manufacturers[1] = "BMW";
      manufacturers[2] = "Volvo";
      manufacturers[3] = "Audi";
      manufacturers[4] = "Renault";
      manufacturers[5] = "Opel";
      manufacturers[6] = "Volkswagen";
      manufacturers[7] = "Chrysler";
      manufacturers[8] = "Ferrari";
      manufacturers[9] = "Ford";
   }

   private List<Car> cars;

   private Car selectedCar;

   private Car[] selectedCars;

   public TableBean() {
      cars = new ArrayList<Car>();
      populateRandomCars(cars, 50);
   }

   public Car[] getSelectedCars() {
      return selectedCars;
   }

   public void setSelectedCars(Car[] selectedCars) {
      this.selectedCars = selectedCars;
   }

   public Car getSelectedCar() {
      return selectedCar;
   }

   public void setSelectedCar(Car selectedCar) {
      this.selectedCar = selectedCar;
   }

   private void populateRandomCars(List<Car> list, int size) {
      for (int i = 0; i < size; i++)
         list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));
   }

   public List<Car> getCars() {
      return cars;
   }

   private int getRandomYear() {
      return (int)(Math.random() * 50 + 1960);
   }

   private String getRandomColor() {
      return colors[(int)(Math.random() * 10)];
   }

   private String getRandomManufacturer() {
      return manufacturers[(int)(Math.random() * 10)];
   }

   private String getRandomModel() {
      return UUID.randomUUID().toString().substring(0, 8);
   }
}


The page:
<?xml version="1.0" encoding="UTF-8"?>
<html
    xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view contentType="text/html">
   <h:form prependId="false">

      <p:dataTable
         var="car"
         value="#{tableBean.cars}"
         rows="10"
         paginator="true"
         selection="#{tableBean.selectedCars}"
      >

         <f:facet name="header">
            Checkbox Based Selection
           </f:facet>

         <p:column selectionMode="multiple" />

         <p:column headerText="Model">
            <h:outputText value="#{car.model}" />
         </p:column>

         <p:column headerText="Year">
            <h:outputText value="#{car.year}" />
         </p:column>

         <p:column headerText="Manufacturer">
            <h:outputText value="#{car.manufacturer}" />
         </p:column>

         <p:column headerText="Color">
            <h:outputText value="#{car.color}" />
         </p:column>

         <f:facet name="footer">
            <p:commandButton value="View" image="ui-icon ui-icon-search" update="displayMulti" oncomplete="multiCarDialog.show()" />
         </f:facet>
      </p:dataTable>

      <p:dialog header="Car Detail" widgetVar="multiCarDialog" width="250" height="300" showEffect="explode" hideEffect="explode">
         <p:dataList id="displayMulti" value="#{tableBean.selectedCars}" var="selectedCar">
            Model: #{selectedCar.model}, Year: #{selectedCar.year}
           </p:dataList>
      </p:dialog>

   </h:form>
</f:view>
</html>


A clue to solve the problem would be appreciated.

Best regards,
eth


Posts: 723
Location: United States
The static inner class looks suspicious. I don't see any examples in the showcase using that either...

eth

Posts: 4
Hello bumble.bee,

thanks for your time.

I just moved the inner class into an own file, cleaned all caches (server and client), but it didn't help. What server is your showcase running on and what is the JSF-Code for this specific example? Does it really match the code available on the page? I'm asking because I simply copied the code and tried two application servers already.

Best regards,
eth


eth

Posts: 4
Hello again,

I found the error, yet I don't know why it is causing trouble. I simply added the following tag:
<h:head></h:head>


The table not only looks better (I didn't define any custom styles), it seems to be working perfectly well. I'm still on it, figuring out what's happening to fully understand the error.

Best regards,
eth


Posts: 723
Location: United States
Glad you figured it out.

The dataTable probably tries to attach styles and scripts to the head component and isn't robust enough to handle the situation where it hasn't been created.

Next

Return to General

cron