Following issue, I want to update my front-end from my backing-bean.
View:
<p:layoutUnit id="center" position="center">
<p:layout>
<p:layoutUnit id="inner_north" position="north" size="100">
<h:form id="fortschrittForm">
<h:panelGrid columns="10" id="fortschritt" cellspacing="7" title="Fortschritt" cellpadding="6">
<h:outputText value="Mails heruntergeladen:"/>
<p:graphicImage library="img" name="erfolg.png"
rendered="#{managedBean.mails}" />
<h:outputText value="Pdfs wurden gelesen:"/>
<p:graphicImage library="img" name="erfolg.png"
rendered="#{managedBean.pdfs}" />
</h:panelGrid>
</h:form>
[...]
Button:
<p:commandButton value="Transition starten" actionListener="#{managedBean.prozessablauf}" update=":formTabelle:formDetail:msg anzeigeRisiko"/>
Backend:
public void prozessablauf() {
try {
emailHerunterladen();
mails = true;
RequestContext.getCurrentInstance().update("fortschrittForm:fortschritt");
} catch (Exception e) {
e.printStackTrace();
}
My problem is that
RequestContext.getCurrentInstance().update("fortschrittForm:fortschritt");
is not firing. Just when the method is completely done, all icons are shown. But I want in particular to update the fortschrittForm.
Heres the code in from firebug:
enter image description here
My problem is that
RequestContext.getCurrentInstance().update("fortschrittForm:fortschritt");
is not firing.
You misunderstand the behavior of RequestContext#update method. It does not trigger a seperate response. It just provides a simple way to set which components to update within the current request at runtime instead of hardcoding it via the update attribute in the markup.
Just when the method is completely done, all icons are shown.
This is the normal behavior.
Every change to the view on the client side has to be made with a request from the client side. This is how it works (unless you are using sockets or something like this). So to reflect updates from a long running or composite process on the server side, you have to poll for updates from the client as long as the process is running.
E.g. <p:poll /> is a very good candidate to go with and i would try something like this:
When requesting the start of the process on the client side, also start <p:poll /> with update attribute set to the target part of the view.
While the process is running on the server side, update the model values associated with the target part of the view on the client side respectivley.
When process ends on the server side, request a final update of the target part of the view and stop polling on the client side.
In addition I just found something interesting, which may be an option for you also. Have a look at PrimeFaces Push
Related
I am working with Primefaces 6.2 Schedule component for a few days now and I can't find an answer to solve my issues using the component. I need some technical advice on this matter.
I've created a view with the Schedule component inside a composition like so:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:form id="content-form">
<p:outputPanel id="page-title-myevents">
<h3>#{translations['pvm_myevents']}</h3>
</p:outputPanel>
<h5>#{translations['misc_myscheduler']}</h5>
<p:schedule id="myScheduler" value="#{myEventsBean.eventModel}" widgetVar="myscheduler" timeZone="#{appSettingsBean.uiTimeZone}">
<p:ajax event="dateSelect" listener="#{myEventsBean.onDateSelect}" update="myEventDetails" oncomplete="PF('myEventDialog').show();" />
<p:ajax event="eventSelect" listener="#{myEventsBean.onEventSelect}" update="myEventDetails" oncomplete="PF('myEventDialog').show();" />
<p:ajax event="eventMove" listener="#{myEventsBean.onEventMove}" update="myEventMessages" />
<p:ajax event="eventResize" listener="#{myEventsBean.onEventResize}" update="myEventMessages" />
</p:schedule>
<p:dialog widgetVar="myEventDialog" header="Event details" modal="true">
<h:panelGrid id="myEventDetails" columns="2">
<p:outputLabel for="myEventTitle" value="#{translations['fld_eventtitle']}" />
<p:inputText id="myEventTitle" value="#{myEventsBean.event.title}" required="true" />
<p:outputLabel for="myEventFrom" value="#{translations['fld_from']}" />
<p:calendar id="myEventFrom" value="#{myEventsBean.dateFrom}" timeZone="#{appSettingsBean.uiTimeZone}" pattern="#{appSettingsBean.uiDateTimePattern}" />
<p:outputLabel for="myEventTo" value="#{translations['fld_to']}" />
<p:calendar id="myEventTo" value="#{myEventsBean.dateTo}" timeZone="#{appSettingsBean.uiTimeZone}" pattern="#{appSettingsBean.uiDateTimePattern}" />
<p:outputLabel for="myEventAllDay" value="#{translations['fld_allday']}" />
<h:selectBooleanCheckbox id="myEventAllDay" value="#{myEventsBean.event.allDay}" />
<p:commandButton id="myEventResetForm" type="reset" value="#{translations['btn_reset']}" />
<p:commandButton id="myEventUpdate" value="Save" action="#{myEventsBean.addEvent}" oncomplete="PF('myscheduler').update();PF('myEventDialog').hide();" />
</h:panelGrid>
</p:dialog>
<p:messages id="myEventMessages" showDetail="true" closable="true">
<p:autoUpdate />
</p:messages>
<hr></hr>
</h:form>
</ui:composition>
I have various compositions and they all get loaded inside my dashboard.xhtml like so:
<!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">
<ui:include src="/themes/theme.xhtml"/>
<h:body>
<ui:insert name="header" >
<ui:include src="/main-dashboard/my-topnav.xhtml"/>
</ui:insert>
<ui:insert name="content" >
<ui:include src="/main-dashboard/my-sidenav.xhtml"/>
<p:outputPanel id="dashboard-container">
<ui:include src="/main-dashboard/my-sidenavtoggler.xhtml"/>
<p:outputPanel id="content-window">
<p:outputPanel id="content-panel">
<ui:include src="#{contentLoaderBean.mainContent}" />
</p:outputPanel>
</p:outputPanel>
</p:outputPanel>
</ui:insert>
</h:body>
</html>
This is my first composition that's actually built (others are still empty). I load a simple ScheduleModel to it on #PostConstruct inside a #ViewScoped bean.
Since I'don't have any events in my database yet, I set the model like so: setEventModel(new DefaultScheduleModel());
FIRST ISSUE: If I put some random generated events inside a model, sometimes they get displayed in the view, sometimes they don't. I don't understand why this happens at all. I don't get any errors in Java or Javascript console, it's just random. Lazy model works the same.
SECOND ISSUE: Empty or full Schedule model, doesn't matter. When the page loads I usually get a Javascript warning saying:
jquery.js.xhtml?ln=primefaces&v=6.2:4 [Deprecation] Synchronous
XMLHttpRequest on the main thread is deprecated because of its
detrimental effects to the end user's experience. For more help, check
https://xhr.spec.whatwg.org/
THIRD ISSUE: You may have noticed I also have a dialog inside the content form. This dialog fires on date select event and when I try and select a date from the datepicker component it throws an interesting Javascript error (uncaught type error) like so:
It's interesting because if I try to do the same thing on Firefox it throws a different error like so:
Microsoft Edge doesn't throw errors at all.
NOTICE:
Datepicker could be an issue as well since it doesn't pop up when schedule loads and shows a model with randomly generated data. If scheduler fails to load the model, datepicker will pop-up and throw the uncaught type error when any date is selected.
It doesn't matter which date I select, errors are thrown. Since Ajax requests don't fire correctly, bean methods don't fire at all, so I think it has to be something on the view side that needs to be fixed properly.
I've tried and disabled all custom css and js imports (am using Bootstrap 4.2.1 css and js for design purposes) and manually cleaned deployment directories. I also made sure my project is loaded without old resources by clearing browser history and cache. I had no luck fixing these issues so far (all warnings and errors remain the same).
I don't know if all three issues are related or not but I've put them in the same post. Sometimes solving one issue, solves others as well. Since they all happen in the same composition this just might be the case again.
Let me know if I can provide more detail in any way and I'll do what I can.
Thank you.
EDIT: Based on a received comment from #Melloware. Upgrading Primefaces 6.2 to Primefaces 7-RC2 solved some issues for me. Deprecation warnings and uncaught type errors are gone now. First issue still remains. Schedule component doesn't show schedule objects or "events". During debug mode, I've found out that schedule objects are created and are pushed to the schedule model. All I need now, is the view component to show them.
Since I was able to solve the last piece of my puzzle, Schedule not displaying my schedule objects, I'll write a full answer to my question.
Answer provided by #Melloware helped me move forward with my core design. Upgrading Primefaces 6.2 to Primefaces 7-RC2 removed deprecation warnings and uncaught type errors. Now I was able to locate and implement a solution for my final issue, loading schedule objects.
I've made a rookie mistake loading my contents through my content loader bean. To be precise, I've implemented content navigation while pushing links to my content loader bean which handles what should be loaded next when navigation action is executed. Navigation actions should be called with Action properties from CommandLink components. Here is where I made my design mistake. I used the ActionListener property instead, which resulted in a situation where my content didn't get loaded properly.
Here is a quote from #BalusC post that got my wheels spinning again:
The action method can (thus, not must) return a String which will be
used as navigation case outcome (the target view). A return value of
null or void will let it return to the same page and keep the current
view scope alive. A return value of an empty string or the same view
ID will also return to the same page, but recreate the view scope and
thus destroy any currently active view scoped beans and, if
applicable, recreate them.
Full post can be found here: differences-between-action-and-actionlistener
I've learned something new today.
Thank you!
"anymore" is definitely a key word here. I had this working, and even after comparing my previous revisions, I cannot see a smoking gun.
I have placed an accordion in the navigation panel on the West side of my layout. I have overridden the actionListener to call a remoteCommand, like this.
<p:accordionPanel widgetVar="tabPanel"
dynamic="true" cache="true"
activeIndex="-1"
actionListener="tabChange()">
<p:remoteCommand name="tabChange"
process="#this"
update=":contentPanel"
actionListener="#{viewSelectionBean.changeView}" />
When clicking on any given tab, it used to call the backing bean method changeView, which sets the html page being shown in ":contentPanel", but now I get no backing bean action. I have commandLinks within each of these accordion tabs that also call changeView successfully. Its only the tabChange() that doesn't seem to be called.
actionListener is not a property of accordionPanel, therefore, thats why it wouldn't be called. This feature can be made to work using ajax, but it demonstrates lag while expanding each tab. Lag aside, one might also have success overriding onTabChange of the accordionPanel, but that will force you to have to manually effect the activeIndex, and the expanding of tabs.
<p:accordionPanel widgetVar="tabPanel"
dynamic="true" cache="true"
activeIndex="-1">
<p:ajax event="tabChange"
listener="#{viewSelectionBean.onTabChange}"
update=":contentPanel"
process="#this"
partialSubmit="true"/>
I have the following scenario :
Page.xhtml (p:selectCheckBoxMenu id=sb1)
From page.xhtml I call genericDialog.xhtml
genericDialog.xhtml (Composite implementation with p:dialog,etc...)
From genericDialog.xhtml how can I process and update via p:ajax the sb1 component.
Error : javax.faces.FacesException: Cannot find component with identifier "formPessoa:tipoMercado" referenced from "j_idt440:myForm:confirm"
From the left side of image in green color I have my composite p:dialog (genericDialog.xhtml)
From the right side of image I have in red the selectCheckBoxMenu id=sb1 which I need to reload after saving new data from dialog.
thanks a lot stack members.
After a lot of time to me.... I figured out the issue:
<p:commandButton id="confirm" value="#{cc.attrs.labelbotao1}"
oncomplete="#{cc.attrs.oncompletebotao1}" update="myForm:divmessage"
actionListener="#{cc.attrs.actionbeanbotao1}" **ajax="true"**>
<p:ajax update="#{cc.attrs.ajaxupdate1}" process="#{cc.attrs.ajaxprocess1}"
listener="#{cc.attrs.listener1}" />
</p:commandButton>
Two problems:
First I need to reference in the composition genericDialog.xhtml the full path to update the component e.g. myform: sb1
Second the AJAX on p: commandButton has to be false. This way it does not cancel the p: AJAX update and process.
I'd like to hear some other opinions or fixes, etc.
i am using primefaces 3.2 when try to update the ajax in two differnt forms is not getting updated. See the below code
<p:selectOneMenu value="#{baen.vareable1}">
<f:selectItem itemLabel="val1" itemValue=="val1"/>
<f:selectItem itemLabel="val2" itemValue="val2" />
<p:ajax update="new" listner="#{bean.val()}" event="onchange"/>
</p:selectOneMenu >
replace event="onchange" with event="change" or event better remove it completely (cause its the default event)
Could it be that a form validation is blocking the request? Try setting <p:ajax process="#this" .../>.
By default the complete form that the component belongs to is processed. So by setting this attribute to "#this", only the selectOneMenu component is processed. An additional advantage is that the request becomes a little bit lighter, because less information is sent to the server.
How can I use an AJAX listener inside a tabview. Whenever the tab opened(or for a mouse click anywhere), the listener need to execute. I tried with event=click,change,blur etc, but not worked.
<p:tabView activeIndex="#{backingbean.tanIndex}">
<p:ajax event="?" listener="#{backingbean.setTabIndex}" />
in view.jsf:
<p:tabView>
<p:ajax event="tabChange" listener="#{employeeEdit.onTabChange}">
in edit.jsf:
<p:tabView activeIndex="#{employeeEdit.tabIndex}">
in backingBean:
private int tabIndex;
public int onTabChange(TabChangeEvent event)
{
// Here I'm getting event.getTab().getId() and set it to `tabIndex` property.
}
When editing I need redirect to the that tab which is active in view. So if I didn't change the tab onTabChange() will not execute and tabIndex has its old value only.
I'm using Primefaces version-3.0.M3.
It looks like this was a Primefaces bug that was fixed in the newest 3.0.1 release:
http://forum.primefaces.org/viewtopic.php?f=3&t=17288
I had a similar problem with Primefaces 5.1
As long as i put the tabview into a form everything worked fine.
But because i wanted to use seperate forms in my tabs i had to remove the surrounding form of the tabview to avoid nested forms.
Without the surrounding form the ajax event didn´t get triggered any more when changing the tab.
My solution was to use a remotecommand in a form parallel to the tabview.
The remotecommand is triggered by the onTabChange attribute of the tabview element.
At that call i forwarded the index parameter to the global request parameters.
<p:tabView id="rootTabMenu" styleClass="tabcontainer" prependId="false"
activeIndex="#{sessionData.activeTabIndex}" widgetVar="rootTabMenu"
onTabChange="tabChangeHelper([{name: 'activeIndex', value: index}])">
// Tabs...
</p:tabView>
<h:form id="tabChangeHelperForm">
<p:remoteCommand name="tabChangeHelper" actionListener="#{sessionData.onTabChange()}" />
</h:form>
In the backing bean i catched the value again from the request parameter map and set the active index.
public void onTabChange()
{
FacesContext context = FacesContext.getCurrentInstance();
Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();
String paramIndex = paramMap.get("activeIndex");
setActiveTabIndex(Integer.valueOf(paramIndex));
System.out.println("Active index changed to " + activeTabIndex);
}
Hope that can help you
Not sure if what I am writing is true for ver 3.0.M3. I have in front of the documentation of ver 3.0RC2 and there is a paragraph about this, with explaination and sample code (chapter TabView, paragraph Ajax Behaviour Events). You should have a look at that.
This is the part of the sample code that should help most:
<p:tabView>
<p:ajax event=”tabChange” listener=”#{bean.onChange}” />
</p:tabView>
Jaron has an answer that the 3.0.1 release fixed this but I had this all the way up to 3.5 i believe i was still having this problem. on firefox and IE, the javascript handler for the Tabs weren't firing the ajax event. On google chrome, for whatever reason, it actually worked.
I moved up to Primefaces 5.0 today and this does NOT have the problem any longer. So at the very worst-case, go to Primefaces 5.0 and you'll be all good in the hood