I'm trying to use validateOrder component to validate two java.util.Date objects. It is similar to showcase example on this link (PrimeFaces example). Everything works perfect, but i have one question:
What if 2nd date field is not required?
In that case i'm getting nullpointer exception, and since validateOrder has "disabled" attribute, i was wondering is it worth/possible enabling/disabling it via ajax every time the 2nd date is inserted/removed. If not, i guess i'll stick to Balus' approach for JSF2.0 cross-field validation that you can read about on this link.
Let the disabled attribute check if the 2nd field is filled in. If it's not filled in, the request parameter value associated with field's client ID will be empty. Use exaclty that to let disabled attribute evaluate to true.
<p:calendar ... binding="#{endDate}" />
...
<o:validateOrder ... disabled="#{empty param[endDate.clientId]}" />
Code is as-is. No additional backing bean property necessary for binding.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?
Related
I have an input field which must meet the following restrictions: the input data should have exactly 2 characters, it should accept only letters and numbers, and it must be uppercase. So far, i did the following:
<h:inputText id="code" >
<f:validateLength minimum="2" maximum="2" />
<f:validateRegex pattern="^[a-zA-Z0-9]*$"/>
<f:validateRegex pattern="^[A-Z0-9]*$"/>
</h:inputText>
However, i need individual error messages when any of these validations fails. I did some search, and i found the following UNsuitable solutions:
1) How to customize JSF validation error message : Providing an validatorMessage attribute inside the text tag won't do the job, because this way i can provide only one message per input text tag.
2) http://incepttechnologies.blogspot.ro/p/validation-in-jsf.html : Validation method in the backing bean, or imperative validation using #FacesValidator annotation, are not good because this is exactly what i try to avoid; i want to move validation from back-end to front-end
3) https://www.mkyong.com/jsf2/customize-validation-error-message-in-jsf-2-0/ : overriding the error message in messages.properties is not good for two reasons: 1. I want to use custom error messages only locally (page scope), not for the entire application. 2. I have the same validator tag occuring twice - but with different patterns, and i want a different error message for each situation
The documentation for the validation tags (http://docs.oracle.com/javaee/6/javaserverfaces/2.0/docs/pdldocs/facelets/ and http://docs.oracle.com/javaee/6/javaserverfaces/2.0/docs/pdldocs/facelets/f/validateLength.html) specifies no attribute such as 'message', or 'errorMessage', as I hoped.
I have not tFied Kt but I think a woraround will be to place the custom overridden validation messages in a locale specific (which can be used only for this case ) properties file and use locale attribute of f:view tag to set the locale at the page level so that the messages are displayed from the locale specific message bundle.
A temporary solution is to concatenate all error messages into one big message. In case any validation fails, the corresponding message is anyway included in the big message.
So i made use of the validatorMessage attribute in the inputText tag.
Also, in order not to get the large message multiple times (when more than one of the validations fails) i replaced the 3 validations with an equivalent one:
<f:validateRegex pattern="^[A-Z0-9]{2}$"/>
I built two custom components using built-in CQ components. The components' JSP's, along with some custom javascript, have a line like below in order to leverage the built-in components (and their formatting, labels, etc.).
<cq:include path="." resourceType="foundation/components/form/dropdown" />
I have one each of my custom dropdown components on a form. I can mark field A and field B as both being required in their respective components' editor dialog. I can provide required messages so that when either field is blank and the form is submitted, I get a message that the fields are required (with my custom messages). However, what I really want to do is hide or disable field B based on the value supplied in field A. I'm handling this manually via jQuery. However, this of course presents a problem on validation. I want field B to be NOT required when it is hidden/disabled and for it to be required when it is enabled/visible. Since the showing/hiding is done client-side, the server-side validation has know knowledge of the change and still expect a value to be provided for field B.
I'm been trying to poke around in the CQ Widgets API to find if there is something I can do on the client side to set/unset the required property so that when the form gets posted it is handled correctly. I'm guessing that there isn't since the validation seems to be happening on post instead of client-side.
Any ideas/thoughts/options?
It turns out that the link from my comment gave me the idea that I can have custom server-side validation for my form, I just wasn't sure how to connect it to the field. It turns out that all I had to do was create a servervalidation.jsp file in my "B" component. CQ will see the servervalidation.jsp and automatically invoke it for my custom component.
I was then able to examine the submitted value of field "A" (by getting the parameter from the request object) and doing some other custom logic for my needs.
I was then able to optionally do this:
FieldDescription field = FieldHelper.getConstraintFieldDescription(slingRequest);
FieldHelper.checkRequired(slingRequest, field);
I have a form that contains a Part Number inputText field and some other fields that represent the attributes of a part. If the user enters an existing part number, I want to populate the other fields with the part's existing attributes. The operator then has the option to change Part Number to something else (essentially creating a new part using the existing part as a template) and/or modify its attributes. I have an AJAX event defined to update the model when Part Number changes, so I can retrieve the attributes from the database:
<f:ajax event="valueChange" execute="#this" render="partlength" />
My question is this: How does the Part Number setter (e.g. setPartNumber() ) know whether it is being invoked as part of an AJAX event, in which case I want to fetch the attributes, or as part of the Update Model Values phase of the form being posted, in which case I don't? Or is there a better way to accomplish what I'm trying to do?
You can determine by PartialViewContext#isAjaxRequest() whether the current request is an ajax request or not. You can obtain the PartialViewContext by FacesContext#getPartialViewContext().
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// The current request is an ajax request.
}
An alternative is to just do the job in the listener method of <f:ajax> instead of in the getter/setter (doing business job in getters/setters is a poor practice anyway):
<f:ajax listener="#{bean.listener}" render="partlength" />
(note that I omitted the event and execute attributes as you've used the default values already)
I have a hidden input field, which value is read from a property of the request scope:
<h:inputHidden id="myHiddenField" value="#{requestScope['myVar']}" />
I trigger an Ajax-Request where I change the value of myVar.
<p:commandButton value="submit" action="#{myController.doSomething}" update="myHiddenField">
But my input field still contains the old value.
Any idea how I can solve this?
UPDATE:
Maybe I have to explain it a little bit more.. myVar contains the IDs of all input fields with an error message (facesContext.getClientIdsWithMessages()).
When I first submit the form (with some validation errors) it works as expected. When I resubmit the form with some other validation errors the value of myVar doesn't get updated... (Still contains the IDs of the 'old' errors) When I resubmit the form with no validation errors myVar gets updated. (myVar is empty now)
If you want to access a bean after the page has been loaded it needs to be at least ViewScoped. RequestScoped beans are destroyed when the page is loaded (the request is handled and there is no need for it anymore).
I have some fields on my page which I want cross-validated. But I don't want error from this validation to be displayed in <h:message> for this fields.
If I add validator to any of the fields, and validator throws exception, error is displayed in <h:message> for this field. On the other hand I HAVE TO throw exception if I want to suppress page from submitting. Just displaying some error message is not enough.
So I created some hidden field on the form, and attached validator there. This validator has access to UIComponents of the fields I want to validate, so it can validate them. When validator throws exception, error shows in <h:message> for hidden field, which I can place anywhere I want.
Everything works, if I put hidden field after the fields I want to validate. (If I put it before, hidden field validation is triggered before even UIComponents of my fields are updated).
The problem is it's nasty hack :) Is there some better way to do it?
The problem is it's nasty hack :) Is there some better way to do it?
Not for the particular functional requirement. It's very true that JSF allows very little fine grained control for cross-validation of multiple fields.
Everything works, if I put hidden field after the fields I want to validate. (If I put it before, hidden field validation is triggered before even UIComponents of my fields are updated).
Components are during validations phase processed in the order as they appear in the component tree. If you have at some point an UIInput at hands which is still to be processed yet, then you need to grab the submitted value by UIInput#getSubmittedValue(). If it is already been processed, then you need to grab the submitted (and converted and validated) value by UIInput#getValue() instead.
So, if you put the hidden field with the validator after the to-be-validated components, then you need UIInput#getValue() to grab the values. If the hidden field is put before the to-be-validated components, then you need UIInput#getSubmittedValue() to grab the values.
i have got this code working for me:
throw new ValidatorException(new ArrayList());
no errors were displayed.