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

Dynamic fields #1006

Open
saharulit opened this issue Feb 16, 2023 · 6 comments
Open

Dynamic fields #1006

saharulit opened this issue Feb 16, 2023 · 6 comments

Comments

@saharulit
Copy link

I have a form where some fields are dynamically created, some of the dynamic fields are required and some are optional,
I couldn’t find a way to make vest support this use case, any suggestions?

@ealush
Copy link
Owner

ealush commented Feb 16, 2023

Not knowing much about your specific use-case (maybe share a more detailed example?), but just from the overall description, it seems like you require something of that sort: A combination of each+optional

https://vestjs.dev/docs/writing_tests/advanced_test_features/dynamic_tests - allows you to iterate over a list of values to create dynamic tests
https://vestjs.dev/docs/writing_your_suite/optional_fields - allows you to set values as optional so they do not set the form as invalid when they are not filled out

@saharulit
Copy link
Author

I appreciate your quick response!

I will share with you more details -
My form library is Felete and my validator is Vest.
There are some fields in my form that are not consts and I'm getting them at runtime (I don't have the fields names)
It looks something like this:

[
{name: "address" , required: true},
{name: "building_number", required: false},
...
]

Is there a way to create a dynamic suite that gets data on the fly?

@swithek
Copy link

swithek commented Mar 8, 2023

each(data.fields, field => {
    optional(field.name)
    test(
      field.name,
      'item price must be greater than 0',
      () => {
        enforce(field.price).isNumeric().greaterThan(0);
      },
    );
});

@ealush is this how you would write these validation tests? Combining each and optional this way doesn't seem to work (i.e., the fields aren't marked as optional).

@ealush
Copy link
Owner

ealush commented Mar 8, 2023

@swithek I just ran a test with the exact scenario that you mentioned, and I can confirm it works correctly: https://codesandbox.io/s/react-forked-0bobdc?file=/src/suite.js

Type in Req_1 and Req_2, and you'll see that the submit button lights up, even though you did not fill out the optional field.

I believe that what you're experiencing is this:
You type in the optional field, and then remove its content. In this scenario, the field is indeed not valid any more.

It all boils down to what optional really means in your app's context, and what qualifies as optional-satisfying-test.

Let me explain:

If the field is empty, does that qualify for optional? Maybe. But what if the user typed inside the field and then removed its content - is that qualify as optional? Maybe in your app, the field is optional only if some other condition applies, for example - when another field has been filled...

As you see, optional can mean different things in different context. As I mentioned in a previous answer a couple of weeks back, Vest doesn't have a notion of your apps logic, or in other words - Vest has no knowledge of "what should happen now", it also doesn't make sense of your data, so marking a certain field as optional, doesn't mean Vest is going to check the data properties passed to it, because you may name them whatever you want.

Instead, a different approach is taken in Vest, assuming it isn't aware of your business logic.

Vest determines whether a field qualifies as optional by a certain rule: did it have any test runs?
Meaning, if a test of a certain field did indeed run, it will be regarded as required, because its tests were triggered.

  • or, in other words - Vest allows the Suite to be regarded as valid, if the fields marked as optional did not run at all.

@swithek
Copy link

swithek commented Mar 9, 2023

Thank you for your quick reply @ealush! What you're saying makes complete sense, however, as specified in the docs, you can have custom rules that determine whether the field should be optional or not, is that correct? If that's the case, shouldn't having

optional({
    optional: !data["optional"],
});

be enough to cover all the empty value/undefined field cases, even when there are existing validation results from previous runs? This doesn't seem to work when each is used. Maybe I'm missing something?

Here's an example based on your example: https://codesandbox.io/s/react-forked-oy06l8?file=/src/suite.js

@ealush
Copy link
Owner

ealush commented Mar 9, 2023

I will have to dig deeper to see why that specific case didn't work for you, but just to unblock you now - using a function should solve it for you.

optional({
  optional: () => !data.optional
});

https://codesandbox.io/s/react-forked-hpry5u?file=/src/suite.js

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