How to pass parameter to valueChangeListener in p:dataTable?

时光总嘲笑我的痴心妄想 提交于 2019-12-10 20:29:56

问题


I am calling valueChangeListener on a <h:selectBooleanCheckbox> which is inside a dataTable. and that dataTable is again inside another(outer) dataTable. In the valueChangeListener method I want the instance object of outer dataTable. Is there any way to get the object of outer dataTable instance?

EX:

<h:panelGroup id="panelId">
    <p:dataTable id="outerDatatable"
                 var="supplier"
                 value="bean.supplierList">

        <p:column>
            <f:facet name="header">
                <h:outputText value="Suppliers" />
            </f:facet>
            <h:outputText value="#{supplier.name}" />
        </p:column>

        <p:column>
            <p:dataTable id="innerDataTable"
                         var="supplierAccount"
                         value="supplier.supplierAccountList">

                <p:column>
                    <h:selectBooleanCheckbox id="booleanBoxId"
                                             value="#{supplierAccount.supported}"
                                             valueChangeListener="#bean.checkBoxListener}"
                                             immediate="true"
                                             onchange="this.form.submit();"/>
                </p:column>
            </p:dataTable>
        </p:column>
    </p:dataTable>
</h:panelGroup>

I found the following solution : I used <p:ajax> listener instead of valueChangeListener, and I could pass 'supplier' object as well as supplierAccount object to this listener method. We can pass any number of custom objects to <p:ajax> listener.

<p:column>
    <h:selectBooleanCheckbox id="booleanBoxId"
                             value="#{supplierAccount.supported}"
                             immediate="true">
    </h:selectBooleanCheckbox>

    <p:ajax listener="#{bean.myListenerMethod(supplier,supplierAccount)}"
            update=":formName:panelId"/>
</p:column>

回答1:


In this particular case, you could get it by evaluating the #{supplier} programmatically:

public void checkBoxListener(ValueChangeEvent event) {
    FacesContext context = FacesContext.getCurrentInstance();
    Supplier supplier = context.getApplication().evaluateExpressionGet(context, "#{supplier}", Supplier.class);
    // ...
}

However, this is plain ugly, you're synchronously submitting the entire form by onchange="submit()". I recommend to throw in some ajax for that.

<h:selectBooleanCheckbox value="#{supplierAccount.supported}">
    <f:ajax listener="#{bean.checkBoxListener}" render="???" />
</h:selectBooleanCheckbox>

(the render attribute is up to you)

with

public void checkBoxListener(AjaxBehavior event) {
    Boolean value = (Boolean) ((UIInput) event.getComponent()).getValue();
    FacesContext context = FacesContext.getCurrentInstance();
    Supplier supplier = context.getApplication().evaluateExpressionGet(context, "#{supplier}", Supplier.class);
    // ...
}

Or if your environment supports EL 2.2 and thus specifying method arguments in EL:

<h:selectBooleanCheckbox value="#{supplierAccount.supported}">
    <f:ajax listener="#{bean.checkBoxListener(component, supplier)}" render="???" />
</h:selectBooleanCheckbox>
public void checkBoxListener(UISelectBoolean checkbox, Supplier supplier) {
    boolean selected = checkbox.isSelected();
    // ...
}

See also:

  • When to use valueChangeListener or f:ajax listener?

Unrelated to the concrete problem, as to using onchange="submit()", it may be useful to know that onchange doesn't work as expected for checkboxes in IE6/7. It get only fired on every 2nd click. You rather want to use onclick="submit()" instead.




回答2:


I see that you forgot a brace ({) just before bean:

valueChangeListener="#{bean.checkBoxListener}" immediate="true" 

Also, since you're using Primefaces, you could use it's components(that if you use version 3): http://www.primefaces.org/showcase-labs/ui/selectBooleanCheckbox.jsf

It isn't necessary to use outputText if you use jsf 2:

<f:facet name="header">   
  Suppliers  
</f:facet>   

Also it isn't necessary to use f:facet because the column component has an attribute called headerText:

<p:column headerText="Suppliers">
    #{supplier.name}"
</p:column>

It's a lot simpler that way, isn't it?

PS: What's this? value="supplier.supplierAccountList" No #{ }?



来源:https://stackoverflow.com/questions/8382579/how-to-pass-parameter-to-valuechangelistener-in-pdatatable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!