JSF-Calling BackingBean method twice maintaining value of inputFileUpload - jsf

I am very new to JSF. I have the following requirement:
On click of a commandButton, call a backing bean method to check if there is some data present satisfying the condition.
If yes, confirm from user for overwrite.
If user says OK, call the same method of backing bean with some parameters set to tell the program to overwrite the data.
What I am doing is:
having action of the commandButton as the method name.
in the backing bean method, check if we have come with certain condition, check if the data is already present.
If yes, go back to page and ask for confirmation.
If confirmed, call the click method of the button.
The problem is, when I come back to the page, the inputFileUpload component on the page loses its value.
What can I do to achieve this? Please help.

This is fully by HTML specification and completely outside control of JSF. It's by HTML specification for security reasons not possible to (re)display the value of a HTML input file field with a value coming from the server side. Otherwise a hazard scenario as shown in this answer would be possible.
You need to redesign the form in such way that the input file field is not been updated during confirmation. You can use among others JavaScript/ajax for this: just submit the form by ajax and make sure that the input file field is not been updated on ajax response.

Related

jsf get disabled field values in requestscoped bean

Could you please give me some directions on how to pass values from disabled or readonly input fields in xhtml page to requestscoped bean?
I thought that I can bypass jsf checking the field state by disabling
fields in javascipt code on form open and then submit form, but that
did not help too.
I cannot use view scope, because I would have to set then almost
every page in my application in view scope.
It is very inconvenient to use hidden fields for this purpose,
because it would double the number of fields on the page.
Maybe I have missed some clean solution?
Thank you in advance for any help.
Disabling fields using JavaScript didn't work probably because you didn't enable them just before sending a form. Values of disabled fields are not sent (see input documentation).
For example the following code works perfectly well:
<h:form>
<h:inputText id="disabledinput" styleClass="disabled"
value="#{someBean.property}"></h:inputText>
<h:outputScript>
$('.disabled').attr('disabled', 'disabled');
</h:outputScript>
<h:commandButton action="#{someBean.action}"
onclick="$('.disabled').removeAttr('disabled'); return true;"
value="Submit" />
</h:form>
onclick attribute executes JavaScript code that enables input just before sending the form.
If you use AJAX request you have to restore disabled state using oncomplete or similar.
The problem with this solution is that user can manipulate the value. E.g. she/he can use javascript console in a browser to change the input to enabled or use some tool (e.g. curl) to prepare or tamper request. So if the value is sensitive or should never be changed by the user consider storing the value in the session.
IMHO if the value was provided by the user in one of the previous steps then it doesn't matter that much. However, if value is calculated (like total value or something) you should not depend on its value as users could change it. Personally I would prefer to store the value on server side (in session or in flash).

best practice for communicating between two beans that back the same page

We are making the transition to bootstrap pages. As part of this, we are making most of our dialogs into simple include files that get rendered on demand. The include files have their own backing bean to minimize code duplication.
The typical use case is when a user enters a page a datatable shows a list of things. The user selects one or more rows in the table and then clicks a button to perform an action. The page is re-rendered using ajax. The datatable is not displayed but the former dialog is. The user then does whatever bulk operation the former dialog does and clicks execute (or cancel). The page is then re-rendered with the datatable showing and the former dialog box not.
The problem here is simple; how do you set the render flags on the datatable and former dialog box? Each of the beans needs to set the render flag of the other bean. I blithely tried injecting each bean into the other and promptly got a circular injection error at runtime. I've gone to having a callback interface that the datatable beans implement. When the former dialog bean gets injected, the datatable bean sets itself up to be called back. This works but I am not sure it's the best way to do it. Being an old swing programmer, I considered using property change listeners, which are much more robust than the simple interface, but I'm not sure what the implications of using them in a managed bean environment are. I did check out the messaging API but it clearly doesn't apply to this case.
So, what's the best way for two view beans that are backing the same page to talk to each other?

Set current displayed tab programmatically in p:wizard

Is it possible to set current displayed tab programmatically in <p:wizard>?
For example, I want that for two different request to the same page which contains a wizard, to have a different tab selected.
What I am currently trying to do, is to have a wizard with many tabs, in the second tab I have a redirection to another page, so when I come back I want to come to the last step which caused the redirection.
Can you please help me ? Thank you a lot !
According to primefaces documentation there's a step attribute for p:wizard tag, which specifies the step of the wizard you're currently in.
attribute: step
default value: 0
type: String
description: Id of the current step in flow
You must bind this attribute to a value of your backing bean and maintain it during redirection and coming back. If your wizard's bean is #ViewScoped you'll loose that info during redirection step, so you have to pass it using a view param or flash scope.
My answer would most probably not meet your complete requirements, but, nonetheless, it may point you towards solution to your problem.
As far as I know, the PrimeFaces Wizard UIComponent is designed for a workflow of one page. That effectively means that inputs will be handled by a backing beans that is in a view scope.
This way, making a redirection on a certain step will clear all data inputs, because your view changes and the old one is destroyed.
Anyway, a means of setting a current tab for display is step attribute of Wizard component. So,
<p:wizard step="#{wizardBean.currentStep}" >...</p:wizard>
will force the wizard to show you step which you specified in your bean. You may be able to get it by using, for example, a view parameter, like in
<f:viewParam name="step" value="#{wizardBean.currentStep}" />
But it will make sense if lifetime of your bean is more that for a view, for example, the bean could be put in session scope.
That said, maybe it is a better idea to do login beforehand. Or, if it is absolutely necessary to do it in step 2 of your wizard, provide for a built-in login functionality in a page itself, or in a popular window?
Also, programmatically the setting you speak of can be achieved via a binding of component to your backing bean and setting the step value in the backing bean, for example, in a preRenderView event.

JSF page navigation failing with NullPointerException

I wrote two pages...one a form where data submitted and second just to confirm the transaction actually carried out some calculation.
I have a managed bean i.e. FormDataBean and a class Reservation.java from which i instantiate for each booking made. Now I have at the end of a form a submit button:
<h:commandButton value="Submit" action="confirmation"/>
in the bean I have setters and getters as usual. in a method i defined I create an instance of Reservation, then set the beans variables to the instance variabels, like
reservation.startDate = startDate;
reservation.endDate = endDate;
reservation.checkRange();
The last method, i.e. checkRange() will use the assigned values to instance variables to carry calculation. it should return a string successful or failure.
Now when I enter data in the form, and press submit, it just refreshes the page but nothing is submitted. because it doesn't go to next page :(
Any idea what is happening? I don't need to define a navigation rule, because in other project, I carry out simple calculation and display result in next page and it worsks! Please advice
Thanks,
Your are missing to tell us some of the more important details so the answer is a kind of guesswork.
As you don't use navigation rules I assume you are using JSF 2, aren't you?
With JSF 2 you can directly set the new navigation target, without navigation rules. A forward to "confirmation" should work if your outcome file is named confirmation.xhtml. Check that. With a navigation rule you could forward it do a different file.
This part should work regardless of the rest.
For the bean not getting any values make sure that you are using the correct scope either through annotation or entry in your faces-config.xml. As you have a quite unusal validation mechanism you probably have to use the session scope.
The correct way would be using an actionlistener that does your checks and then sets the navigation depending on your checks. The bean scope could be more restrictive then.
Did you try action="confirmation?faces-redirect=true"?

Audit trail for JSF application - Global valueChangeListener possible?

I am trying to implement an audit trail functionality for my web application that records:
lastModified (timestamp)
modifiedBy (user information)
userComment (reason for value change)
for each of my input fields (input fields are spread over several forms with different backing beans and different valueHolder classes).
The first two (lastModified and modifiedBy) are easily done with the help of an JPA AuditListener and #PrePersit and #PreUpdate methods.
The third one is a bit tricky since it requires user interaction. Best would be a dialog that asks for the user comment.
So there are (at least) two open issues: Can I establish a "global" valueChangeListener for all input fields in my application? Is this possible without attaching <f:valueChangeListener> to each single input component? Second: How can I grab the user comment. My idea is to put a p:dialog in my web page template but this dialog needs to know from which input component it is called.
Can I establish a "global" valueChangeListener for all input fields in my application? Is this possible without attaching to each single input component?
Yes, with a SystemEventListener which get executed during PreRenderViewEvent. You need to walk through the component tree as obtained by FacesContext#getViewRoot() to find all components which are an instanceofEditableValueHolder (or something more finer-grained) and then add the new YourValueChangeListener() by the addValueChangeListener() method. See also this answer how to register the system event listener: How to apply a JSF2 phaselistener after viewroot gets built?
Second: How can I grab the user comment. My idea is to put a p:dialog in my web page template but this dialog needs to know from which input component it is called.
You could in YourValueChangeListener#processValueChange() set the component in question as a property of some request or view scoped which you grab by evaluateExpressionGet().
Recorder recorder = (Recorder) context.getApplication().evaluateExpressionGet(context, "#{recorder}", Recorder.class);
recorder.setComponent(event.getComponent());
// ...
It will execute the EL and auto-create the bean in its scope if necessary. The bean in turn should also hold the property representing the user comment. Finally, you can use it in your <p:dialog>.
<p>You have edited #{recorder.component.label}, please mention the reason:</p>
...
<h:inputText value="#{recorder.comment}" />

Resources