1

I'm using <p:dataTable> and in a <p:column> I have a <p:commandButton> that must be disabled in one condition that is specified in the bean.

Here's the form:

<p:dataTable var="flusso" id="flussoList" rows="5"
            widgetVar="flussoTable" value="#{invioFlussiTUManagedBean.flussi}"
            filteredValue="#{invioFlussiTUManagedBean.filteredFlussi}"
            emptyMessage="#{i18n['tu.msg.emptysearch']}" paginator="true"
            paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">

     <p:column style="width:100px;height:35px;">

             <p:commandButton
                        update=":invioFlForm:flussoList :invioFlForm:displayConfirm"
                        icon="ui-icon-extlink" oncomplete="confirmation.show()"
                        title="#{i18n['tu.button.flusso.invia']}"
                        rendered="#{flusso.statoFlusso.code == 'DS'}"
                        disabled="#{!invioFlussiTUManagedBean.dettaglio}">
                        <f:setPropertyActionListener value="#{flusso}"
                            target="#{invioFlussiTUManagedBean.selectedFlusso}" />
                        <f:setPropertyActionListener value="#{false}"
                            target="#{invioFlussiTUManagedBean.modoInvioTutti}" />
            </p:commandButton>
     </p:column>
</p:dataTable>

In my ManagedBean:

public boolean isDettaglio() {
    return flussiTURepository.isDettaglio(selectedFlusso);
}

This method queries the database and returns true or false depending if selectedFlusso responds to a condition.

The issue is this: in the method isDettaglio(), selectedFlusso is initialized in the f:setPropertyActionListener. When the method is called, selectedFlusso is null. How do I set selectedFlusso so that in the disabled attribute of <p:commandButton> is not null?

Gaetano Tortora
  • 105
  • 1
  • 5
  • 8
  • 1
    Your question is confusing. The code snippets and the description in the question does not seem to match each other. Do you actually mean the one and the same thing with `isDettaglio` and `disableDettaglio`? If so, why don't you have just a `disabled="#{flusso.dettaglio}"`? – BalusC Mar 18 '13 at 16:36
  • You're right, sorry! I did some tests and I have not restored the original. disableDettaglio in reality is dettaglio like this: disabled="#{!invioFlussiTUManagedBean.dettaglio}"> – Gaetano Tortora Mar 18 '13 at 16:52

2 Answers2

2

The <f:setPropertyActionListener> is not invoked when the HTML representation of the button is rendered, as you seem to expect. Instead, it is only invoked when the form is submitted via the button in question and its action is been queued.

If you want to continue using this strange design — I'd have just used

disabled="#{!flusso.dettaglio}"

instead —, then your best bet is to programmatically evaluate #{flusso} inside the getter.

public boolean isDettaglio() {
    FacesContext context = FacesContext.getCurrentInstance();
    Flusso currentFlusso = context.getApplication().evaluateExpressionGet(context, "#{flusso}", Flusso.class);
    return flussiTURepository.isDettaglio(currentFlusso);
}

Note that if your environment would support the new EL 2.2 feature of invoking methods with arguments, then you could just use

disabled="#{!invioFlussiTUManagedBean.isDettaglio(flusso)}"

See also How to call a method with a parameter in JSF.

Regardless of the solution based on the current design, this design is "strange", because it's potentially very expensive. See also Why JSF calls getters multiple times.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for your answer. Can you tell me how can I allow my environment to support the new EL 2.2? – Gaetano Tortora Mar 18 '13 at 17:24
  • Click the "See also" link. It isn't included for decoration purposes :) – BalusC Mar 18 '13 at 17:27
  • Great answer @BalusC !! I always end up adding managed beans inside another managed bean just to get a hold of a single variable or expression , evaluateExpression is a wonderful alternative for some scenarios. – Avinash Singh Mar 18 '13 at 17:30
  • @Avinash: if you happen to use OmniFaces; it's also available via the easier-to-use `Faces.evaluateExpressionGet("#{flusso}")` utility. See also [showcase](http://showcase.omnifaces.org/utils/Faces). – BalusC Mar 18 '13 at 17:32
  • @BalusC : Omnifaces is my go-to util library for JSF. I especially use it for validators . I wonder if there is any harm in adding name as Faces.getManagedBean() . It makes code look simpler , some of my team doesn't understand 'evaluateExpression'. – Avinash Singh Mar 18 '13 at 18:14
  • Interpret it as: "evaluate the given EL expression in the current EL scope and return the result". E.g. `Faces.evaluateExpressionGet("#{1 + 1}")` would return 2. It's just reusable for more purposes than just returning a bean by name. – BalusC Mar 18 '13 at 18:17
0

You could use something like that

<p:commandButton disabled=#{!invioFlussiTUManagedBean.isDettaglio(flusso)}

and in your bean:

public boolean isDettaglio(Flusso selectedFlusso) {
    return flussiTURepository.isDettaglio(selectedFlusso);
}
phoenix7360
  • 2,807
  • 6
  • 30
  • 41
  • Noted should be that this works in Servlet 3.0 / EL 2.2 only and it's not clear from OP's question if he is using that. JSF 2.x is namely backwards compatible with Servlet 2.5 and EL 2.1. You should never assume EL 2.2 to be always present in JSF 2.x, unless otherwise indicated by the question or the code snippets (which does not seem to be the case anywhere in this particular case). – BalusC Mar 18 '13 at 16:38
  • according to your suggestion, I have the following exception: 18.03.2013 18:01:52 *ERROR* DefaultExceptionHandler: handleUnexpected - An unexpected internal error has occurred - (DefaultExceptionHandler.java, line 119) javax.faces.view.facelets.TagAttributeException: /tu/invio-flussi-tu.xhtml @77,68 disabled="#{!invioFlussiTUManagedBean.isDettaglio(flusso)}" Error Parsing: #{!invioFlussiTUManagedBean.isDettaglio(flusso)} – Gaetano Tortora Mar 18 '13 at 17:04
  • Your environment doesn't support EL 2.2, as predicted by my comment, and this answer is therefore useless/unhelpful to you :) – BalusC Mar 18 '13 at 17:05
  • Thanks. I'll wait for other answers! – Gaetano Tortora Mar 18 '13 at 17:15
  • Even more, 5 minutes before you posted your comment, I've already posted an answer. – BalusC Mar 18 '13 at 17:18