2
votes

Person can have only one car , but in the datatable I want to display all the cars in the list but select the one user person belongs to. This way user can update any person's car on the fly.

Let say I have two tables

Person

id 
name 
car_id

Cars

id
name

Ideally , person should have Cars id as primary key but that is not the case. So each person has car ,right.

Now I am displaying list of person in datatable e.g.

------------------------------------
Name | Car 
----------------------------------------
ABC | 1
DDD | 2

But I want to show like :

------------------------------------
Name | Car 
----------------------------------------
ABC | Toyota
DDD | Ford

The existing code :

<p:dataTable value="#{test.persons} var="person">
    <p:column headerText="Name"> 
        #{person.name}
    </p:column>
    <p:column headerText="Name"> 
        #{person.carID}
    </p:column>
</p:dataTable>

But I want to do something like:

<p:dataTable value="#{test.persons} var="person">
    <p:column headerText="Name"> 
        #{person.name}
    </p:column>
    <p:column headerText="Car">
        <p:selectOneMenu value="#{test.selectedCar}"
            converter="entityConverter">
            <f:selectItems value="#{spMBean.cars}" var="car" 
                itemLabel="#{car.name}" itemValue="#{car}" />
        </p:selectOneMenu>
    </p:column>
</p:dataTable>

If someone can help me with this, I'll highly appreciate that.

3
Are you using some ORM tool like Hibernate? Ideally , person should have Cars id as primary key but that is not the case. So each person has car ,right. I don't understand this statement, I think your model is correct. - Xtreme Biker
Yes , I am using JPA Hibernate. Actually, I have similiar tables ,even though Person has car id but it doesn't have primary key of Cars table as foriegn key. I know the database design is not right. - Makky
The model is denying the possibility of a person to have more than one car, it is desired? I believe that your model needs to be more refined ... - Lucas Oliveira
Thats right , A person should only have one car ,but I want users to be able to change the car from the list down box. - Makky
If each person has only one car, the model is correct. - Xtreme Biker

3 Answers

2
votes

You want to associate the selected car with the individual person.

However, you're binding the dropdown value to a generic backing bean property instead of to the invidivual person. All those dropdowns in all those rows in the same data table now point to one and same backing bean property. Upon submitting, the selected value of every single row will override each other until the backing bean property ends up with the selected value of the last row.

This doesn't make sense. You need to bind the dropdown value to the individual person.

<p:selectOneMenu value="#{person.car}">

This is easiest if Person entity has a private Car car property instead of a private Long carID. You can of course keep the available items in a separate bean.

2
votes

Based on BalusC answer . Here is the solution.

<p:dataTable value="#{test.persons} var="person">
    <p:column headerText="Name"> 
        #{person.name}
    </p:column>
    <p:column headerText="Car">
        <p:selectOneMenu value="#{person.carID}">
            <f:selectItems value="#{spMBean.cars}" var="car" 
                itemLabel="#{car.name}" itemValue="#{car.id}" />
        </p:selectOneMenu>
    </p:column>
</p:dataTable>

It will list the car names but display the one which a person has.

Thanks all for your answer.

1
votes

There are a couple of options.

The first is that you could change the member in your Person() class to take an instance of Car instead of an integer of carId:

public class Person {

    private String name;
    private Car car;
    }

So then your dataTable could look like this:

<p:dataTable value="#{test.persons} var="person">

                        <p:column headerText="Name"> 
                            <h:outputText value="#{person.name}" />
                            </p:column>

                        <p:column headerText="Car">
                            <h:outputText value="#{person.car.model}" />
                            </p:selectOneMenu>
                        </p:column>
                    </p:dataTable>

...assuming a Car pojo such as:

public class Car {

private String make;
private String model;
}

The second is that your could add a getCarById() method to your backing bean and use it in the DataTable.

So, in your page:

<p:dataTable value="#{test.persons} var="person">

                    <p:column headerText="Name"> 
                        <h:outputText value="#{person.name}" />
                        </p:column>

                    <p:column headerText="Car">
                        <h:outputText value="#{myBean.getCarById(person.carId).model}" />
                        </p:selectOneMenu>
                    </p:column>
                </p:dataTable>

and in your backing bean:

public Car getCarById(int carId) {
for(Car c: getAllMyCars() {
if(c.carId == carId) {
  return c;
}
return null;
}

Again, assuming a Car pojo such as:

public class Car {

private String make;
private String model;
}