Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preserved validation results/errors for array items #508

Closed
1 task done
linus-amg opened this issue Nov 11, 2024 · 6 comments
Closed
1 task done

preserved validation results/errors for array items #508

linus-amg opened this issue Nov 11, 2024 · 6 comments

Comments

@linus-amg
Copy link

linus-amg commented Nov 11, 2024

Screen.Recording.2024-11-11.at.16.40.08.mov
  • Before posting an issue, read the FAQ and search the previous issues.

Description
Validation results seem to stay in some kind of cache when an invalid element gets deleted from an array, while the expectation is that the errors of this item would also get reset.

MRE: https://www.sveltelab.dev/nl0wj3phemks2d5
Instructions:

  1. Click add button to add a new item to an array
  2. Click submit button to trigger client-side validation
  3. See the "Required" error message next to the input field
  4. Click delete button to delete the item from the array
  5. Click add button
  6. See the "Required" error message next to the input field, even though we did not yet submit again - it seems as the index is stuck with the validation error from before
  7. Click add one more time
  8. See that the last item added does not have a validation error

Same results with trying all other validationMethod.

@linus-amg linus-amg added the bug Something isn't working label Nov 11, 2024
@pekeler
Copy link

pekeler commented Nov 12, 2024

Related question:

Once the user tries to submit a form, all fields are validated. In case where the submission fails due to validation errors, the user could make a change afterwards that reveals more form fields (perhaps by changing a "kind" attribute which controls a discriminating union in the zod schema).

One could argue that the newly revealed fields should immediately be validated to be consistent with the fields that were already there before the attempted submit. Or, one could argue that they should not be validated until the user actually focussed->inputted->blurred something on the new field.

Does Superforms have an opinion on this?

@ciscoheat
Copy link
Owner

@linus-amg since your validationMethod is set to onsubmit, the validation won't run until you submit the form. If you remove it to have the default auto value, it works as you would expect.

If you want to keep onsubmit but still want it to validate on deletion, deconstruct validateForm from superForm and call it in deleteItem:

const deleteItem = (index) => () => {
  $formData.tags = $formData.tags.filter((_, i) => i !== index);
  validateForm({update: true});
};

@ciscoheat
Copy link
Owner

@pekeler Good question, I have no opinion really but I think the default focus-input-blur is fine. If you have any further ideas about it, please let me know!

@linus-amg
Copy link
Author

linus-amg commented Nov 13, 2024

@linus-amg since your validationMethod is set to onsubmit, the validation won't run until you submit the form. If you remove it to have the default auto value, it works as you would expect.

If you want to keep onsubmit but still want it to validate on deletion, deconstruct validateForm from superForm and call it in deleteItem:

const deleteItem = (index) => () => {
  $formData.tags = $formData.tags.filter((_, i) => i !== index);
  validateForm({update: true});
};

@ciscoheat I've tried your recommendation of using validateForm, but I guess I was not yet able to bring across the actual issue, the problem is not that it's not validating, the problem is that it is validating, even though I'm not submitting in between deletes and adds, but still get errors for items at an index which was invalid before. I created two more recordings trying showcase the issues, one could also try it out in the SvelteLab link, I've updated the code to use "auto", but it's the same behavior.

Screen.Recording.2024-11-13.at.09.56.43.mov
Screen.Recording.2024-11-13.at.09.57.12.mov

@ciscoheat
Copy link
Owner

I see, then you need to use update for the form data store and set it to prevent tainting, because it's the tainting that makes it validate. So your add/delete functions should be something like:

	const addItem = (evt) => {
		evt.preventDefault();
		formData.update($formData => {
			$formData.tags = [...$formData.tags, { timestamp: Date.now() }];
			return $formData;
		}, {taint: false});
	};

	const deleteItem = (index) => () => {
		formData.update($formData => {
			$formData.tags = $formData.tags.filter((_, i) => i !== index);
			//validate(`tags[${index}]`);
			return $formData;
		}, {taint: false}) 
	};

@ciscoheat ciscoheat removed the bug Something isn't working label Nov 15, 2024
@linus-amg
Copy link
Author

I see, then you need to use update for the form data store and set it to prevent tainting, because it's the tainting that makes it validate. So your add/delete functions should be something like:

	const addItem = (evt) => {
		evt.preventDefault();
		formData.update($formData => {
			$formData.tags = [...$formData.tags, { timestamp: Date.now() }];
			return $formData;
		}, {taint: false});
	};

	const deleteItem = (index) => () => {
		formData.update($formData => {
			$formData.tags = $formData.tags.filter((_, i) => i !== index);
			//validate(`tags[${index}]`);
			return $formData;
		}, {taint: false}) 
	};

Thank you very much for the suggestion @ciscoheat - will give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants