Update ui components from server event - jsf

How would I go about updating a UI component when a server process finishes or anytime else for that matter?
Can\Should I
extend the UI component and register some kind of EventListener on it?
bind the UI component in a backing bean?
use some of the new PrimePush features?
something else?
If anyone could guide me in the right direction I'd appreciate it.
Example Case One
Server process ends and updates the database.
I want to automatically
update a DataTable with new rows based on the new information.
I don't want to poll for the new data.
EDIT
I want to update the UI component (a primefaces datatable) from an EJB Stateless Bean

You didnt mention which version of primefaces you are using but you can update components from backed bean with addpartialupdatetarget.
RequestContext context = RequestContext.getCurrentInstance();
context.addPartialUpdateTarget("myForm:myComponent");

You can just use the update attribute of your commandButton or whatever else you're using.
Something like this should work
<p:dataTable value="#{backer.bean}" id="table">
// columns with data
</p:dataTable>
<p:commandButton actionListener="#{backer.updateDB}" update="table" />

Related

Updating an UI value from javascript is not getting reflected in javabean

I am trying to update an UI text field in primefaces 6.2 using java script method. Though I am able to update the value from UI side, it is not reflecting in backing managed bean
Xhtml:
<h:inputHidden id="test" value="#{mybean.fieldname}" valueChangeListener="#
{mybean.method}">
<f:ajax/>
</h:inputHidden>
Javascript:
function update(){
document.getElementByID('form:test').value="change";
alert(document.getElementByID('form:test').value);
}
I expect my value changehandler to get called since I updated my value but nothing occurs.can some one pls tell where I am getting wrong
Edit :Actually I am trying to submit the value changed from UI side alone using Js to the actual bean value, basically dom alone is changed and kind of trying to submit the same using any ajax calls. but still it is not working. Refered this link:When to use valueChangeListener or f:ajax listener? Can some one pls give some insights on how this can be achieved?
You have to trigger explicitly a change event by JavaScript if you set a value by JavaScript.

Execution order of events when pressing PrimeFaces p:commandButton

I am trying to execute a JSF2 bean method and show a dialog box after completion of the method on click of PrimeFaces <p:commandButton>.
<p:commandButton id="viewButton" value="View"
actionlistener="#{userBean.setResultsForSelectedRow}" ajax="false"
update=":selectedRowValues"
oncomplete="PF('selectedRowValuesDlg').show()">
</p:commandButton>
<p:dialog id="selectedRowValues" widgetVar="selectedRowValuesDlg" dynamic="true">
<h:outputText value="#{userBean.selectedGroupName}" />
</p:dialog>
When I click on the command button, the bean action listener method setResultsForSelectedRow executes properly, but it does not show the dialog box when the method completes. If I remove actionlistener, it shows the dialog box. I do not know what is going wrong.
What is the execution order of events? Is it possible to execute actionlistener and oncomplete simultaneously?
It failed because you used ajax="false". This fires a full synchronous request which in turn causes a full page reload, causing the oncomplete to be never fired (note that all other ajax-related attributes like process, onstart, onsuccess, onerror and update are also never fired).
That it worked when you removed actionListener is also impossible. It should have failed the same way. Perhaps you also removed ajax="false" along it without actually understanding what you were doing. Removing ajax="false" should indeed achieve the desired requirement.
Also is it possible to execute actionlistener and oncomplete simultaneously?
No. The script can only be fired before or after the action listener. You can use onclick to fire the script at the moment of the click. You can use onstart to fire the script at the moment the ajax request is about to be sent. But they will never exactly simultaneously be fired. The sequence is as follows:
User clicks button in client
onclick JavaScript code is executed
JavaScript prepares ajax request based on process and current HTML DOM tree
onstart JavaScript code is executed
JavaScript sends ajax request from client to server
JSF retrieves ajax request
JSF processes the request lifecycle on JSF component tree based on process
actionListener JSF backing bean method is executed
action JSF backing bean method is executed
JSF prepares ajax response based on update and current JSF component tree
JSF sends ajax response from server to client
JavaScript retrieves ajax response
if HTTP response status is 200, onsuccess JavaScript code is executed
else if HTTP response status is 500, onerror JavaScript code is executed
JavaScript performs update based on ajax response and current HTML DOM tree
oncomplete JavaScript code is executed
Note that the update is performed after actionListener, so if you were using onclick or onstart to show the dialog, then it may still show old content instead of updated content, which is poor for user experience. You'd then better use oncomplete instead to show the dialog. Also note that you'd better use action instead of actionListener when you intend to execute a business action.
See also:
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
Differences between action and actionListener
I just love getting information like BalusC gives here - and he is kind enough to help SO many people with such GOOD information that I regard his words as gospel, but I was not able to use that order of events to solve this same kind of timing issue in my project. Since BalusC put a great general reference here that I even bookmarked, I thought I would donate my solution for some advanced timing issues in the same place since it does solve the original poster's timing issues as well. I hope this code helps someone:
<p:pickList id="formPickList"
value="#{mediaDetail.availableMedia}"
converter="MediaPicklistConverter"
widgetVar="formsPicklistWidget"
var="mediaFiles"
itemLabel="#{mediaFiles.mediaTitle}"
itemValue="#{mediaFiles}" >
<f:facet name="sourceCaption">Available Media</f:facet>
<f:facet name="targetCaption">Chosen Media</f:facet>
</p:pickList>
<p:commandButton id="viewStream_btn"
value="Stream chosen media"
icon="fa fa-download"
ajax="true"
action="#{mediaDetail.prepareStreams}"
update=":streamDialogPanel"
oncomplete="PF('streamingDialog').show()"
styleClass="ui-priority-primary"
style="margin-top:5px" >
<p:ajax process="formPickList" />
</p:commandButton>
The dialog is at the top of the XHTML outside this form and it has a form of its own embedded in the dialog along with a datatable which holds additional commands for streaming the media that all needed to be primed and ready to go when the dialog is presented. You can use this same technique to do things like download customized documents that need to be prepared before they are streamed to the user's computer via fileDownload buttons in the dialog box as well.
As I said, this is a more complicated example, but it hits all the high points of your problem and mine. When the command button is clicked, the result is to first insure the backing bean is updated with the results of the pickList, then tell the backing bean to prepare streams for the user based on their selections in the pick list, then update the controls in the dynamic dialog with an update, then show the dialog box ready for the user to start streaming their content.
The trick to it was to use BalusC's order of events for the main commandButton and then to add the <p:ajax process="formPickList" /> bit to ensure it was executed first - because nothing happens correctly unless the pickList updated the backing bean first (something that was not happening for me before I added it). So, yea, that commandButton rocks because you can affect previous, pending and current components as well as the backing beans - but the timing to interrelate all of them is not easy to get a handle on sometimes.
Happy coding!

Update PrimeFaces dataTable from backing bean

I use schedule(Timer) in bean which update variable when employees enrolling which get data from fingerprint device. I need to update component in jsf from backing bean when variable in bean updated. I try to use primefaces poll component but it update component every time.
Assuming you'll be calling a Java method using Listener from Fingerprint device API, and from ManagedBean you can update any Primefaces Component using RequestContext.
RequestContext.getCurrentInstance().update("ID_OF_YOUR_DATATABLE")
There's already a component in Primefaces, as you can see : here.
RequestContext is a feature with various handy utilities.
Update component(s) programmatically. Execute javascript from beans.
Add ajax callback parameters. ScrollTo a specific component after ajax
update.
Have a look here for an example.
I resolved my problem with primefaces push component.
java code is:
PushContext pushContext = PushContextFactory.getDefault().getPushContext();
pushContext.push("/finger", "Pressed");
in jsf:
<p:socket channel="/finger" onMessage="clearCookies" />
"clearCookies" is remoteCommand function which update my dataTable.
It has changed from primefaces 7.0
PrimeFaces.current().ajax().update("elementJS");

have to press command button twice

I'm working on building a web page and notice now that I have to press the command button twice. Any command button has the same problem, so I figured I would add and action listener on one of them to see if I could see something.
<h:form id="formP">
<p:commandButton id="temp" value="photos" actionListener="#{viewBacking.debugBreakpoint()}" action="userPhoto" />
</h:form>
The backing bean has
public void debugBreakpoint() {
int i = 0;
i++;
}
Unfortunately, this does help. It hits my breakpoint only after the second press. I suspect that some field somewhere isn't passing validation but I would like some method of detecting what exactly is going wrong - why do I need the second push? Is there some option I can turn on in Glassfish, or something else where I can look at a dump of debug information? I can ignore the dump until everything is stable and then see what exactly is happening when I press the button for the first time.
Is there any such tool which I can use?
That can happen when a parent component of the given <h:form> has been rendered/updated by another command button/link with <f:ajax>. The given form will then lose its view state which it would only get back after submitting the form for the first time. Any subsequent submits will then work the usual way. This is caused by a bug in JSF JS API as descibred in JSF issue 790 which is fixed in the upcoming JSF 2.2.
You need to fix the another command button/link with <f:ajax> to explicitly include the client ID of the given <h:form> in the render.
<f:ajax render=":somePanel :formP" />
Another way is to replace this <f:ajax> by a PrimeFaces <p:commandLink> or <p:commandButton> so that you don't need to explicitly include the client ID of all the forms. PrimeFaces's own JS API has namely already incorporated this fix.
add event="onclick" in your p:commandbutton
I guess that will sort it out.
or you can add this ajax="false" property in your commandButton
<p:commandButton ajax="false" action="#{userController.create}" value="#{bundle.CreateUserSaveLink}"></p:commandButton>
I ran into the same issue. The solution was simple, instead of having both an actionListener and an action, just convert the actionListener method to return a string to where you want to navigate to and use it as the method for the action (and don't have an actionListener).
In simple terms: only use an action (do not use an actionListener on a commandButton that is submitting a form).
Please check your binding with bean.
bean fields should be String or non primitive.

JSF validation for client side injected elements

I know there is a property in asp.net (probably this EnableEventValidation of "<%# Page%> tag) .Which, once caused problem when i try to add select items to a component using javascript ,I want to know how jsf handling this. That is,
if i send a h:select* like below and client add a new item "option3 " to item list, is jsf detect this automaticly before update model values .
<h:selectOneMenu id="type"
value="#{foo.value}"
required="true"
requiredMessage="Type is required"
style="width:100px">
<f:selectItem value="option1}"/>
<f:selectItem value="option2}"/>
</h:selectOneMenu>
I think what you need to understand regarding JSF is that the client/server parts of the components are tightly coupled together. You are probably better off thinking of them strictly as one entity, and forget about fiddling with one side only, reverting to custom Javascript when that is the only solution left.
The other way to think of it is that the server side renders the client side, not vice versa! So whenever you need to update a component the update must be done on the server side first, which will propagate to the client side (the browser).
In your example the proper way to add and element to the select* items is to store the selectable items in a data structure within a bean (probably #ViewScoped), and then do a partial update via AJAX for the select* component or its container component, when the server side gets the chance to become aware of the changes and can update the client side properly as well.
Sure, you can hack your way through Javascript only, but then why use JSF? The whole point of JSF is to avoid the need for hacks like this.
Remember, JSF is not JSP, which is basically a println macro for html output. JSF stores the page components' representation on the server side, mirroring the browser's representation.
Check the Primefaces showcase for examples on how to do partial updates. More specifically this is the example you could be looking for. This is available in standard JSF2, for JSF 1.2 you must use a component library to get AJAX support.
You should not add the new option by JavaScript, but you should add the new option by JSF. JSF needs to know about the new option somehow in order to allow the submitted value. The new option really needs to be served by <f:selectItem(s)>. Otherwise you will face Validation error: Value not valid all the time when submitting the option value which is added by JS. This is after all just a safeguard of JSF to prevent clients from manipulating the request and submitting values which they are not supposed to submit.
The following kickoff example should work:
<h:form>
<h:selectOneMenu id="menu" value="#{bean.item}">
<f:selectItems value="#{bean.items}" />
</h:selectOneMenu>
<h:inputText id="newItem" value="#{bean.newItem}" />
<h:commandButton value="add" action="#{bean.addNewItem}">
<f:ajax execute="#this newItem" render="menu" />
</h:commandButton>
<h:commandButton value="submit" action="#{bean.submit}" />
</h:form>
with a #ViewScoped managed bean something like follows:
private String item;
private List<String> items = Arrays.asList("option1", "option2");
private String newItem;
public void addNewItem() {
items.add(newItem);
}
// ...

Resources