haacked / aspnet-client-validation

A client validation library for ASP.NET MVC that does not require jQuery

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

remove(root: ParentNode) {
this.logger.log('Removing', root);
this.scanMessages(root, true);
this.scanInputs(root, true);
}

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.