Search code examples
jsfprimefacesdialog

Clear form or invoke method if primefaces dialog is closed via the 'X' close button


Using primefaces you can generate a dialog and set a form to control what is rendered. An example code is below:

public void enterGroup(){

if(!AuthorizationUtils.isUserInRoles(new String[]{"UPDATER"})){

    FacesContext context = FacesContext.getCurrentInstance();
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL,
            "Error",  "The user does not have permissions to perform this 
action."));

    return;


}
else{

Map<String,Object> options = new HashMap<String, Object>();
options.put("resizable", false);
options.put("draggable", false);
options.put("modal", true);
options.put("width", 500);
options.put("height", 90);
options.put("contentWidth", "100%");
options.put("contentHeight", "100%");


PrimeFaces.current().dialog().openDynamic("entergroup",options,null);
}
}

My question is if anyone knows if there is a way to control what occurs is the dialog is X'ed out, rather than a user performing the actions on the dialog. I am aware that you can set closable to false and eliminate the X altogether, but that is not exactly user-friendly. I simply need to either be able to reset my dialog form when the X is clicked, or execute a method that clears some of my Beans, and was wondering if there is a way to do so. This is more cosmetic than vital. Any help would be appreciated! I have included the xhtml below if that aids in painting a picture.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">

<h:head>
<title>Enter the Name of the new group</title>
<style type="text/css">
.ui-widget {
font-size: 90%;
}
</style>
</h:head>

<h:body>
<div class="main">
    <h:form method="post">

        <p:panelGrid columns="3" styleClass="ui-noborder">
            <p:outputLabel for="newgroupname" value="Group Name: "> 
</p:outputLabel>
            <p:inputText id="newgroupname" value="#{addgroup.newGroupName}" 
/>
            <p:commandButton action="#{addgroup.addNewGroup}" 
value="Submit"></p:commandButton>

        </p:panelGrid>

        <h:outputText value="#{addgroup.dialogMessage}" style="color: red;"> 
</h:outputText>

    </h:form>
</div>
</h:body>

</html>

Solution

  • You can do it this hacky way:

    MyBean.java:

    import static java.util.Collections.emptyMap;
    import java.util.HashMap;
    import java.util.Map;
    import javax.enterprise.context.RequestScoped;
    import javax.inject.Named;
    import org.primefaces.PrimeFaces;
    
    @Named
    @RequestScoped
    public class MyBean {
        public void dfShow() {
            Map<String, Object> options = new HashMap<>();
            // ...
            PrimeFaces.current().dialog().openDynamic("entergroup", options, emptyMap());
        }
    
        public void dfClosed() {
            PrimeFaces.current().dialog().closeDynamic("X");
        }
    }
    

    And in your entergroup.xhtml:

    <h:body>
        <h:outputScript>
        $(document).ready(function(){
            // try to get a reference to the DF widget from top window context:
            var dfWidgetVar = window.top.$('[data-pfdlgcid]').attr('data-widgetvar');
            var dfWidget = window.top.PF(dfWidgetVar);
    
            // clear closeIcon click event listener stack and add your remoteCommand:
            dfWidget.closeIcon.unbind('click').on('click', dfClosed);
        });
        </h:outputScript>
    
        <h:form>
            ...         
            <p:remoteCommand name="dfClosed" action="#{myBean.dfClosed}"/>
        </h:form>
    
    </h:body>