Best way to check ajax updates in JSF 2.0?

Our team has been writing our first JSF 2.0 application since using Stripes for many years, and I have some questions about the best way to use the f: ajax tag and validate the input.

A lot of the questions that I saw have a form with several inputs and then a submit button), but we would like individual input fields to be updated immediately after the change and stored in the database (without the submit button. Had this working tone in Stripes using Prototype Ajax.Request, but it was an extra step that I would like to avoid if possible.

Essentially, we have a page with a bunch of inputs on it that beans directly supports, for example:

<h:inputText id="name" value="#{personController.name}" > <f:ajax listener="#{personController.ajax}" /> </h:inputText> 

As you know, by the time the listener is called, the name has already been changed to bean. That would be convenient, but I have a few problems with it:

  • the listener clearly does not know what bean value has been changed
  • the value has already been changed, I can not perform a server side check
  • I don’t know what the old value of the name is, even if I could perform some kind of check on it, I would not know what to return the value to

Right now, it looks like we will need to implement some kind of javascript intermediary in order to accept which property has changed and the new value, send it to the controller and perform its check, update the database, send something to rendering, etc. But, as I said, this is what we did with Stripes, and I would really like to use something more native.

I saw that if we wanted some Submit button on the page, we could use something like the valueChangeListener attribute, but I would also like to avoid bulk messages.

I have included the OpenFaces tag because we already use this for data, so if there is something nice there, we are open to use it. But as far as I can tell, their o: ajax tag is not much more efficient than JSF f: ajax.

Thanks!

+6
source share
1 answer

You are looking for the wrong direction to achieve a specific functional requirement for checking an input field. You should use a regular JSF validator for this, and not some ajax listening method that executes at the wrong time ( INVOKE_ACTION phase instead of the PROCESS_VALIDATIONS phase) and where you do not have a direct binding to the model value. The ajax listener method is simply used to execute some business logic based on the current model values.

JSF has several built-in validators behind the required attribute and several <f:validateXxx> tags. You can even create your own validators by implementing the Validator interface.

eg. validation check:

 <h:inputText ... required="true"> <f:ajax /> </h:inputText> 

Or check if it matches the pattern using one of the various <f:validateXxx> tags :

 <h:inputText ...> <f:validateRegex pattern="[az]+" /> <f:ajax /> </h:inputText> 

Or using a custom validator:

 <h:inputText ...> <f:validator validatorId="myValidator" /> <f:ajax /> </h:inputText> 

from

 @FacesValidator("myValidator") public class MyValidator implements Validator { @Override public void validate(FacesContext context, UIComponent component, Object value) { if (value is not valid) { throw new ValidatorException(new FacesMessage(...)); } } } 

<f:ajax> just to send the current input field during the HTML DOM change event (or click in the case of checkboxes / radio buttons). You don't necessarily need the <f:ajax listener> method to send the current input field using ajax. If you want to connect to the value change event, just use valueChangeListener .

 <h:inputText ... valueChangeListener="#{bean.valueChanged}"> <f:ajax /> </h:inputText> 

from

 public void valueChanged(ValueChangeEvent event) { Object oldValue = event.getOldValue(); Object newValue = event.getValue(); UIComponent component = event.getComponent(); // ... } 

Please note that this will only be called when validation is validated on a specific component.

+11
source

Source: https://habr.com/ru/post/926896/


All Articles