Sway
Sway

Reputation: 151

JSF: Showing/Calling a dialog programmatically

How can I show/call a dialog programmatically and add this to stage (actual browser window)?

I want to trigger a database update every 2 hours. I have done this with a TimerTask. This works fine for me, the timer task gets all the data I want from the database. Before this timer task is triggered I want to "lock" the screen for some seconds that no user (session scoped) can access the database (I also know how this will work). My problem is that I don't know/cannot find a way to call a dialog programmatically.


Update I want to set this primefaces dialog:

Dialog dialog = new Dialog(); 
dialog.setAppendToBody(true);
dialog.setModal(true);
dialog.setVisible(true);
dialog.setWidgetVar("generatedDialog");
dialog.setId("fancyDialog");
dialog.setClosable(false);
dialog.setHeader("Getting latest information from the database");
dialog.setDynamic(true);
dialog.setResizable(false);
dialog.setDraggable(false);

How can I display it to my browser?

Upvotes: 2

Views: 5026

Answers (3)

Sway
Sway

Reputation: 151

According to @Luiggi Mendoza idea, i am stuck a bit ...

I added to my jsf the following:

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

    <ui:define name="content">

        <p:growl widgetVar="growl" showDetail="true" />

        <h:form>
        Fanciest Page ever          
        </h:form>

        <p:socket onMessage="handleMessage" channel="/notifications" />

        <script type="text/javascript">
            function handleMessage(facesmessage) {
                facesmessage.severity = 'info';

                growl.show([ facesmessage ]);
            }
        </script>

    </ui:define>
</ui:composition>

I am calling my TimerTask in a bean which is sessionscoped:

@PostConstruct
    public void initLazyModel() {
        getTimerMB().startTimer(this);
        System.out.println("Timer started");

    }

My Timer looks like this:

@ManagedBean(name = "timerMB")
@SessionScoped
public class TimerManagedBean extends TimerTask {

    private int counter;
    private Timer timer;
    private ArtikelManagedBean artikelMB;

    public void startTimer(ArtikelManagedBean artikelMB){
        this.artikelMB = artikelMB;
        this.timer = new Timer(); 
        Calendar date = Calendar.getInstance();  
        date.set(2012, 3, 28, 21, 28);
        //execute every 10 seconds  
        timer.schedule(this, date.getTime(), 10000);
    }

    @PreDestroy
    public void cancelTimer(){
        this.timer.cancel();
        System.out.println("UpdateTimer cancelled!");
    }

    @Override
    public void run() {
        counter++;
        System.out.println("Upadatetimer started: "+ new Date()+" ("+counter+")");
            PushContext pushContext = PushContextFactory.getDefault()
            .getPushContext();

    pushContext.push("/notifications", new FacesMessage("Simple",
            "Test"));
    }
}

Hmm ... Nothing happens, but anything should happen, shouldn't it ? It should give me an notification with "simple" and "test", i guess...

UPDATE:

Thank you Luiggi Mendoza! Managed it in a very simple way to show my dialogs (call it serverside). I added the following Servlet to my web.xml.

<servlet>
    <servlet-name>Push Servlet</servlet-name>
    <servlet-class>org.primefaces.push.PushServlet</servlet-class>

    <init-param>
    <param-name>org.atmosphere.useBlocking</param-name>
    <param-value>true</param-value>
</init-param>

    <init-param>
        <param-name>org.atmosphere.cpr.sessionSupport</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>Push Servlet</servlet-name>
    <url-pattern>/primepush/*</url-pattern>
</servlet-mapping>

Upvotes: 0

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

You don't need to create a dialog programatically. What you need is Push Technlogogy, i.e. the server initiates the interaction with the clients. PrimeFaces already have this technology and ready to use for you.

A basic case for your needs would be the PrimePush - FacesMessage:

  • User writes a notification.
  • The server gets the notification.
  • The notification is sent to the PushContext under the /notifications channel.
  • To every client that contains the /notifications channel, an action will be executed. In this case, the channel is only in the same page, and the action will be to show the notification.

You can test this behavior by opening the same page in two different navigators and send a notification. All the pages will show the notification (and looks like what you want).

Having this example on, the only thing you need to do will be:

  1. Set a channel on every page (this is really tedious work but it's what you want/need) or on the master pages (in case you used the template system).
  2. Your timer has to invoke somewhat a Server request to start the notification. There's a sample here about how to upload a file programmatically, but you only have to start the request1, no need to send any parameters.
  3. The request that the Timer invokes will add a notification to the channel.
  4. The channel will automatically fire the action and can do what you want/need. In the provided example, it shows a growl, but you can modify it to show a <p:dialog>.

1 In order to prevent users to invoke this request for you, it would be good to set a Filter that prevents anyone except your timer to execute the request.

Upvotes: 1

olyanren
olyanren

Reputation: 1458

There is an easy solution:

  1. Firstly add a dialog to master page. This dialog's rendered attribute should firstly be set to false.

  2. Secondly Refresh current page following codes

    protected void refreshPage() { 
        FacesContext fc = FacesContext.getCurrentInstance(); 
        String refreshpage = fc.getViewRoot().getViewId();
    
        ViewHandler ViewH = fc.getApplication().getViewHandler(); 
        UIViewRoot UIV = ViewH.createView(fc,refreshpage);
        UIV.setViewId(refreshpage); 
        fc.setViewRoot(UIV); 
    }
    
  3. Thirdly call above method with TimerTask class related method and set the dialog rendered attribute to true in this TimerTask class' related method.

Thats all :)

Upvotes: 0

Related Questions