Open jcheroske opened 7 years ago
Can you share a reproducible example? It should work. When you fire an actions.change('foo.bar', { ... })
, it should automatically create the form and field states for foo
and foo.bar
in the forms
slice of your state.
Yeah, it did that. But for some reason, the validators were saying the form was invalid when it wasn't. As soon as I added the initial state of the model back to createForms
it worked.
I'd need to see a full code example.
import {FlatButton, TextField} from 'material-ui'
import PropTypes from 'prop-types'
import {Form, Control} from 'react-redux-form'
import {isEmail, isEmpty, isLength, normalizeEmail, trim} from 'validator'
const propTypes = {
finalCost: PropTypes.number.isRequired
}
const required = val => val && !isEmpty(trim(val))
const minLength = min => val => val && isLength(trim(val), {min})
const email = val => val && isEmail(normalizeEmail(val) || '')
const ContactForm = ({finalCost}) => (
<div>
<h2>Your Quote: ${finalCost.toFixed(2)}</h2>
<Form
model='forms.contactForm'
onSubmit={(...args) => console.log('burp', args)}
validators={{
name: {
required,
minLength: minLength(3)
},
email: {
email
},
phone: {
required,
minLength: minLength(10)
},
commodity: {
required,
minLength: minLength(3)
}
}}
>
<Control.text
component={TextField}
floatingLabelText='Full Name'
fullWidth
mapProps={{
errorText: ({fieldValue: {errors, submitted}}) => {
if (submitted && errors.required) {
return 'Full name is required'
}
else if (submitted && errors.minLength) {
return 'Full name must be 3 or more characters'
}
}
}}
model='.name'
/>
<Control.text
component={TextField}
floatingLabelText='Email Address'
fullWidth
mapProps={{
errorText: ({fieldValue: {errors, submitted}}) => {
if (submitted && errors.email) {
return 'A valid email address is required'
}
}
}}
model='.email'
/>
<Control.text
component={TextField}
floatingLabelText='Phone Number'
fullWidth
mapProps={{
errorText: ({fieldValue: {errors, submitted}}) => {
if (submitted && errors.required) {
return 'Phone number is required'
}
else if (submitted && errors.minLength) {
return 'Phone number must be 10 or more characters'
}
}
}}
model='.phone'
/>
<Control.text
component={TextField}
floatingLabelText='Commodity'
fullWidth
mapProps={{
foo: props => console.log(props),
errorText: ({fieldValue: {errors, submitted}}) => {
if (submitted && errors.required) {
return 'Commodity is required'
}
else if (submitted && errors.minLength) {
return 'Commodity must be 3 or more characters'
}
}
}}
model='.commodity'
/>
<Control.button
component={FlatButton}
fullWidth
label='Contact Us!'
mapProps={{
disabled: ({fieldValue: {valid}}) => !valid
}}
model='.'
type='submit'
/>
</Form>
</div>
)
ContactForm.propTypes = propTypes
export default ContactForm
Here's my current reducer:
const rootReducer = combineReducers({
apollo: apolloClient.reducer(),
forms: combineForms({}, 'forms'),
...sharedReducers,
...appReducers
})
If an empty object is passed to combineForms
then it doesn't work. If I pass in the initial state for the contactForm
then it validates.
any update on this? @davidkpiano @jcheroske
Sorry, I'd need to see a full code example in a CodePen or CodeSandbox (makes it way easier to debug).
Ping... Interested in seeing if this was resolved or not.
I'm also reworking how we handle forms now and have been recently moving towards a more dynamic model, where I download N form configurations at runtime and would like to inject them into RRF. To further complicate this, one key change I'm trying to make work is that I'd like to store all field values in a single, shared reducer state, this will keep field values in sync across forms if they share an underlying ID - which is a business requirement. I'd like to dynamically inject forms at runtime, which use a slice of the shared reducer state, but ideally still produce unique form state for each dynamic form (so I can quickly and easily check form completeness, for example).
I'll plow ahead on my own but I'd be interested in hearing if you've already overcome any of these challenges, OP.
Thanks!
I'm wanting to simplify my store config, and am experimenting with using RRF in a completely dynamic fashion. Here's how I'm setting up my root reducer:
This actually works, but I'm not sure if I've suddenly wandered into the wilderness or not. What are some things I'm going to need to watch out for? How can I set the initial state of the form when doing things this way?
Update: Actually, that doesn't seem to work. Validation isn't running as expected. So, I guess what I'm really asking is: is it possible to have all forms dynamically added to RRF, or do I need to declare them all in the reducer?