-
-
Notifications
You must be signed in to change notification settings - Fork 686
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
Add foundations for extensible validation in forms #6161
Conversation
✅ Deploy Preview for plone-components canceled.
|
* main: Remove `react-share` library and `SocialSharing` component (#6162)
``` | ||
|
||
It takes two `dependencies`. | ||
The first element should be the `default` identifier, and the second you can set it up to identify the validator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not explained why default
should be the first identifier.
```ts | ||
config.registerComponent({ | ||
name: 'fieldValidator', | ||
dependencies: ['integer', 'maximum'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the default
is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ummm, in that line, the default
is not needed here, because it's not a default validator, it's a type
one, so the first dependency is the name of the type.
customField: { | ||
title: 'Default field', | ||
description: '', | ||
validator: 'isURL', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe allow passing directly a validator function as well? We're way past the point "schemas should be serializable" and for one-offs it's easier to declare them inline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the pattern we are teaching is go for "named" components and call them by name (partially because of the duality forms from the backend/content types and the client defined forms in blocks), I'd refrain to do so, because then we will have two use cases, one where you can do it, and another use case in which you can't.
Also, in terms of explaining this in docs will became tricky and separate this is already confusing (I've been there when reviewing this with @ericof). Some other considerations is testability, because in that regard, modularization >> inlining things.
So, in principle, I would be -1 for this.
name: 'fieldValidator', | ||
dependencies: ['phoneNumber', 'isValidPhone'], | ||
component: phoneValidator, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What makes this a widget validator instead of a type validator?
}); | ||
``` | ||
|
||
The first dependency should be the `id` of the block, and the second the `id` of the field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it the @type
of the block?
``` | ||
|
||
It does not need to be tied to any field `type` or `widget` definition. | ||
It runs in addition to all the above, so it complements the other validators if any apply. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My biggest piece of feedback on this overall is using an array for the dependencies
feels like trying to fit a square peg into a round hole. It's quite hard to keep track of all the different ways validators can be registered and which values need to go in the dependencies for each one. And it also seems to be like there might be some ambiguous cases, like if there is a field type and a widget type with the same name.
I don't know if the registry supports this but would it be possible to make things a bit more explicit by specifying the dependencies as an object instead of an array? So for example:
config.registerComponent({
name: 'fieldValidator',
dependencies: {
blockType: 'slider',
fieldName: 'url',
validatorName: 'isURL',
},
component: urlValidator,
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davisagli TBH, I'm not fully satisfied with it... I thought that the reason was mainly because we can't get it to work as satisfying as the ZCA works :) As you know, I initially envisioned and implemented the resolution algorithm using a string and concating the deps if we have an array, so I've played with that concept, even in the new getComponents
registry API method.
Using an object would be possible too, I guess. I can play with the idea, and leave the original API in place also.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davisagli I did an initial implementation of using an object instead of an array but I have doubts on how to hash the resultant key to store that object, so then getComponents
work in the same simple way, under the same concepts that we had before. It does work, but under some assumptions that I do not like or they are not satisfactory/safe :/
Maybe if you have some time, we can talk about it.
Co-authored-by: David Glick <[email protected]>
Edit: nevermind, the validator function gets the field definition, so it's possible to set those in the schema |
|
||
### `default` validators | ||
|
||
These validators are registered and applied to all fields. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For context, does "all" mean for all form blocks, or something else? I guess form blocks, but please correct me, if not.
These validators are registered and applied to all fields. | |
Default validators are registered and applied to all fields for all form blocks. |
}); | ||
``` | ||
|
||
It takes two `dependencies` being the first element a fixed `default` identifier, and the second you can set it up to identify the validator itself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to flesh out what the dependencies
key actually means and how to use it.
- What's the purpose of the
default
identifier? - Can I use more than two identifiers in the
dependencies
array?
It takes two `dependencies` being the first element a fixed `default` identifier, and the second you can set it up to identify the validator itself. | |
The `dependencies` key accepts an array of two values. | |
The first element has the identifier of `default`, and the second element has the identifier of the validator. | |
The second identifier can be any string. | |
In the following example, the second identifier is `minLength`. |
``` | ||
|
||
It takes two `dependencies` being the first element a fixed `default` identifier, and the second you can set it up to identify the validator itself. | ||
In the case of the example, this other dependency is `minLength`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of the example, this other dependency is `minLength`. |
|
||
It takes two `dependencies` being the first element a fixed `default` identifier, and the second you can set it up to identify the validator itself. | ||
In the case of the example, this other dependency is `minLength`. | ||
It can be any string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be any string. |
dependencies: ['default', 'minLength'], | ||
component: minLengthValidator, | ||
}); | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's move the example after the explanation. It's jarring to throw an example before its description without some kind of introduction.
|
||
Volto provides a set of validators by default, you can find them in this module: `packages/volto/src/config/validators.ts` | ||
|
||
### How to override them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### How to override them | |
### Override Volto's default validators |
|
||
### How to override them | ||
|
||
You can override them in your add-on as any other component defined in the registry, by redefining them using the same `dependencies`, and providing your own. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can override them in your add-on as any other component defined in the registry, by redefining them using the same `dependencies`, and providing your own. | |
You can override Volto's default validators in your add-on as any other component defined in the registry. | |
To do so, use the `dependencies` key, and provide your own values. | |
```{todo} | |
Provide usage example. | |
``` |
}; | ||
``` | ||
|
||
This is an example of an `isNumber` validator: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an example of an `isNumber` validator: | |
The following example shows an `isNumber` validator. |
}; | ||
``` | ||
|
||
Using the `formData` you can perform validation checks using other field data as source. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the `formData` you can perform validation checks using other field data as source. | |
Using `formData`, you can perform validation checks between multiple fields' data. |
``` | ||
|
||
Using the `formData` you can perform validation checks using other field data as source. | ||
This is interesting in the case that two fields are related, like `start` and `end` dates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting in the case that two fields are related, like `start` and `end` dates. | |
This is useful when you need to compare the values of multiple fields, such as ensuring that the end date and time of an event is after its start. | |
```{todo} | |
Provide usage example. | |
``` |
Closing this pull request since we have the superseding #6181 |
No description provided.