I have a text field and a validator as shown below. It uses p:ajax to submit the value the moment it is changed, and the validator stops the submission if the field does not pass. The user gets the error message as expected (which is what update="msgs .." does).
However when it doesn't pass I want to reset the value to what it was before.
<p:inputText id="txtName"
value="#{workspace.selectedPath.name}"
style="width: 20%"
validator="validateName"
valueChangeListener="#{workspace.doNameChanged}"
>
<p:ajax update="msgs formTree" />
</p:inputText>
The following link shows how to use the p:resetInput tag in PrimeFaces, but it doesn't work as part of p:inputText because it is not an ActionSource. If you make it a child of the p:ajax tag it is just ignored. Any suggestions?
How to reset input fields in a form after validation fail when updating it with new values
Since PrimeFaces 4.0, you can use <p:ajax resetValues> for this.
<p:inputText ...>
<p:ajax ... resetValues="true" />
</p:inputText>
See also:
How can I populate a text field using PrimeFaces AJAX after validation errors occur?
Related
I want to pass data to back bean through ajax call on command button click.
I have a form with couple of input text fields where each field is having ajax blur event.
Every thing is working fine in happy flow except in the flowing scenario.
Ajax blur event is invoking when i directly clicking on submit which is suppose to be happen before submit click, hence i should make another click on submit button to invoke ajax call to save my form.
Here is the code.
Input text fields:
<p:inputText id="txt_name"
value="#{partnerVO.partnerName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_name" preventPaste="false" />
<p:ajax update="txt_name" event="blur" />
</p:inputText>
<p:inputText id="txt_assigned"
value="#{partnerVO.assignedName}"
required="true" maxlength="30"
rendered="#{!partnerVO.isReadOnly}">
<p:keyFilter regEx="/[A-Za-z0-9#.,&- ]/i"
for="txt_assigned" preventPaste="false" />
<p:ajax update="txt_assigned" event="blur" />
</p:inputText>
Command Button:
<p:commandButton id="btn_save"
title="Save"
value="#{lbl['tpdetails.remove.additional.address']}"
update="#form" process="#this"
action="#{partnerDetailsController.save}">
</p:commandButton>
I'm using JSF 2.2
Please provide some suggestions to overcome this strange behavior.
Note: omitted form related code here.
I've got the code below. I removed facets and similar tags, to make it more readable. I highly doubt they are the issue. I'm using Primefaces 6.1 for all tags, except the form tag is Omnifaces.
<h:form id="form">
<p:dataTable id="table" value="#{data.rows}" var="row" rowIndexVar="index">
<p:column id="ajaxColumn" rendered="#{true}">
<p:inputText id="ajaxValue" value="#{row.ajaxValue}">
<p:ajax event="blur" process="#this" update="#this form-table-#{index}-targetColumn" listener="#{bean.ajaxMethod(index)}"/>
</p:inputText>
<p:column>
<p:column id="targetColumn"rendered="#{true}">
<p:inputText id="targetValue" value="#{row.targetValue}"/>
</p:column>
</p:dataTable>
</h:form>
I want to update the 'targetValue' inputText with a new value, after the 'ajaxValue' inputText deselection caused a blur event. The ajax call should send the value inside 'ajaxValue' to the backend and set the 'targetValue' in the bean accordingly. After that the 'targetValue' should update with the new value.
My problem is that when I add "form-table-#{index}-targetColumn" to the update attribute of the ajax tag, the 'targetValue' remains empty from the start. It has no value on the frontend. If I add "form-table-0-targetColumn" instead, only the first 'targetValue' won't have a value.
Looking at the getter calls while debugging, their behavior is identical, whether I have the update attribute or not.
Any ideas?
EDIT: To clarify. The separators in the ID are meant to be '-', not ':', as they are usually, I believe.
In a datatable you cannot use the index to update in rows. If you want to update some element that is in the same row, You should just use update="targetColumn".
(There must be a duplicate of this somewhere, but I cannot find it and until I do, I'll leave this answer here
Here is my configuration:
PrimeFaces: 4.0.4 (elite)
OmniFaces: 1.6.3
JSF: MyFaces 2.0.2
Server: WebSphere 8.5.0.2
Some code (I only post the relevant part for better clarity):
<p:selectOneMenu value="#{viewModel.selectedContact}" required="true" converter="omnifaces.SelectItemsConverter">
<p:ajax event="change" listener="#{viewModel.updateContact}" update="area"/>
<f:selectItem itemValue="#{null}" itemLabel="#{msg.no_contact}" noSelectionOption="true" />
<f:selectItems value="#{viewModel.contacts}"/>
</p:selectOneMenu>
So here, we have a simple p:selectOneMenu that contains a list of Contact objects as well as a "No Contact" option. This field is required if I want to submit the form.
When a contact is selected in the list, the updateContact method is called. This method will generate data that will be displayed in the area section of the page updated by the AJAX call.
If I select the "No Contact" option, a validation error is triggered as this field is required, so the updateContact method is not called. I would like the method to be called as I would need to reset some data then hide the area section of the page.
I have tried using process="#this", immediate="true", but it doesn't work. With immediate="true", the selected Contact is not passed to the updateContact method.
So, what is the best way to bypass the validation of this field when selecting a null value?
Let the required attribute check if the command button is invoked. You can check that by the presence of the button's client ID in the request parameter map.
<p:selectOneMenu ... required="#{not empty param[save.clientId]}" />
...
<p:commandButton binding="#{save}" ... />
(note: code is as-is, you don't need a bean property for this)
If the command button is not invoked (but instead the ajax change listener is invoked), then the required attribute will evaluate false and everything will go as you intented.
Update: as per the comments, you intend to make them appear like required during render response all time. So, just add that check:
<p:selectOneMenu ... required="#{not empty param[save.clientId] or facesContext.currentPhaseId.ordinal eq 6}" />
...
<p:commandButton binding="#{save}" ... />
I have a problem with a JSF 2 form that contains an ajax field. When I use the mouse to press the submit button of the form while the cursor is still in the ajaxified input field the input value of the field does not get submitted before the action is triggered in the backing bean. Also the attached validator and converter are not triggered.
<h:form id="invoice">
...
<h:inputText value="#{invoiceBean.amount}" required="true" validator="#{invoiceBean.validateAmount}">
<f:converter converterId="CurrencyConverter" />
<f:ajax event="blur" render="#this"/>
</h:inputText>
<h:commandButton action="#{invoiceBean.processInvoice()}" />
</h:form>
I also tried to enhance the command button with <f:ajax /> but the result stayed the same. Other (non-ajax) fields on the same form (not shown in the code snippet above) are submitted correctly. The ajax field is also submitted, converted and validated if I click somwhere else on the page before submitting but not when using the button directly.
Is there anything I am missing to have the field also be submitted on/before form submit?
Regarding the <h:inputText> ajax behaviour: use <f:ajax> with the default event valueChange, which is the default event for all input components. This is indeed equivalent to omitting the event attribute:
<f:ajax render="#this" />
Regarding the <h:commmandButton> component, don't forget to specify the execute attribute of <f:ajax>:
<f:ajax execute="#form" />
otherwise it will default to #this, therefore rendering vane your effort.
I have a h:selectOneListbox which has the attribute required="true". Client side validation with a4j:ajax works fine.
If a valid selection is done, another panelgroup is rendered.
Example:
<h:selectOneListbox
....
id="first"
....
required="true"
>
<a4j:ajax event="valueChange" render="secondGroup" listener="#{myController.anotherMethodINeed}"/>
</h:selectOneListbox>
<!-- the other panel -->
<h:panelGroup id="secondGroup" layout="none">
<h:panelGroup id="secondGroupCheck" layout="none" rendered="#{not empty model.first}">
</h:panelGroup>
</h:panelGroup>
This also works.
Here's the problem:
If the user now selects a illegal value on the first select box (like an empty one), then input is validated on client side. Hence the information never makes it to the model. After the first valid input, the panel is always rendered. There is no way to make it disappear again, since the server does not know of the change.
The only workaround I know is to make a custom validator for such a field. The validator sets then a flag if the panel needs to be rendered. This flag can then be used to decide if the panelgroup should be rendered.
Is there not a smarter way to do this?
I know that I can use something like rendered="#{not facesContext.validationFailed}" to check all the field, but I do not know a method to check just one field.
If an UIInput component throws a ValidatorException during validations phase, then JSF will automatically call UIInput#setValid() with false. This thus means that you can use UIInput#isValid() in the view to check if the particular component has passed validation or not.
You can use the binding attribute to bind an UIInput component to the view and then access all its properties the usual EL way.
<h:selectOneListbox id="first" binding="#{first}" ... required="true">
...
<a4j:ajax listener="#{myController.anotherMethodINeed}" render="secondGroup" />
</h:selectOneListbox>
<h:panelGroup id="secondGroup">
<h:panelGroup id="secondGroupCheck" rendered="#{not empty model.first and first.valid}">
...
</h:panelGroup>
</h:panelGroup>
By the way, the layout="none" is an invalid attribute for <h:panelGroup>, so I omitted it. Also, the event="valueChange" is the default already for <a4j|f:ajax> inside UIInput components, so I omitted it.