Comments (9)
Hey @adberard!
Thanks for your questions and interest. I took a look at your codesandbox and the questions in your comments, and compiled a list of answers below.
Here a an updated version of your codesandbox to follow along:
https://codesandbox.io/s/4qy8v0ony9
QUESTION:
I had to comment injectGenProps in order to use my own validate function,
but then the required key in the field objects became useless,
how can I still use the required key instead of writing which components
are required in my validate.js:3
It looks like the reason that you wanted to use a custom validate function was because you wanted to use a regex to validate the email, right? If that is the case, there is good news, because redux-form-gen
supports custom validation by using our conditional operators. I just noticed that I forgot to add the conditionalValid
field property to the docs, but I've taken a note to add it. We have a regex
operator that will compare the value against the regex during validation. It would look something like this:
{
type: "text",
formType: "email",
questionId: "email",
label: "Email",
required: true,
conditionalValid: {
regex: "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}$"
}
}
Within the customFieldTypes.js
for the password
field type, you asked:
// QUESTION is there other components that I should nullify ?
Here is a link to the source for genericFieldProps()
It essentially boils down to:
export const genericFieldProps = ({field}) => ({
_genFieldComponent: Field,
_genLabelComponent: GenericRequiredLabel,
name: field.questionId
});
Because the TextField
for material-ui
has the input, label, and required
indicator built in, you wouldn't need the _genLabelComponent
. There shouldn't be anything else you need to nullify.
QUESTION:
How would I wrap childFields in a FormSection from react redux ?
You can extend the section
field type to render a <FieldSection />
component from redux-form
, but after trying to implement an example for you I think it may be a little more detailed that I originally thought. Let me whip something up for that and answer it in issue #23.
Thanks you so much for your questions, and let me know if you have any feedback as well. I have lots of ideas for features and improvements to the field type API, and look forward to hearing any suggestions you may have.
from redux-form-gen.
Im the one thanking you so much for your really quick and detailed answers !
But If you like questions I may still have some that rised up.
How can I set my own custom message for precise errors in field ? I need this because im planning on doing some multi-languages.
How can I put my own function into validate (which would my global state for coherent dates for examples)
I really look forward #23, I tryed to play around but Im not getting everything about how childrens are generated with _gencomponent !
from redux-form-gen.
I played a bit the SectionField that you started to write and it seem that validation with nested component like this isnt going to work. Even when using my own validate.js its not very simple, ive read that redux form v8 will enhance validation
from redux-form-gen.
How can I set my own custom message for precise errors in field ? I need this because im planning on doing some multi-languages.
You can use the requiredMessage
and invalidMessage
to overwrite the message used for that field. here's an example:
{
type: 'text',
questionId: 'Name',
conditionalValid: {
minLength: 2
},
invalidMessage: 'Must be at least two characters'
}
If you're planning on using a multi-language framework, such as react-intl
, you could make your invalidMessage
the message id for your defined messages in react-intl
instead of an actual error message. Then you would expect the meta.error
that comes down from redux-form
to be a message id and would run formatMessage(formMessages[error])
.
something like this:
// the field
{
type: 'text',
questionId: 'Name',
conditionalValid: {
minLength: 2
},
invalidMessage: 'minTwoChars' // the message id from defineMessages
}
// messages
import {defineMessages} from 'react-intl';
const formMessages = defineMessages({
minTwoChars: {
id: 'formMessages.minTwoChars',
description: 'Form error message for min two characters',
defaultMessage: 'Must be at least two characters'
}
});
// field component
import {injectIntl} from 'react-intl';
const TextField = injectIntl(({intl: {formatMessage}, meta, ...props}) => (
<Input
{...props.input}
error={meta.touched && meta.invalid && formatMessage(formMessages[meta.error])}
/>
));
How can I put my own function into validate (which would my global state for coherent dates for examples)
Not sure what you mean exactly. If you want to provide a custom validate function in addition to having injectGenProps
do validation, you can pass it like this:
const MyForm = injectGenProps(
reduxForm({
form: 'exampleForm',
onSubmit
// don't pass validate here, since it will get overridden by injectGenProps. you need to pass it above injectGenProps
})(MyFields)
);
const customValidate = (formValues) => {
// do some custom validation here, and return an errors object
};
const App = () => (
<Provider store={store}>
{/* pass a custom validate function here: */}
<MyForm fields={fields} customFieldTypes={customFieldTypes} validate={customValidate} />
</Provider>
);
This is more of a last resort if you can't build the logic you need with a conditional object. There is also the option to provide your own customOperators for use in conditional object. You can find examples of conditionalOperators here:
https://github.com/isobar-us/redux-form-gen/blob/master/src/conditionalUtils.js#L39
I really look forward #23, I tryed to play around but Im not getting everything about how childrens are generated with _gencomponent !
Let me see if I can explain:
The <FormGenerator />
runs through the list of fields and recursively renders <GenField />
components for each field. GenField
handles the rendering of childFields
internally so that each field component implementation doesn't have to be concerned about it. Also of note, childFields
are not actually rendered as children react nodes, but as siblings to the field. The parent/child relationship was more referring to the visibly/hidden relationship that parents and children have. If a parent field is hidden, so are it's children.
If you do want to render the childFields
inside of your _genComponent
(as is the case for a FormSection
, There is an override to have GenField
skip rendering of childFields
by passing _genSkipChildren: true
in the field type definition. Then in your _genComponent
you can read the field.childFields
from props, and map over them to render <GenField field={field} />
for each field.
I played a bit the SectionField that you started to write and it seem that validation with nested component like this isnt going to work. Even when using my own validate.js its not very simple, ive read that redux form v8 will enhance validation
After digging around a bit, I realized that the issues we're seeing around the FormSection
and validation stem from bugs in the way the pathPrefix
is handled in the validation of conditional objects. There's a larger discussion to be had in how to fix this, and I have some ideas I've been working on.
In the meantime, I realized you can work around it by prefixing your questionId
's individually, instead of using a FormSection
+ questionId
at the section
level.
{
type: 'section',
label: 'Step 1',
childFields: [
{
type: 'text',
inputType: 'email',
// questionId's have been prefixed with "parent."
questionId: 'parent.email',
label: 'Email',
required: true,
conditionalValid: {
regex: '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}$'
}
},
{
type: 'text',
inputType: 'text',
questionId: 'parent.firstName',
label: 'First Name',
required: true
},
{
type: 'text',
inputType: 'text',
questionId: 'parent.secondName',
label: 'Second Name'
},
{
type: 'password',
questionId: 'parent.password',
inputType: 'password',
label: 'Password',
required: true
}
]
}
from redux-form-gen.
Thank you again for your super detailled explanations !
I didnt saw customValidation examples so I didnt knew how to use it. I was more thinking about putting the function in the field object directly.
{
type: 'password',
questionId: 'parent.password',
inputType: 'password',
label: 'Password',
required: true,
validate: (value) => {
...
}
}
I figured out how to use the childrenFields finally and I kept on adding components
https://codesandbox.io/s/j4n568lo5
I created a stepper field. But im now stuck at creating checkboxes as you can test the input value isnt the correct one and I fail to understand why. (CheckboxField.js)
from redux-form-gen.
Wow, that stepper
field type is impressive! Really creative way to implement a stepped wizard.
I didnt saw customValidation examples so I didnt knew how to use it. I was more thinking about putting the function in the field object directly.
Ah, I see what you mean. We've stuck to a JSON-compatible field structure in order to make sure the field structure could be requested from a back-end, since you can't describe a function in JSON. That's also the reasoning behind the conditional object API, for things like conditionalVisible
, conditionalValid
, conditionalDisabled
, and conditionalRequired
, as well as the customOperators
API so you can define your own operators for custom logic like date comparisons for example.
From what I can tell, all the logic that you have in your validate
function can be described as a conditionalValid
property, with custom messages like I described above. For example:
requiredMessage: 'Champs requis'
invalidMessage: 'Addresse Email invalide'
But im now stuck at creating checkboxes as you can test the input value isnt the correct one and I fail to understand why. (CheckboxField.js)
Are you trying to create a single checkbox field? or more like a checkbox list, where you can select multiple options?
Checkbox Lists can work like a list. the value of the checkboxList can be an array, where all the value
s of the selected options
will appear in the array. you can use a custom onClick
on the rendered checkbox input to add/remove values from the array. Since you always want the value to be an array, you can use _genDefaultValue: []
, so the generator will populate it be default.
const checkboxListType = ({ field, ...options }) => ({
...genericFieldProps({ field, ...options }),
_genDefaultValue: [],
component: CheckboxListField,
options: field.options
});
Single Checkboxes can be tricky in forms. Since it can only have two states, true
or false
. If it comes in as null
/undefined
/""
and gets checked (set to true
), and then unchecked (set to false
), it breaks the dirty/pristine state of redux-form. For this case, we have a concept of _genDefaultValue
which will ensure that default values are filled when the form first boots up. For a checkbox, the default value can be set to false
, and we provide a custom _genIsFilled
to tell the generator that this field is filled out when the value === true
. Try this out:
const checkboxType = ({ field, ...options }) => ({
...genericFieldProps({ field, ...options }),
_genDefaultValue: false,
_genIsFilled: ({ data, field }) => _.get(data, field.questionId) === true,
component: CheckboxField
});
As a note, if you don't use injectGenProps
, you won't get default values from _genDefaultValue
since that happens inside there and is passed to the form as initialValues
.
from redux-form-gen.
Thanx again for explanation, but still ended up pulling my hair off on the checkbox list.
So I tryed to use _genDefaultValue, but once inside the component I cant find how to bind the list of checkbox to the value of the form. I need to use objects instead of array (because their key->value never change when you remove or insert an element).
Can you help me making a basic working checkbox list component ?
something like
{
type: "checkbox",
questionId: "DevModel",
options: [
{ label: "Up", value: "1" },
{ label: "Down", value: "2" },
{ label: "Middle", value: "3" }
]
},
Would submit a value like :
DevModel: {
up: true,
down: false,
middle: true
}
Also with an onclick event that only modify values I dont think that box would appear checked when I will need to inject initialvalue
in reduxForm(MyForm)
in the futur.... I really need to get how you change the input. Im looking at the radio component (https://github.com/isobar-us/redux-form-gen/blob/master/src/defaultFieldTypes/components/RadioField.js) too see how you implemented having bunch of inputs in one 1 group but didnt managed to get something working.
Here is my latest attempt
https://codesandbox.io/s/j4n568lo5?module=%2Fsrc%2FCheckboxField.js
from redux-form-gen.
Here's a working example with the CheckboxField.
https://codesandbox.io/s/wy23z9lv9w?module=%2Fsrc%2FCheckboxField.js
A quick list of some changes:
CheckboxField.js
- modified props to
<Checkbox />
to includechecked
- updated logic in custom
this.onChange
handler
- modified props to
customFieldTypes.js
- modified the
_genDefaultValue
for thecheckbox
type to build the value object you were looking for instead of an array
- modified the
index.js
- wrapped
reduxForm
ininjectGenProps
HOC - moved the custom
validate
function to be a prop of<MyForm />
. - added
customFieldTypes
as a prop of<MyForm />
.injectGenProps
needs this in order to pickup your_genDefaultValue
and inject the properinitialValues
into redux form.
- wrapped
from redux-form-gen.
Your help is precious, I was far to get the logic of it. I will keep on adding materials components :)
from redux-form-gen.
Related Issues (13)
- DateOrUnknownField fails on render HOT 1
- Create a distinction between childFields and innerFields
- lookupTable not getting passed into evalCond in GenCondEval
- Add customOperators example to storybook/sandbox examples
- Nested FormSection HOT 1
- add `conditionalValid` to the API docs
- Hidden fields dependent of css HOT 1
- Feature request: use not? conditional operation on self question ID HOT 2
- Wizard allow to go to next step when invalid
- Custom Array Form HOT 1
- Conditional Value is possible?
- isSectionValid function should be renamed to getSectionErrors
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redux-form-gen.