JSF component value not properly updated to model upon submit - jsf

I have facelets page with a control that usually is disabled by default, i. e. when the page is first rendered to the client. This is determined by an EL expression:
disabled="#{referenceValue != requestbean.dependentControlValue}" id="notWorking"
After the page is rendered, the user can set the requestbean.dependentControlValue to referenceValue and via some Javascript for the dependent control, the component "notWorking" is enabled.
However, upon submitting the form the value for notWorking does not get updated as found out by adding a debug log message in the setter for the value. I can see, that the value for notWorking is set in the request when inspecting it with firefox.
Question:
What am I doing wrong?
By the way:
I know that according to HTML specification, disabled controls cannot be successful thanks to the research here on StackOverflow.
Moreover, I know from this post, that the disabled and rendered expressions are considered before updating the model values, but I think the disabled expression should evaluate to false upon submitting the form.

What am I doing wrong?
Using JavaScript instead of JSF to re-enable the input.
As part of JSF's builtin safeguard against tampered/hacked HTTP requests, the disabled attribute is (like rendered and readonly attributes) re-evaluated during processing the form submit. If they evaluate in such way that the value shouldn't be processed at all (i.e. disabled/readonly=true and rendered=false, then the submitted value won't be applied, converted, validated and the model won't be updated.
The solution would be to use JSF instead of JavaScript to re-enable the input, or to rewrite the condition in disabled attribute in such way so that the disabled attribute evaluates false during processing the form submit.

Related

Rendered attribute executing before button action

I have two view htmls(V001 & V002) both of which are to be rendered using the same jsf page. There is a continue button in my JSF Page which performs the action of storing the V001 DOM in Cache and fetches the V002 from Content server and displays it to the user. This is achieved through a managed bean.
In view V002, I have a button which I need to be rendered based on whether the view is V002 or not.
However the issue is the rendered condition is executing before the continue action and hence always evaluate to false since the view change from V001 to V002 happens only when the continue button action is executed.
NB: My bean is request scoped and I am using JSF 1.1

Debugging JSF Life Cycle - what exactly happens in each phase

I have decided to dig completely into JSF 2.0 as my project demands deep knowledge of it. I am reading JSF Lifecyle Debug, a well written and awesome article on JSF Life cycle. While reading this article, I have following confusions.
If it's an initial request, in Restore View Phase an empty View is created and straight Render Response Phase happens. There is no state to save at this point. What actually happens in render response phase then? I am confused a little while I am running the example.
The article states that, retrieved input value is set in inputComponent.setSubmittedValue() in Apply Request Values phase. If validation and conversion passes, then the value gets set in inputComponent.setValue(value) and inputComponent.setSubmittedValue(null) runs. On same point article states that, now if in the next post back request, value is changed, it is compared with the submitted value which would always be null on every post back, value change listener will be invoked. It means if, we don't change the value even, as submittedValue would be null, valueChangeListener will always be invoked? I am confused on this statement. Can someone elaborate on this?
Article states the usage of immediate attribute. If immediate attribute is set on an input component, than ideally Process Validation Phase is skipped, but all of the conversion and validation happens in Apply Request Values. My point is, still when the conversion and validation is happening, what's the advantage of skipping the third phase?
What does the term retrieved value means?
I would like to know, if lets say there are five fields on the view. Does JSF makes a list of some collection of these values and Apply Request Values and Process Validations phase iterate over them one by one?
At the last point of this article where it states, when to use immediate attribute. As per my understanding, if immediate attribute is set in both input component and command component, It will skip the phases from Apply Request Values to Invoke Application for any attribute not having immediate. Then what does the last statement mean "Password forgotten" button in a login form with a required and immediate username field and a required but non-immediate password field.
I know these are very basic confusions but clarity on these topics will definitely help sharpen the JSF knowledge.
1: What actually happens in render response phase then?
Generating HTML output for the client, starting with UIViewRoot#encodeAll(). You can see the result by rightclick, View Source in webbrowser (and thus NOT via rightclick, Inspect Element in webbrowser, as that will only show the HTML DOM tree which the webbrowser has built based on the raw HTML source code and all JavaScript events thereafter).
2: it is compared with the submitted value which would always be null on every post back
Nope, it's being hold as an instance variable. JSF doesn't call getSubmittedValue() to compare it.
3: My point is, still when the conversion and validation is happening, what's the advantage of skipping the third phase?
This is answered in the bottom of the article, under Okay, when should I use the immediate attribute?. In a nutshell: prioritizing validation. If components with immediate="true" fail on conversion/validation, then components without immediate="true" won't be converted/validated.
4: What does the term retrieved value means?
The "raw" value which the enduser has submitted (the exact input value which the enduser entered in the input form). This is usually a String. If you're familiar with servlets, then it's easy to understand that it's exactly the value as you obtain by request.getParameter().
5: Does JSF makes a list of some collection of these values and Apply Request Values and Process Validations phase iterate over them one by one?
Almost. The collection is already there in flavor of the JSF component tree. JSF thus basically iterates over a tree structure, starting with FacesContext#getUIViewRoot().
6: Then what does the last statement mean "Password forgotten" button in a login form with a required and immediate username field and a required but non-immediate password field.
This way you can reuse the login form for the "password forgotten" case. If you submit the "login" button, then obviously both the username and password fields must be validated. However if you submit the "password forgotten" button, then the password field shouldn't be validated.
That said, you may find the below JSF phases/lifecycle cheatsheet useful as well for a quick reference:
fc = FacesContext
vh = ViewHandler
in = UIInput
rq = HttpServletRequest
id = in.getClientId(fc);
1 RESTORE_VIEW
String viewId = rq.getServletPath();
fc.setViewRoot(vh.createView(fc, viewId));
2 APPLY_REQUEST_VALUES
in.setSubmittedValue(rq.getParameter(id));
3 PROCESS_VALIDATIONS
Object value = in.getSubmittedValue();
try {
value = in.getConvertedValue(fc, value);
for (Validator v : in.getValidators())
v.validate(fc, in, value);
}
in.setSubmittedValue(null);
in.setValue(value);
} catch (ConverterException | ValidatorException e) {
fc.addMessage(id, e.getFacesMessage());
fc.validationFailed(); // Skips phases 4+5.
in.setValid(false);
}
4 UPDATE_MODEL_VALUES
bean.setProperty(in.getValue());
5 INVOKE_APPLICATION
bean.submit();
6 RENDER_RESPONSE
vh.renderView(fc, fc.getViewRoot());
See also:
Difference between Apply Request Values and Update Model Values
JSF - Another question on Lifecycle
What's the view build time?

What is the difference between partialSubmit and autoSubmit in JSF?

I guess I knew the difference, but right now I find myself confused. :P
Both of them seem to be do the same thing, except that partialSubmit is used on submit buttons to submit the form using AJAX and autoSubmit is used on editable components, which submits only its own contents. Am I right in saying this?
The accepted answer isn't 100% correct for ADF. The partialTriggers attribute is involved in the lifecycle.
From Enabling Partial Page Rendering Declaratively
The autoSubmit attribute on an input component and the partialSubmit
attribute on a command component are not the same thing. When
partialSubmit is set to true, then only the components that have
values for their partialTriggers attribute will be processed through
the lifecycle. The autoSubmit attribute is used by input and select
components to tell the framework to automatically do a form submit
whenever the value changes. However, when a form is submitted and the
autoSubmit attribute is set to true, a valueChangeEvent event is
invoked, and the lifecycle runs only on the components marked as root
components for that event, and their children. For more information,
see Section 4.4, "Using the Optimized Lifecycle".
They are both AJAX enabled calls occurring from custom properties of custom JSF components. The autoSubmit essentially asynchronously postsback content specific to the component for keeping the server side managed bean values current with the content within the component on the client side.
A partialSubmit is another asynchronous AJAX call that will serve to immediately postback a component value on some kind of component event, like losing focus on an ICEFaces inputText component for example.
The interesting thing to note is that the entire ViewState is posted back on each type of asynchronous submit, so if the values of other components HAD changed on the page before the submit, the bound server side managed bean properties will have their values refreshed as well, even though the client side components MAY not be refreshed to reflect any server side data changes that may have occurred.
In fact, the entire JSF server side lifecycle occurs on each postback, read the following article on implementing a debug PhaseListener that allows you to see what Phases are occurring after each asynchronous submit operation occurs.
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html

how to distinguish a jsf action or direct url link invoked the page

I have a situation, I have a session bean with list, this list I show in html data table. When the user hits the url from browser or normal href, I have to show all records. There is provision to search for the data also, where I have to show the filtered list. Now after a user has made the search, the list contains filtered records and after doing this he leaves the page to some other, and now if the user hits the url or uses the menu to come back to this page, since I have this list in session bean, I still have the filtered list.
Since there is no default action in JSF 1.1 or 2.0 preRenderView concept, its difficult to clear the list and get non filtered data(all results) again. Even tricks in getList() method fail to accomplish the task.
I have planned to use phase listener, as when a user reaches a page via href or url hit in browser, invoke application phase does not happen. I can toggle boolean variable in my session bean and in getList() I can perform some trick to check it was url,href hit or by command button.
Hope I have made myself clear. In short I have to identify in my bean whether the request came directly from href,browser or an action. If search action filter records for data table if not keep list cache and keep showing it as long as search is not made.
Just guide me whether I am doing things in right way or thinking too much or can it be done in much more efficient way.
Thanks in advance.
Well platform is jsf 1.1 in weblogic portal 10.3 .....
JSF 1.x actions use by default POST method. Direct links/bookmarks/etc are by nature GET method. Since there's no ResponseStateManager#isPostback() or FacesContext#isPostback() in JSF 1.1, you have to determine the request method yourself:
HttpServletRequest request = (HttpServletRequest) facesContext.getExternalContext().getRequest();
boolean postback = "POST".equalsIgnoreCase(request.getMethod());
Or check for a certain parameter in the request parameter map, but I can't tell from top of head which one you'd like to check. You've to determine it yourself.
boolean postback = facesContext.getExternalContext().getRequestParameterMap().containsKey(SOME_KEY);
If postback is true, then a JSF action is been invoked.

How to call an action method of a UICommand Component which was rendered conditionally?

action method is not called Please refer to this question - , One of my UICommand Component is rendered conditionally , it was said in the answer of the linked question - point 5 - that if the Component's or any of its parents rendered or disabled attributes are false - then the action method will not be called ? If thats the case- How do i achieve the same functionality? Is there a work around ? or a trick ? or any other approach ?
Thanks!
To the point, you'd like to retain the property responsible for the rendered condition in the subsequent request. There are several solutions for this problem:
Put bean in session scope. It's easy, but it hurts. It's bad for user experience since changes will be reflected in all tabs/windows the user has open in the same session.
Use <h:inputHidden> to transfer the property. In theory easy, but in practice it hurts as well. The value will namely get lost whenever a validation/conversion error has occurred in any of other inputs in the same form. This is an odditity in how JSF handles hidden input elements. A workaround is to use <h:inputHidden binding="#{bean.hidden}"> and do a hidden.getValue() and hidden.setValue() in bean.
If you're using <h:commandLink> instead of <h:commandButton>, then you can use <f:param> to transfer the property. It will be available as request parameter, you can check for it in bean's (post)constructor.
Use Tomahawk's <t:saveState>. The perfect solution as far. This will retain the value (or even a complete bean) in the subsequent request.
If you're already on JSF 2.0, the #ViewScoped would have solved this all. It behaves like the <t:saveState>.
See also:
commandButton/commandLink/ajax action/listener method not invoked or input value not updated
The trick is to have 'rendered' evaluate to true when it is time to run the action and then change the condition to false in the action method.
Let's say you have a link rendering based on a boolean in your bean called 'editing'. Then your action would look something like this:
public String myAction() {
// whatever you want your action to do
editing = false;
}
Edit: this assumes that the bean is either session scoped or the boolean get propagated between requests.
In my case, Javascript came for rescue, Which means, whatever was to be displayed conditionally , put them in a HTML Portion and don't display them display: none until the desired event occurs.
HTML Portion can have any JSF Tags(including CommandButtons) as you wish and would work (invoking the action methods and the stuff )perfectly okay.

Resources