I am facing the problem of immediate = "true" in my project.
I have applied immediate = "true" on search commandLink to By Pass the validation.
but it affects the search functionality.
it does not execute the search method...
what is the problem can anyone explaine...
is there any way to bypass the validation and search the product without using immediate="true"
Thanking in advance
Your functional requirement is still unclear (which brings those contra-questions: Why is the validator there? Why/when do you want to bypass this? Do you have multiple buttons? etc..etc..), so I can't be of more help than recommending you to get yourself through this article to learn about the why of the immediate attribute and to help yourself with the problem: Debug JSF lifecycle.
Here's a summary of relevance:
Okay, when should I use the immediate attribute?
If it isn't entirely clear yet, here's a summary, complete with real world use examples when they may be beneficial:
If set in UIInput(s) only, the process validations phase will be taken place in apply request values phase instead. Use this to prioritize validation for the UIInput component(s) in question. When validation/conversion fails for any of them, the non-immediate components won't be validated/converted.
If set in UICommand only, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s). Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.
If set in both UIInput and UICommand components, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form expect for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required but non-immediate password field.
Related
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?
When I read article Listen and debug JSF lifecycle phases
wrtten by #BalusC, I have some trouble understanding the article.
While Add immediate="true" to UIInput and UICommand, It says:
Note for all components with immediate: as the Update model values phase is skipped, the value bindings aren't been set and the value binding getters will return null. But the values are still available...
Note for other components without immediate: any other UIInput components inside the same form which don't have immediate="true" set will not be converted, validated nor updated, but behind the scenes the inputComponent.setSubmittedValue(submittedValue) will be executed before the action() method will be executed. You can retrieve...
Is that means no matter with or without immediate, the Update model values phase will always skipped because the immediate="true" in the h:commandButton? If so, the value in backing bean will not change, right?
However, in the last paragraph of the article, it summarized "when to use immediate=true" and mentioned:
If set in both UIInput and UICommand components, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form except for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required and immediate username field and a required but non-immediate password field.
I am confused because I thought Process validations Phase and Update model values Phase are skipped no matter there are/aren't immediate once you set immdediate=true in h:commandButton in the same form.
I must misunderstood something, please help me clarify it.
Thanks in advance!
That part indeed needs clarification.
What is meant in the summary, is the job which is normally executed in the mentioned phases (i.e. applying request values, processing validations and updating model values), even though they happen in the apply request values phase.
I have updated the article accordingly.
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"?
I have two input components on my page. Each of them has a converter (It's a converter which checks for empty values, like JSF required one, but for some reasons I cannot use jsf one so I've made my own converter).
I also have a ice:selectBooleanCheckbox:
<ice:selectBooleanCheckbox
styleClass="graUserAppUserGroupAddChk"
value="#{userGroupTableNewRecordBean.addNewDomain}"
partialSubmit="true"
immediate="true"
valueChangeListener="#{userGroupTableNewRecordBean.addDomainListener}"></ice:selectBooleanCheckbox>
As you see I put immediate=true attribute on it, becase when I select this checkbox I do want the conversion phase to be skipped but it does not work, the converters still show their warnings. Do you know why?
I also add a valueChangeListener on this checkbox and called there the renderResponse directly, based on this quote:
So in the value changed listener method for the dropdown lists, just
call renderResponse() from the
FacesContext object and validation and
conversion is bypassed and you can
still do what you want.
public void addDomainListener(final ValueChangeEvent valueChangeEvent) {
// skip validation
logger.info("listener calleddddddddddddd");
FacesContext.getCurrentInstance().renderResponse();
}
Maybe a JSF guru can help?
Thanks a lot...
UPDATE: I know that a solution would be to put the checkbox in a separate form but I cannot afford this...
UPDATE 2: I've corrected some code about listener, so now it is called when clicked but still the converter fails and render response phase is not done...
UPDATE 3: This is not an icefaces issue... I've tried with a h:selectBooleanCheckbox and it happens the same...
The whole question and the functional requirement behind this all is pretty confusing. Why are you using a converter instead of a validator to validate the inputs? Why are you using a converter/validator if you don't seem to care about the conversion/validation outcome?
As you see I put immediate=true attribute on it, becase when I select this checkbox I do want the conversion phase to be skipped but it does not work, the converters still show their warnings.
Putting the immediate="true" on input components does not skip conversion/validation. They just shifts conversion/validation to an earlier phase (i.e. it takes place in apply request values phase instead of validations phase). You basically need to remove immediate="true" from those inputs and put it on the command link/button in order to skip conversion/validation of those inputs. See also Debug JSF lifecycle:
Okay, when should I use the immediate attribute?
If it isn't entirely clear yet, here's a summary, complete with real world use examples when they may be beneficial:
If set in UIInput(s) only, the process validations phase will be taken place in apply request values phase instead. Use this to prioritize validation for the UIInput component(s) in question. When validation/conversion fails for any of them, the non-immediate components won't be validated/converted.
If set in UICommand only, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s). Use this to skip the entire processing of the form. E.g. "Cancel" or "Back" button.
If set in both UIInput and UICommand components, the apply request values phase until with update model values phases will be skipped for any of the UIInput component(s) which does not have this attribute set. Use this to skip the processing of the entire form expect for certain fields (with immediate). E.g. "Password forgotten" button in a login form with a required but non-immediate password field.
Solved it finally...
I post here the sum up of the question and the solution.
I had a checkbox in my popup. When I select it I want to show some hidden fields but this did not work because I also had two required fields on the same page so jsf PROCESS_VALIDATIONS phase came up...
I thought that putting immediate=true will solve this, but it did not...
So, in my ValueChangeListener of the checkbox I had to manually skip the jsf validation phase:
public void addDomainListener(final ValueChangeEvent valueChangeEvent) {
// skip validation
final PhaseId phaseId = valueChangeEvent.getPhaseId();
final Boolean newValue = (Boolean) valueChangeEvent.getNewValue();
if (phaseId.equals(PhaseId.ANY_PHASE)) {
valueChangeEvent.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
valueChangeEvent.queue();
this.addNewDomain = newValue;
FacesContext.getCurrentInstance().renderResponse();
}
}
If I have many input controls in a form (There are separate validators for each of these input controls - like required,length and so on ) , there is a command button which submits the form and calls an action method. The requirement is - though the input control values are , say , individually okay - the combination of these values should be okay to process them together after the form submission - Where do i place the code to validate them together?
1) Can i add a custom validator for the command button and validate the combination together? like validate(FacesContext arg0, UIComponent arg1, Object value) but even then I will not have values of the other input controls except for the command button's/component's value right ?
2) can i do the validation of the combination in the action method and add validation messages using FacesMessage ?
or do you suggest any other approach?
Thanks for your time.
Point 2 is already answered by Bozho. Just use FacesContext#addMessage(). A null client ID will let it land in <h:messages globalOnly="true">. A fixed client ID like formId:inputId will let it land in <h:message for="inputId">.
Point 1 is doable, you can grab the other components inside the validator method using UIViewRoot#findComponent():
UIInput otherInput = (UIInput) context.getViewRoot().findComponent("formId:otherInputId");
String value = (String) otherInput.getValue();
You however need to place f:validator in the last UIInput component. Placing it in an UICommand component (like the button) won't work.
True, hardcoding the client ID's is nasty, but that's the payoff of a bit inflexible validation mechanism in JSF.
I've just landed on your post after having the same question.
Articles I have read so far identify that there are four types of validation for the following purposes:
Built into the Components (subscribe to individual fields; required=true, LengthValidator, etc)
'Application Validation' added to the Action in the Backing Bean (Business Logic)
Custom Validators (subscribe to individual fields)
Method in the Backing Bean used as a Custom Validator (subscribe to individual fields).
With reference to Validators: The validation mechanism in JSF was designed to validate a single component. (See S/O Question here)
In the case where you want to validate a whole form as a logical grouping of fields, it appears with standard JSF/Apache MyFaces that the most appropriate to do it is as Application Validation, as the set of individual fields take on a collective business meaning at this point.
BalusC has come up with a way of shoehorning form validation into a single validator attached to the last form item (again, see S/O Question here and another worked example on his website here) however it isn't necessarily extensible/reusable, as the references to the ID's of the form have to be hardcoded as you can't append to the validate() method's signature. You'll get away with it if you're only using the form once, but if it pops up a few times or if you generate your ID's programmatically, you're stuck.
The JSF implementation portion of Seam has a <s:validateForm /> control which can take the IDs of fields elsewhere in your form as parameters. Unfortunately, it doesn't appear that any of the MyFaces/Mojara/Sun JSF implementations have an equivalent as it isn't part of the standard.
I've successfully used the 2nd approach:
FacesMessage facesMessage =
new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);