Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PrimeFaces p:blockUI blocking a certain component dynamically (on JSF EL condition)?

How do you make PrimeFaces p:blockUI block a certain component dynamically, that is on EL condition?

USE CASE:

The condition at hand is basically a mode that the user can be in on a page: if there are any exceeded collisions and they are currently shown at the users request then block the navigation tree (show exceeded collisions mode, nav tree blocked), otherwise we are in regular view and the navigation tree should be unblocked (show regular collisions mode, nav tree unblocked).

The problem currently is, that when in "exceeded mode", when a status change dialog changes the status to non-exceeded, the page renders/updates itself correctly back to regular mode, but the shadow on the navigation tree is still there. Since we're in regular mode now, I need some way to unblock if there are no more exceeded collisions.

Understood? :-)

OK, here's the bean property first:

/*
 * The logic of this method ensures that after status update the
 * mode is automatically put back into regular view if no followup
 * date exceeded collisions exist.
 */
public boolean isFollowupExceededCollisionsShown()
{
    return getFollowupExceededCount() > 0 ? this.followupExceededCollisionsShown : false;
}

1st try:

Looking at the VDL docs http://www.primefaces.org/docs/vdl/3.4/primefaces-p/blockUI.html revealed some blocked attribute.

    <p:blockUI widgetVar="explorerBlocker"
               block=":explorer-form"
               blocked="#{collisionManager.followupExceededCollisionsShown}" />

The above however does absolutely nothing.

2nd try:

Looking at the showcase http://www.primefaces.org/showcase/ui/blockUI.jsf, the client API seemed to be more adequate.

The idea was to call either show() or hide() depending on a ValueExpression when pressing OK on the status change dialog:

    <p:dialog id="state-change-dialog"
              widgetVar="stateChangeDialog"
              modal="true"
              appendToBody="true">

        <h:form>

            <ui:include src="/view/collisionmgmt/collisionStatusChangeGrid.xhtml" />

            <h:panelGroup layout="block" styleClass="center-button-panel">
                <p:commandButton id="save-button"
                                 icon="ui-icon ui-icon-disk"
                                 value="OK"
                                 action="#{collisionManager.performStatusChange}"
                                 process="@form"
                                 update=":explorer-form:tree :collision-form:period-grid :collision-form:list :collision-form:growl"
                                 oncomplete="stateChangeDialog.hide();" />
                <p:commandButton icon="ui-icon ui-icon-close"
                                 value="Cancel"
                                 update=":collision-form:list"
                                 onclick="stateChangeDialog.hide();"
                                 immediate="true" />
            </h:panelGroup>
        </h:form>

    </p:dialog>

The idea was to somehow extend the OK button's oncomplete="" with a call to explorerBlocker.show(); or explorerBlocker.hide(); depending on the new value of the EL #{collisionManager.followupExceededCollisionsShown}.

There are two basic variants I tried:

oncomplete="stateChangeDialog.hide(); #{collisionManager.followupExceededCollisionsShown ? 'explorerBlocker.show();' : 'explorerBlocker.hide();' }"

oncomplete="stateChangeDialog.hide(); if ( #{collisionManager.followupExceededCollisionsShown} ){ explorerBlocker.show(); } else { explorerBlocker.hide(); }"

The status change dialog is closed all the time, but the logic above isn't kicking in.

I must be making something inherently wrong here. I'm suspecting the OK button's oncomplete EL expression doesn't get re-evaluated when being clicked. Adding an @this to the update list doesn't change anything.

                 update="@this :explorer-form:tree :collision-form:period-grid :collision-form:list :collision-form:growl"
  1. How is my problem best solved, where "best" is JSF-only first, then PrimeFaces-specific (and ideally, where this is documented!).

  2. Is it possible to use the blockUI blocked="#{?}" attribute with EL?

Thanks

like image 410
Kawu Avatar asked Oct 22 '22 17:10

Kawu


1 Answers

One way is to call hide() and show() method of BlockUI from Managed Bean.
You can do that by using RequestContext:

RequestContext.getCurrentInstance().execute("widgetVar.show()");

Another is you can pass the variable to JavaScript function and then let the Javascript function take care of that for you.

onClick="func(#{elvariable})"

<script type="text/javascript">
 function func(value)
 {
 if(value==something){
 widgetVar.show();
 }else{
 widgetVar.hide();
 }
 }
</script> 
like image 184
Kishor Prakash Avatar answered Oct 27 '22 20:10

Kishor Prakash