JSF 2 - save all valid component values

I have a requirement to create a javascript function that, when called, will save all valid components in the form of JSF 2.0. Since the full form will never be valid in general, I need to figure out a way to start the life cycle for each component, so that if the validation phase is successful, the model will be updated and ultimately saved.

Ideally, this should be the only ajax request, since iterating over each component using a separate ajax request will be painfully inefficient.

Has anyone solved the problem before? If you could not give me some pointers on possible implementations?

Edit:

Here is what seems to work for me so far:

@ManagedBean(name = "partialAppSaveBean") @RequestScoped public class PartialAppSaveBean implements Serializable { protected static final Logger LOGGER = LoggerFactory.getLogger(PartialAppSaveBean.class); private static final long serialVersionUID = 1L; /** * Save any valid Application values * * @param event */ public void saveData(AjaxBehaviorEvent event) { final FacesContext context = FacesContext.getCurrentInstance(); UIForm form = getParentForm(event.getComponent()); Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED); form.visitTree(VisitContext.createVisitContext(context, null, hints), new VisitCallback() { @Override public VisitResult visit(VisitContext context, UIComponent component) { if (component instanceof UIInput) { UIInput input = (UIInput) component; input.validate(context.getFacesContext()); if (input.isValid() && input.getValue() != null) { ValueExpression valueExpression = input.getValueExpression("value"); if (valueExpression != null && valueExpression.getExpressionString() != null) { try { valueExpression.setValue(context.getFacesContext().getELContext(), input.getValue()); } catch (Exception ex) { LOGGER.error("Expression [ " + valueExpression.getExpressionString() + "] value could not be set with value [" + input.getValue() + "]", ex); } } } } return VisitResult.ACCEPT; } }); //Save data here } /** * Returns the parent form for this UIComponent * * @param component * @return form */ private static UIForm getParentForm(UIComponent component) { while (component.getParent() != null) { if (component.getParent() instanceof UIForm) { return (UIForm) component.getParent(); } else { return getParentForm(component.getParent()); } } return null; } } 

Called with something like:

 <h:commandButton id="saveData"> <f:ajax listener="#{partialAppSaveBean.saveData}" execute="@form" immediate="true" onevent="onPartialSave" /> </h:commandButton> 
+3
source share
1 answer

You can use UIComponent#visitTree() on a UIForm .

 FacesContext context = FacesContext.getCurrentInstance(); UIForm form = getFormSomehow(); Map<String, Object> validValues = new HashMap<String, Object>(); Set<VisitHint> hints = EnumSet.of(VisitHint.SKIP_UNRENDERED); form.visitTree(VisitContext.createVisitContext(context, null, hints), new VisitCallback() { @Override public VisitResult visit(VisitContext context, UIComponent component) { if (component instanceof UIInput) { UIInput input = (UIInput) component; if (input.isValid()) { validValues.put(input.getClientId(context.getFacesContext()), input.getValue()); } } return VisitResult.ACCEPT; } }); 
+2
source

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


All Articles