Primefaces component push to client - jsf

I have short question on Primefaces and especially on server-side push capabilities. Due to the given examples on http://www.primefaces.org/showcase/push/index.jsf, I know that it is possible to push a string to the client and force to update some UI-elements.
However, in my case I would need something slightly different:
Is it possible to add and push entire components (Buttons, Textfields etc.) to the client?
The push itself will be triggered by an background thread too. So, basically my workflow looks like that:
User -> starts background (multi) threads
Background thread -> generates new component (Button, TextField) -> added to UI / bean -> bean / view updated
There can also be longer time ranges when the UI will be updated with a new element again, therefore a simple ajax request, for example, every 5-10 sec. would cause too much traffic.
This question is also related to this: PrimeFaces push component and How to update the GUI from another thread?

I have used two approaches that worked:
Use to create a javascript method that you can call from . This remote command can call a listener on the managed bean and do an ajax partial update of your page which can add a component.
Use AngularJS, jquery, or raw javascript to add components to your DOM- this has the benefit of being very fast - not requiring any round-trip to the server.
I hope this helps.

Related

Partial refresh in XPages causing other controls to not execute event handlers?

I have an xpage with a bunch of controls on it. One of them is a simple label that I'm updating with a partial refresh every five seconds. (I'm implementing a document locking scheme, and the label indicates whether someone has locked the document.) A button on the page fails to execute its event handler if I press it while the partial refresh of the label is occurring. At other times, it works fine. Is this a known issue, or is there perhaps something else going on that may explain this behavior?
(I'm unable to post sample code, unfortunately.)
You need to change your approach. Instead of a partial refresh, have an independent Ajax call to an XAgent for your locking (IMHO 5 sec is way to frequent, the WebDAV standard uses 30sec).
The openNTF WebDAV project has locking code you might be able to repurpose for your needs.
The independent Ajax call frees up the jsf lifecycle to run your other events.

Alerts or Popups in MvvmCross

Does MvvmCross support a cross platform solution for displaying alerts or popups?
Searching the code I found MvxDialogActivityView but it has been commented out. Will this remain the case for now?
If there is no direct support how would you suggest this is best done? (Perhaps the ViewModel would change a property and call FirePropertyChanged so that the View would be aware of it and show an alert.)
Edit 16:04 16th June 2012
What I am trying to do for this specific case is as follows:
On the page a button is clicked, which causes a method to run in the ViewModel which does an evaluation to determine which of two messages should be shown to the customer. The message would be shown as an alert or popup (either native, or preferably totally styled by me). The message would fade after (the click of the OK button, or preferably 3 seconds).
After the message has been dismissed a new page will be navigated too (depending on which of the two messages was shown).
How to handle this definitely depends on what the situation is - there's no single best rule (IMHO)
For a general error display pattern, there's one proposal at http://slodge.blogspot.co.uk/2012/05/one-pattern-for-error-handling-in.html
I've used similar patterns for showing application level notifications - e.g. for when a long running operation completes or when a chat message arrives or...
One interesting post about how to display message boxes was: http://awkwardcoder.blogspot.co.uk/2012/03/showing-message-box-from-viewmodel-in.html - I'm not sure I'd completely follow the end solution, but there are definitely some good points there about what not to do.
For your updated scenario, I would consider using a messenger (like TinyMessenger) or using normal C# events exposed by the ViewModel and consumed by its View
On the page a button is clicked, which causes a method to run in the ViewModel
I would implement this using an ICommand bound to the button Click/Tap/TouchDown
which does an evaluation to determine which of two messages should be shown to the customer.
I would definitely implement the logic within a Service
This would be called from the ViewModel - and the result/decision would probably cause some property or private field state change.
How does the View then decide to show a message? I can think of 3 options:
The View could just respond to a Property change (normal Mvvm INPC) - this would be my preference
The ViewModel could expose a normal C# event which it triggers...
The ViewModel could send a Message
This last option (Messenging) is probably the most flexible solution here - it decouples the View and ViewModel in case you later decide to change responsibilities. To implement messenging, either:
implement your own hub (like I do for errors in http://slodge.blogspot.co.uk/2012/05/one-pattern-for-error-handling-in.html)
or use a generic solution like TinyMessenger
The message would be shown as an alert or popup (either native, or preferably totally styled by me).
This is a View concern - so would be entirely controlled by the View project. I'd use controls like: UIAlert, Toast, ToastPrompt, etc - all of which can be styled
The message would fade after (the click of the OK button, or preferably 3 seconds). After the message has been dismissed...
I'd use some form of Code Behind (or maybe a Behaviour in WP7) in the View. This would detect the click/fade/disappear and would then invoke either an ICommand (my preference) or public method on the ViewModel
a new page will be navigated too
This navigation would be requested from the ViewModel
(depending on which of the two messages was shown).
This would be easy to track through the above flow... presumably the ViewModel already knows what to show.
So that's what I'd do...
it keeps the application flow logic inside the ViewModels (and lower)
it keeps the presentation inside the Views
...but I'm sure there are other options :)
One final note... the fade out and then navigate logic can really get "messed up" by Switching/Tombstoning on WP7 and Android - this may or may not matter for your particular scenario.

JSF2 LogicalViews - Losing the Current Page From the Map

We recently updated our Application to use JSF 2.1.3
We have an existing page that has three framesets (left nav, main, footer). Clicking on something in the main frame, causes the footer frame to be reloaded with new content. Because of this, we are losing the main frame from the logical view map after (eg. if com.sun.faces.numberOfLogicalViews is set to 10, we lose the main frame after 9 clicks). After which, trying to submit the main frame causes it to re-render, skipping the action method it's bound too.
Is there any way to keep that logical view from being removed from the map without increasing the number of logical views? I'm not sure why, but this behavior didn't occur when out app was using JSF 1.2.
We solved this problem by overriding the StateManagerImpl, and storing this particular view client side, instead of server side.
It appears in previous versions of jsf, you only needed to override the isClientSide method, but you now need to override the methods to write and restore state.

How to handle multiple submits before response is rendered?

It has been reported from testing that it is occasionally possible to press a button more than once if the response is not rendered fast enough, causing several invocations of the back-end code, which we do not want.
Application is Java EE 6 Web Profile using JSF 2.0 inside Glassfish 3.1.1.
I was wondering how this should be properly dealt with, and have thought of a few scenarios:
Submitting should disable all buttons using javascript while response is being rendered.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
Using one of the "new" scopes like conversion to handle the detection?
My immediate gut feeling is that the best approach is to have sensitive code blocks atomic, but then the problem is with rendering the correct response.
How should I approach this?
Submitting should disable all buttons using javascript while response is being rendered.
This is the easiest to implement in a generic manner. If you happen to use <f:ajax> exclusively, you could use the jsf.ajax.addOnEvent() to perform the job in a generic manner. An alternative JavaScript approach is to create kind of an "Loading" overlay which blocks the UI so that the enduser won't be able to interact with the underlying page anymore. This is basically an absolutely positioned hidden <div> which spans the entire viewport with some opacity (transparency). You could show it on submit and hide it on render. The keyword for this technique is "modal dialog". UI-oriented JSF component libraries have at least such a component already in their assortiment. E.g. PrimeFaces with a <p:dialog modal="true"> inside a <p:ajaxStatus>, or the <p:blockUI>
The only disadvantage is that it won't work if the client has JS disabled or don't use it and it thus won't prevent HTTP clients from double submits.
A flag in the Session scope saying it is already active, so the sensitive code is skipped and just moves on to the re-rendering of the response for the previous submit.
This is more known as "synchronizer token pattern" and has ever been requested for JSF by spec issue 559 which is currently on the ticket targeted for 2.2, but there doesn't seem to be any activity on it. The detection and blocking part is technically easy to implement, but the synchronous response handling part is not easy to implement if you want that the enduser ultimately retrieves the response as generated by the initial request. The asynchronous response handling is easy: just don't specify any components to update, i.e. empty the collection as returned by PartialViewContext#getRenderIds(). After all, this is more robust than using JS to disable the buttons or block the UI.
As far as I know, Seam 2 was the only who offered a reuseable JSF component for this, the <s:token>. I must however admit that this is an interesting idea for a new OmniFaces component. Maybe I will personally take a look at it.
A synchronized block delaying the processing until the previous request have finished. Then it should be detected that it has been already processed and skipped.
This is not easy to implement generically, this would require a change in all action methods to check if the job is already done. It also won't work if the webapp runs on multiple servers. A synchronizer token is easier as it would be performed before the action methods are invoked. A synchronizer token is also less expensive as you don't end up with multiple requests in the queue which would only cost threads/resources.
Using one of the "new" scopes like conversion to handle the detection?
This problem cannot be solved by playing around with managed bean scopes. Managed bean scopes serve a different purpose: the lifetime of the bean instance.
As Adrian mentioned, I would also use BlockUI. There is a BlockUI component from Primefaces. When you submit your forms through ajax, you could also use an overlay during the request. See Primefaces`s Ajax Status for an example.

Whats the best way of sending parameters between pages?

We are using JSF in our project (im pretty new to it) were every page have a back bean Java file.
In order to move (redirect) from one page to another, i need to put all the parameters (search criteria) in the request scope before redirecting and then retrieve it back in the next page constructor. When you have few pages deep and you want to come back to the top, it becomes really annoying to maintain.
For example, if i have page 1 with advanced search filters, which redirects to page 2, depending on the chosen item, and from page 2, you get another list were you can go to page 3 for details. Now each time i need to put all the params in the request scope/read them again, store them in hidden fields and get them back.
Whats exactly wrong with this method and whats a better way to do it in JSF?
EDIT: the environment is IBM Rational Application Developer (RAD), which have its own JSF implementation. Not sure if that makes a difference.
Putting request scoped data in session scope will bite you (very) hard if you're going to open the same page in multiple windows/tabs. Only use the session scope if the data itself is also really session scoped (excellent examples are the "logged-in user" and the "shopping cart", you want it to be exactly the same throughout the entire session). Again, don't put request scoped data in the session scope. It hurts both you and the enduser.
Just design your beans smart (it makes no sense to have different beans containing the same data) and make use of h:inputHidden where needed, if necessary in combination with managed property injection. It's indeed a bit a pain to code and maintain. You can on the other hand also just grab Tomahawk <t:saveState> if the to-be-passed data is actually as big as a "whole" managed bean. It costs only a single line in the JSF page and has always been of great assistance.
*For example, if i have page 1 with advanced search filters, which redirects to page 2, depending on the chosen item, and from page 2, you get another list were you can go to page 3 for details. Now each time i need to put all the params in the request scope/read them again, store them in hidden fields and get them back.
Whats exactly wrong with this method and whats a better way to do it in JSF?*
There's nothing wrong with this method. Maybe you coded it the wrong way which caused that it looks unnecessarily overcomplicated. I can't tell much as long as you don't post details about the code used.
As per your edit:
EDIT: the environment is IBM Rational Application Developer (RAD), which have its own JSF implementation. Not sure if that makes a difference.
This is not true. IBM doesn't have any JSF implementation. It has just a component library (the poorly maintained hx prefixed components, also known as "Faces Client Framework"). WSAD/RAD ships with Sun JSF RI (Mojarra) as standard JSF implementation, although it's usually a heavily outdated version. Ensure that you keep it updated.
I'm only starting out with JSF too to be honest, but I thought you can save managed beans in the session scope, thus being able to access the bean on each request? You can also save the state client-side avoiding nastiness about session stickyness and stuff.
So you could save the data you are currently passing as request parameters in a session-scoped managed bean, and it will be available to any requests in that user's session, destroyed when the session times out or is deliberately invalidated (say on user logout).
I don't think JSF currently supports conversation state which I think might be the exact solution to your problem, maybe a session scoped managed bean would be the pragmatic solution?
Make your managed-bean session scoped.
If you are using MyFaces you can use PageFlowScope. If using Seam then use Conversation scope.
If pageflowscope or conversation scope is not available, then use session scoped beans. In addition you can use PhaseListener to initialize or execute specific methods before the page gets called. In you case if the flow is page1 -> page2 -> page3, then initialize the session scoped bean in PhaseListener if page1 gets called.
I'll update with more info if you need.

Resources