Rescanning dynamic inputs does not detect that they are new
RyanONeill1970 opened this issue · comments
I have a form with radio buttons. The buttons have validation on them to ensure one is always selected.
When those buttons are changed / checked, they are dynamically reloaded from the server with new text but the same name / id.
On trying to run validation I hit an error (element.form is null) as the element that is held within aspnet-client-validation no longer has a form attached. The element on the page does though. A longer trace for the error is below.
I tried doing a v.scan(form) as suggested to refresh the lib with the new inputs, but it seems it thinks it already has them as I get lots of 'already tracked' messages such as;
- Validation element for 'xxxxx' is already tracked
- Form input for UID 'yyyyy' is already tracked
Perhaps I need to remove the fields first, so I tried variations such as;
v.remove()
v.scan(form,true);
Followed by another v.scan(), but this fails with the following. I suspect it is because the validators are still there but the elements are not.
Uncaught (in promise) TypeError: root is undefined
scanMessages aspnet-validation.js:742
remove aspnet-validation.js:1364
Initial error without attempting to scan or remove;
Validation error TypeError: element.form is null
required aspnet-validation.js:216
ValidationService aspnet-validation.js:1254
step aspnet-validation.js:142
verb aspnet-validation.js:123
__awaiter aspnet-validation.js:117
__awaiter aspnet-validation.js:113
ValidationService aspnet-validation.js:1230
tasks aspnet-validation.js:892
getFormValidationTask aspnet-validation.js:892
cb aspnet-validation.js:949
trackFormInput aspnet-validation.js:988
addInput aspnet-validation.js:1050
scanInputs aspnet-validation.js:1103
scan aspnet-validation.js:1357
init aspnet-validation.js:1336
bootstrap aspnet-validation.js:1344
Init validation-bootstrap.ts:27
<anonymous> validation-bootstrap.ts:32
I can work around this by using { watch: true } on the bootstrap. Which is great, but how should I be doing this if I do it manually?
I can create a repro if needed. If it is decided it is an edge case and you'd like me to submit a PR, I can do that. I just need some direction as I'm not sure of the codebase.
Thank you,
Ryan
A repro and PR are both very welcome.
Perhaps I need to remove the fields first, so I tried variations such as;
v.remove() v.scan(form,true);
Followed by another v.scan(), but this fails with the following. I suspect it is because the validators are still there but the elements are not.
Uncaught (in promise) TypeError: root is undefined scanMessages aspnet-validation.js:742 remove aspnet-validation.js:1364
remove()
currently requires you to pass in the node to scan for removal:
aspnet-client-validation/src/index.ts
Lines 1392 to 1396 in 062c843
I expect this would work:
v.remove(form);
v.scan(form);
I'm also about done with a PR for #100 that may improve remove()
behavior.
But generally what you observe is expected: for performance reasons we remember validatable element by name
per form
, without a prescribed pattern for situations where those elements are replaced.
Apologies both and thanks for your fast replies. I have found the issue. It appears that the input elements when recreated were done so in JavaScript and the validation was not added. I've switched this to server side rendering and it works.
So in summary, some idiot(*) changed the code to dynamically recreate the controls but not add the validation back.
*Possibly, definitely, me.