How to pass bean action/listener method via <ui:param> of <ui:include>
Asked Answered
M

1

5

I'm using <ui:include> to load a data table (I'm using Primefaces). I want use <ui:param> in the listener into the tag <p:ajax>. I tested the code that is down, but not trigger the event onRowEdit or onRowCancel. This is my page:

...
<ui:include src="../Componentes/tablaEditable.xhtml">
     <ui:param name="columnas" value="#{tabla2FuentesHL7.dataTableColumns}" />
     <ui:param name="bean" value="#{tabla2FuentesHL7.listTabla2FuenteDTO}" />
     <ui:param name="aceptarEdicion" value="#{tabla2FuentesHL7.onRowEdit}" />
     <ui:param name="cancelarEdicion" value="#{tabla2FuentesHL7.onRowCancel}" />
</ui:include>
...

My data table:

<ui:composition 
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">

<h:form >
    <p:dataTable value="#{bean}"  scrollable="true"  scrollHeight="100" var="dato" editable="true">
        <p:ajax event="rowEdit" listener="#{aceptarEdicion}"  />
        <p:ajax event="rowEditCancel" listener="#{cancelarEdicion}"  />
        <c:forEach items="#{columnas}" var="column" varStatus="loop">
            <p:column headerText="#{column.header}" sortBy="#{dato[column.property]}">
                <p:cellEditor>
                    <f:facet name="output">
                        <h:outputText value="#{dato[column.property]}" />
                    </f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{dato[column.property]}" style="width:100%"  />
                    </f:facet>
                </p:cellEditor>     
            </p:column>
        </c:forEach> 
        <p:column style="width:32px">
            <p:rowEditor />
        </p:column>
    </p:dataTable>
</h:form>

My bean:

@ManagedBean(name = "tabla2FuentesHL7")
@ViewScoped
enter code herepublic class Tabla2FuentesHL7 {

private static final long serialVersionUID = 1L;
private List<DataTableColumn> dataTableColumns = new ArrayList<DataTableColumn>();
private List<Tabla2FuenteDTO> listTabla2FuenteDTO = new ArrayList<Tabla2FuenteDTO>();

@PostConstruct
public void init() {

    listTabla2FuenteDTO = Test.getFuenteTabla2();
    dataTableColumns = CargarTablas.getTabla2FuenteHL7();

}

public List<Tabla2FuenteDTO> getListTabla2FuenteDTO() {
    return listTabla2FuenteDTO;
}

public List<DataTableColumn> getDataTableColumns() {
    return dataTableColumns;
}

public void onRowEdit(RowEditEvent event) {
    FacesMessage msg = new FacesMessage("Elemento modificado");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

public void onRowCancel(RowEditEvent event) {
    FacesMessage msg = new FacesMessage("Modificación cancelada");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

public void onCellEdit(CellEditEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();

    if (newValue != null && !newValue.equals(oldValue)) {
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

}

This is the error:

javax.el.PropertyNotFoundException: /Componentes/tablaEditable.xhtml @12,76 listener="#{cancelarEdicion}": /Modulos/hl7.xhtml @31,104 value="#{tabla2FuentesHL7.onRowCancel}": The class 'com.queres.xedoc.consola.componentes.Tabla2FuentesHL7' does not have the property 'onRowCancel'.

If I change this:

<p:ajax event="rowEdit" listener="#{aceptarEdicion}"  />
        <p:ajax event="rowEditCancel" listener="#{cancelarEdicion}"  />

for this:

        <p:ajax event="rowEdit" listener="#{tabla2FuentesHL7.onRowEdit}"  />
        <p:ajax event="rowEditCancel" listener="#{tabla2FuentesHL7.onRowCancel}"  />

my code works fine, but I need a dynamic data table. Is there any way to pass a parameter to the listener? Thanks!

Maser answered 17/3, 2015 at 16:40 Comment(0)
W
11

The <ui:param> can only pass value expressions, not method expressions.

Better make use of the ability of EL to parameterize method names via brace [] notation. Then you can just declare the method names as plain vanilla String.

<ui:include src="../Componentes/tablaEditable.xhtml">
     ...
     <ui:param name="beanEdicion" value="#{tabla2FuentesHL7}" />
     <ui:param name="aceptarEdicion" value="onRowEdit" />
     <ui:param name="cancelarEdicion" value="onRowCancel" />
</ui:include>
<p:ajax event="rowEdit" listener="#{beanEdicion[aceptarEdicion]()}"  />
<p:ajax event="rowEditCancel" listener="#{beanEdicion[cancelarEdicion]()}"  />

Update as per the comments, it appears to still not work in PrimeFaces 5.1 even though the related issue says that it's already fixed in 3.5. You'd basically need to reopen the issue.

In the meanwhile, you can workaround this with help of <o:methodParam> tag of JSF utility library OmniFaces. This basically converts a value expression to a method expression:

<ui:include src="../Componentes/tablaEditable.xhtml">
         ...
     <ui:param name="aceptarEdicion" value="#{tabla2FuentesHL7.onRowEdit}" />
     <ui:param name="cancelarEdicion" value="#{tabla2FuentesHL7.onRowCancel}" />
</ui:include>
<o:methodParam name="aceptarEdicionParam" value="#{aceptarEdicion}" />
<o:methodParam name="cancelarEdicionParam" value="#{cancelarEdicion}" />
...
<p:ajax event="rowEdit" listener="#{aceptarEdicionParam}"  />
<p:ajax event="rowEditCancel" listener="#{cancelarEdicionParam}"  />
Wolford answered 17/3, 2015 at 17:11 Comment(13)
Thanks for your reply, but I am not able to make it work. Now I have this error: javax.el.PropertyNotFoundException: Target Unreachable, identifier 'beanEdicion' resolved to nullMaser
Which PF version? This is a known issue in <p:ajax> and should already be fixed in 5.x. See also related question: #10692136Wolford
I'm using JSF 2.1.11 and Primefaces 5.1. Thanks again :)Maser
Mojarra 2.1.11 is rather old (almost 3 years already!). Can you try 2.1.29? That should bring a lot of bug fixes and performance improvements along.Wolford
I upgraded my JSF version and still the same error. Anyway , thanks for the advice ;)Maser
I'm using Glassfish 2.2 . Could have something to do with the problem ?Maser
@BalusC: Did you reset your reputation or was it an overflow ;-)Phelloderm
GlassFish 2.2? Did you doublecheck the version number? Isn't it 3.1.2.2?Wolford
@BalusC: I tried with Glassfish Server 4.0, and the error is the same. Any idea? Thanks for allMaser
Awkward, it appears that this is not properly fixed in PrimeFaces side as indicated by recent comments on issue 4075. Do you use the utility library OmniFaces, or are you open to using it? It offers a <o:methodParam> which would be the alternative solution. It basically converts a value expression supplied via <ui:param> or tag attribute to a true method expression.Wolford
@Wolford If I can keep using Primefaces and his data table, I would have no problem with OmniFaces. I'll try. Thanks :)Maser
It's an utility library, offering helper components, tags, functions and classes. It works fine together with PrimeFaces.Wolford
@Wolford I used OmniFaces and it worked well . Thank you very much ! I will upload the code with the solution.Maser

© 2022 - 2024 — McMap. All rights reserved.