I have a series of q-expansion-item
s each of which contains a group of inputs, all part of a single overall form:
<q-form @validation-error="onValidationError">
<q-expansion-item>
<field-group-1 />
</q-expansion-item>
<q-expansion-item>
<field-group-2 />
</q-expansion-item>
...
</q-form>
The inputs use rules
-based validation, and I'm calling validate
on the form before proceeding.
This works, but if the invalid input is inside a closed q-expansion-item
the user doesn't have any way of knowing which input failed. I'd like to trigger the relevant q-expansion-item
to show itself in this case.
Right now I'm using a super hacky approach, which works but is really fragile -- I'm catching the failing input then walking up the component hierarchy until I identify the q-expansion-item
via duck typing:
function onValidationError(ref: any) {
let parent = ref.$parent;
while (parent && !parent.show) {
parent = parent.$parent;
}
if (parent?.show) {
parent.show();
}
}
Is there a better way to do this?
A ref based solution would be a more Vue-centric approach. It's not too dissimilar and still involves a loop but I think a less fragile one.
Add refs to expansion items:
<q-form @validation-error="onValidationError">
<q-expansion-item ref="group1">
<field-group-1 />
</q-expansion-item>
<q-expansion-item ref="group2">
<field-group-2 />
</q-expansion-item>
...
</q-form>
Use for
loop to find if any expansion-item ref contains the invalid component
const group1 = ref()
const group2 = ref()
onValidationError(invalidComp) {
const expansionRefs = [group1, group2];
for (const expansionItem of expansionRefs) {
if (expansionItem.value.$el?.contains?.(invalidComp.$el)) {
expansionItem.value.show();
break;
}
}
}