I have an OpenUI5 form consisting of a number of Inputcontrols. These Inputcontrols are bound to a model using the OpenUI5 DataBinding as described in the documentation. For example:
new sap.m.Input({
value: {
path: "/Position/Bezeichnung",
type: new sap.ui.model.type.String(null, {
minLength: 1,
maxLength: 128
})
}
})
As in the example above I'm using constraints on the stringlength. When a User changes the Value of the Input, the Validation is triggered and according to the Validationresult one of the functions descripted here is called. In these functions I'm setting the ValueState of the control like this:
setupValidation: function() {
var oCore = sap.ui.getCore();
oCore.attachValidationError(function (oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.Error);
});
oCore.attachValidationSuccess(function (oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.None);
});
oCore.attachFormatError(function (oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.Error);
});
oCore.attachParseError(function (oEvent) {
oEvent.getParameter("element").setValueState(sap.ui.core.ValueState.Error);
});
},
Let's assume the bound model variable is initial. I'm loading the view, the property value is parsed and displayed as empty. The Validationerror/Parseerror method is not called although the constraints are not met. This seems to be standard behaviour of OpenUI5. Only changes in the Control will be a validated.
Now let's assume I've a submit button and the Value of the Inputcontrol is still empty. When the user hits the submit button I'd like to trigger the DataBinding Validation for all childcontrols of my view. This would validate the above mentioned input and would result in an errorstate.
My question is: How can I trigger the databinding validation for all childcontrols of my view?
There is another question on SO where the poster asks for a way to define required fields. The proposed solution is to call getValue() on the control and validate the value manually. I think this is kind of cumbersome as formating and constraint information and logic is already present.
I suggest looking into field groups.
An example here in the UI5 docs
Field Groups allow you to assign group IDs to the input fields. Then you can call all of the input fields at once. You can set the name
property and required
property on each <Input>
separately in your view, allowing you to handle some logic when you perform validation.
You can call this.getView().getControlsByFieldGroupId("fieldGroupId")
, which will return an array of the input controls. Then you can loop through the controls, pass them through your logic, and use setValueState()
to show the results.
Or, you can assign the validateFieldGroup
event on the parent container, which is usually a form, but can be anything like a <VBox>
that contains the controls. When the users focus moves out of the field group, the event is fired. You can then use the event handler in your controller to perform the validation.
In your case, I would assign a press
event to your submit button, and in the handler, call the field group by ID and loop through the controls. At the end of your function, check to see if all fields are validated before continuing.
View
<Input name="email" required="true" value="{/user/email}" fieldGroupIds="fgUser"/>
<Input name="firstName" required="false" value="{/user/firstName"} fieldGroupIds="fgUser"/>
<Button text="Submit" press="onSubmit"/>
Controller
onSubmit: function() {
var aControls = this.getView().getControlsByFieldGroupId("fgUser");
aControls.forEach(function(oControl) {
if (oControl.getRequired()) {
//do validation
oControl.setValueState("Error");
oControl.setValueStateText("Required Field");
}
if (oControl.getName() === "firstName") {
//do validation
oControl.setValueState("Success");
}
});
var bValidated = aControls.every(function(oControl) {
return oControl.getValueState() === "Success";
});
if (bValidated) {
//do submit
}
}