Wrong label in validator message when switching DynaForms

Community Driven Extensions Project
Post Reply
arnorde
Posts: 6
Joined: 22 Apr 2014, 13:47

10 Sep 2014, 19:49

Hi,

I'm facing an issue with switching dynaforms and form validation. When I validate my form fields in the first dynaform that is rendered every validation message shows up just fine. When I then switch to a different dynaform via an ajax update and validate the form fields the label in the validation messages, e.g for required input fields, is always the label of the last input field of the first dynaform.

View

Code: Select all

<h:form id="myForm">
	<p:outputPanel id="dynaFormGroup">
		<p:selectOneButton value="#{myController.selectedType}" >
			<f:selectItems value="#{myController.typeDefinitions}" var="def" itemLabel="#{def.type}" itemValue="#{def.type}"/>
			<p:ajax event="change" update="dynaPanel" process="@this" />
		</p:selectOneButton>
		<p:outputPanel id="dynaPanel">
			<pe:dynaForm id="dynaForm" value="#{myController.model}" var="data">
				<f:facet name="header"/>
				<pe:dynaFormControl type="input" for="txt">
					<p:outputLabel id="txtLabel" for="txt" value="#{data.type}"/>
					<p:inputText id="txt" value="#{data.value}" validator="#{my.validate}"
						required="#{data.partDefinition.required}" maxlength="#{data.partDefinition.maxLength}" 
						>
						<f:attribute name="validatorId" value="#{data.partDefinition.validatorId}" />
						<p:ajax event="blur" update="txt txtMsg txtLabel" />
					</p:inputText>
					<p:message id="txtMsg" for="txt"/>
				</pe:dynaFormControl>
			</pe:dynaForm>
		</p:outputPanel>
	</p:outputPanel>
</h:form>
Backing Bean

Code: Select all

@Named
@ConversationScoped
public class MyController implements Serializable {
	private DynaFormModel model;
	private String selectedType = "Type1";
	private String lastSelectedType = "";

	@PostConstruct
	public void init() {
		if (model == null) {
			updateModel();
		}
	}

	public DynaFormModel getModel() {
		return model;
	}

	public void setModel(DynaFormModel model) {
		this.model = model;
	}

	public String getSelectedType() {
		return selectedType;
	}

	public void setSelectedType(String selectedType) {
		this.selectedType = selectedType;
		updateModelIfTypeChanged(selectedType);
	}

	private void updateModelIfTypeChanged(String selectedType) {
		if (!lastSelectedType.equals(selectedType)) {
			updateModel();
			resetEditableValueHolders();
			lastSelectedType = selectedType;
		}
	}

	private void updateModel() {
		model = new DynaFormModel();
		List<Part> parts = getParts(selectedType);

		addToModel(parts);
	}

	private List<Part> getParts(String selectedType) {
		List<Part> parts =  new ArrayList<Parts>();
		// create Parts for given type, e.g Type1, Type2
		......
		return parts ;
	}

	private void addToModel(List<Part> parts) {
		for (Part part : parts) {
			DynaFormRow row = model.createRegularRow();
			PartDefinition partDefinition = part.getPartDefinition();
			row.addControl(part, partDefinition.getControlType(), 1, 1);
		}
	}

	/**
	 * Resets the DynaForm component so that input data of value holders with validation errors are reset.
	 */
	public void resetEditableValueHolders() {
		RequestContext.getCurrentInstance().reset("form:dynaPanel");
	}
}
So the label of last control added in addToModel() of the first model that is rendered is used for all other validation error messages for components that are rendered later on via ajax.
Any idea how I can work around that or what is wrong in my code?

Thanks,
Alex

P.S.: I couldn't use the labels provided by the DynaForm Component as they don't have an ID and I didn't find a way to update them. If not updated after ajax validation they stay marked red even though the form might already be valid again.

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

10 Sep 2014, 21:06

I'm not sure what is wrong in your code, but why not create a new model from scratch when switching to another dynaform? It should work if you have two model instances. By the way, regarding Ajax update, there no difference to other data iteration components like p:dataTable, etc. It is a common way to reset fields with RequestContext.getCurrentInstance().reset(...). Maybe you can also execute a custom JS script with RequestContext.getCurrentInstance().execute(...) which removes style classes "ui-state-error".
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

arnorde
Posts: 6
Joined: 22 Apr 2014, 13:47

11 Sep 2014, 09:07

Hi Oleg,
when I use the labels of the dynaform componentn via row.addLabel() etc. then the validation messages work fine, so I'll give it a try to reset the error markers on ajax validation manually.

Still very confused why a outputLabel component in xhtml doesn't work properly. The _ParametrizableFacesMessage args value is always the label of the last input field of the first dynaform. Btw. I always create a new model, please see updateModel(), so no re-usage of old models when switching forms.
Should I eventually include the form-tag in my update as well?

Thanks,
Alex

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

11 Sep 2014, 11:23

Generated label added by row.addLabel() mimics p:outputLabel. The functionality should be the same (I assume this at least). Don't know what is wrong with p:outputLabel.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

Post Reply

Return to “Extensions”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 10 guests