Newbie alert: multiple selectionMode not working?

Components, Ajax Framework, Utilities and More.
esteevens
Posts: 10
Joined: 18 Oct 2010, 21:05

11 Nov 2010, 14:19

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.

Code: Select all

<?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.

Code: Select all

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.

User avatar
bumble.bee
Posts: 723
Joined: 29 Sep 2010, 21:39
Location: United States

11 Nov 2010, 15:49

You need to add a f:view tag to get good results in Chrome:

Code: Select all

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

//Your page here

</f:view>
</html>


esteevens
Posts: 10
Joined: 18 Oct 2010, 21:05

11 Nov 2010, 16:37

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.

esteevens
Posts: 10
Joined: 18 Oct 2010, 21:05

11 Nov 2010, 16:50

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/vi ... 30&start=0

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

eth
Posts: 4
Joined: 15 Mar 2011, 09:43

15 Mar 2011, 11:31

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:

Code: Select all

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:

Code: Select all

<?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

User avatar
bumble.bee
Posts: 723
Joined: 29 Sep 2010, 21:39
Location: United States

15 Mar 2011, 14:30

The static inner class looks suspicious. I don't see any examples in the showcase using that either...

eth
Posts: 4
Joined: 15 Mar 2011, 09:43

15 Mar 2011, 14:45

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

User avatar
bumble.bee
Posts: 723
Joined: 29 Sep 2010, 21:39
Location: United States

15 Mar 2011, 14:50

You should try to run the showcase on your environment. You can download it from here:

http://repository.prime.com.tr/org/prim ... APSHOT.war

Or in source form here:

http://www.primefaces.org/hudson/job/Ex ... kspace.zip

or here:

http://code.google.com/p/primefaces/source/checkout

eth
Posts: 4
Joined: 15 Mar 2011, 09:43

15 Mar 2011, 15:37

Hello again,

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

Code: Select all

<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

User avatar
bumble.bee
Posts: 723
Joined: 29 Sep 2010, 21:39
Location: United States

15 Mar 2011, 15:41

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.

Post Reply
  • Information
  • Who is online

    Users browsing this forum: Yahoo [Bot] and 11 guests