Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly set default values using redux-forms?

Using React with redux-forms, I got following component, it's a form where 3 input fields might get values if the query string include the values.

I'm using initialize method for setting:

initialize({
  firstname: query.firstname,
  lastname: query.lastname,
  birthday: query.dob
});

And that fills the fills, however I got two main issues:

  • The submit button keeps disabled
  • The fields are not editable.

I tried to set a fix for the submit button by testing the invalid prop, but didn't work.

How can I fix and cope those issues?

This is the whole component code:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';
import { reduxForm, Field, SubmissionError } from 'redux-form'
import { RaisedButton, Paper, TextField } from 'material-ui';

import * as actionsAuth from '../redux/modules/auth';
import { createValidator, required, email } from '../utils/validation';
import FieldTextField from '../components-form/FieldTextField';


const styles = {
    root: {
        display: 'flex',
        flexWrap: 'wrap',
        justifyContent: 'space-around',
        paddingTop: 50
    },
    paper: {
        padding: 20,
        maxWidth: 500
    },
    field: {
        width: '100%'
    },
    button: {
        width: '100%',
        marginTop: 10
    }
};

const validate = createValidator({
    firstname: [],
    lastname: [],
    birthday: []
});

class LoginPage extends Component {

    constructor(props) {
        super();
        this.submit = this.submit.bind(this);
    }

    static propTypes = {
        patientChatLogin: PropTypes.func.isRequired
    };

    submit(values) {
        const { user } = this.props;
        let dob = values.birthday.split('-');
        let data = {
            _id: user.id,
            firstname: values.firstname,
            lastname: values.lastname,
            dob: {
                year: dob[0],
                month: dob[1],
                day: dob[2]
            }
        }
        const { patientChatLogin } = this.props;

        return patientChatLogin(data)
            .then(this.onSubmitSuccess, this.onSubmitError);
    }

    onSubmitSuccess(patient) {
        browserHistory.push(`/chat/${patient.id}`);
    }

    onSubmitError(rejection) {
        throw new SubmissionError({ auth: rejection.error, _error: 'Login failed!' });
    }

    ///////////////////
    // render

    render() {
        return (
            <div style={styles.root}>
                {this.renderForm()}
            </div>
        );
    }

    renderForm() {
        const { handleSubmit, initialize, location: {query} } = this.props;
        if (query.firstname && query.firstname !== 'undefined' &&
            query.lastname && query.lastname !== 'undefined' &&
            query.dob && query.dob !== 'undefined') {
            initialize({
              firstname: query.firstname,
              lastname: query.lastname,
              birthday: query.dob
            });
        }
        return (
            <form
                onSubmit={handleSubmit(values => this.submit(values))}
            >
                <Paper style={styles.paper} zDepth={1}>
                    {this.renderFieldFirstName()}
                    {this.renderFieldLastName()}
                    {this.renderFieldBirthday()}
                    {this.renderSubmitButton()}
                </Paper>
            </form>
        );
    }

    renderFieldFirstName() {
        // TODO:
        // Set default as redux-form requires it
        return (
            <Field
                autoFocus
                style={styles.field}
                name="firstname"
                floatingLabelText="First Name"
                component={FieldTextField}
                required
            />
        );
    }

    renderFieldLastName() {
        return (
            <Field
                style={styles.field}
                name="lastname"
                floatingLabelText="Last Name"
                component={FieldTextField}
                required
            />
        );
    }

    renderFieldBirthday() {
        return (
            <Field
                style={styles.field}
                type="date"
                name="birthday"
                floatingLabelText = "Date of Birth"
                floatingLabelFixed={true}
                component={FieldTextField}
                required
            />
        );
    }

    renderSubmitButton() {
        const { pristine, submitting, invalid } = this.props;
        return (
            <RaisedButton
                style={styles.button}
                type="submit"
                label="Enter secure chat"
                secondary
                disabled={ pristine || submitting ||  invalid }
            />
        );
    }
}

export default connect(state => ({
        user: state.auth.user,
}), {
        ...actionsAuth,
    })
    (reduxForm({
        form: 'AuthenticatePatientForm',
        validate,
    })(LoginPage));
like image 393
diegoaguilar Avatar asked Feb 22 '17 21:02

diegoaguilar


People also ask

How do I change initial value in Redux?

To populate your form with initial values, you'll need to pass data to your form from your store. To do this, in your mapStateToProps() function, create a key called initialValues that is set to an object that contains the keys and values of the data you'd like to place in your form.

Should I store form data in Redux?

We specifically recommend that most form state probably shouldn't be kept in Redux. However, it's your app, so you should evaluate the specific use cases you need to deal with to determine the right approach.


1 Answers

You're not able to edit the fields because you're initializing on every render if those props are present. To use initialize, you would want to do that in componentDidMount rather than in your render method.

An alternative approach would be to wrap the form component and supply initialValues based on those props.

const Wrapper = ({ location: { query }, ...props }) => {
  class LoginPage extends Component {
    ...
  }
  const WrappedForm = reduxForm({
    form: 'the-form',
    validate,
    initialValues: {
      firstname: query.firstname,
      lastname: query.lastname,
      birthday: query.dob
    }
   })(LoginPage);
   return <WrappedForm {...props} />;
 }
like image 89
Andy_D Avatar answered Sep 28 '22 02:09

Andy_D