Reputation: 151
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
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
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:
/notifications
channel./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:
<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
Reputation: 1458
There is an easy solution:
Firstly add a dialog to master page. This dialog's rendered attribute should firstly be set to false.
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);
}
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