Turgut Dsfadfa
Turgut Dsfadfa

Reputation: 795

Primefaces dynamic table property

How can i reach the subClass property of a variable. As you can see Primefaces example I can reach properties like Car.color, Car.shape but what I want to get is "Car.PriceInformations.Price". I tried car[column.property][column.subproperty] but it didnt worked. Must I use subtable or is there any better solution?

<p:dataTable id="cars" var="car" value="#{tableBean.carsSmall}" filteredValue="#{tableBean.filteredCars}">                      
    <p:columns value="#{tableBean.columns}" var="column" columnIndexVar="colIndex"   
                sortBy="#{car[column.property]}" filterBy="#{car[column.property]}">  
        <f:facet name="header">  
            #{column.header}  
        </f:facet>  

        #{car[column.property]}  
    </p:columns>  

</p:dataTable>

Upvotes: 2

Views: 2155

Answers (2)

erencan
erencan

Reputation: 3763

You can modify this BalusC answer according to your needs.

Basically you can extend SpringBeanFacesELResolver as you use it for EL resolver. However, EL resolver is looking for Spring Bean inside Spring Context. Source code give very good understanding what SpringBenFacesELResolver do.

Secondly you need javax.el.BeanELResolver to access managed bean values as descriped in BalusC answer. I use Java Reflections for this purpose. javax.el.BeanELResolver can be loaded inside SpringBeanFacesELResolver dynamicly at run tim then invoke SpringBeanFacesELResolver#getValue for nested properties just like in the referenced answer.

Here is the code:

public class ExtendedSpringELResolver extends SpringBeanFacesELResolver {

@Override
public Object getValue(ELContext context, Object base, Object property)
{
    if (property == null || base == null || base instanceof ResourceBundle || base instanceof Map || base instanceof Collection) {
        return null;
    }

    String propertyString = property.toString();

    if (propertyString.contains(".")) {
        Object value = base;
        Class []params=  new Class[]{ELContext.class,Object.class,Object.class};
        for (String propertyPart : propertyString.split("\\.")) {

            Class aClass = BeanELResolver.class;

            try {
                Method getValueMethod = aClass.getDeclaredMethod("getValue",params );
                value = getValueMethod.invoke(aClass.newInstance(), context, value, propertyPart);
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InstantiationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        return value;
    }
    else {
        return super.getValue(context, base, property);
    }

}

}

P.S. I tried the code with the example in PrimeFaces showcase. I change String color to Color color where Color is a user defined class for my case which has only a String proporty. I access the values by adding color.color to columns list.

private String columnTemplate = "model manufacturer year color.color";

Upvotes: 1

klimpond
klimpond

Reputation: 766

If the only collection in your table bean is TableBean#carsSmall, then don't use <p:columns> in your JSF page.

<p:dataTable var="car" value="#{tableBean.carsSmall}>
   <p:column headerText="Car brand">
      <h:outputText value="#{car.manufacturer.name}" />
   </p:column>
   <p:column headerText="Color">
      <h:outputText value="#{car.color.name}" />
      <h:outputText value="#{car.color.code}" />
   </p:column>
</p:dataTable>

And don't forget to create proper getters and setters in your TableBean, Manufacturer and Color classes (as your classes will have different names).

Upvotes: 0

Related Questions