Can't type in text field using redux-form
Asked Answered
P

4

15

I have a form in a modal using redux-form. I have several text fields, but you can not type in them. My suspicion is that the text field doesn't get the onChange event from the redux-form but I couldn't find any clue what am I doing good.

My code is:

import React from 'react'
import { Button, Modal, Form, Message } from 'semantic-ui-react'
import { Field, reduxForm } from 'redux-form'

const renderField = ({ input, label, type, meta: { touched, error, warning } }) => {
  console.log(input)
  return (
  <Form.Field>
    <label>{label}</label>
    <input {...input} placeholder={label} type={type} />
    {touched && (error && <Message error>{error}</Message>)}
  </Form.Field>
)}

let AddNewModal = (props) => {
  const { handleSubmit, pristine, submitting, closeNewSite, isAddNewOpen, submit } = props

  return (
    <Modal dimmer='blurring' open={isAddNewOpen} onClose={closeNewSite}>
      <Modal.Header>Add a new site</Modal.Header>
      <Modal.Content>
        <Form onSubmit={handleSubmit}>
          <Form.Group widths='equal'>
            <Field name='domain' type='text' component={renderField} label='Domain' />
            <Field name='sitemap' type='text' component={renderField} label='Sitemap URL' />
          </Form.Group>
          /**
           * Other fields 
           * /
          <Button type='submit' disabled={pristine || submitting}>Save</Button>
        </Form>
      </Modal.Content>
      <Modal.Actions>
        <Button color='black' onClick={closeNewSite} content='Close' />
        <Button positive icon='save' labelPosition='right' onClick={submit} content='Save' disabled={pristine || submitting} />
      </Modal.Actions>
    </Modal>
  )
}

export default reduxForm({
  form: 'newsite'
})(AddNewModal)
Padriac answered 22/10, 2016 at 20:1 Comment(0)
B
51

I added the reducer and still got the same issue. At last, I found it must add the attr 'form'.

const reducers = {
  routing,
  form: formReducer
};
Bootle answered 26/10, 2016 at 6:12 Comment(2)
You have to call the variable formReducer just "form", and then doing reducers = { routing, form } and nothign else.Lithology
so why you didn't upvote me. Eh? Why? #joking #pleaseUpvoteMeLithology
P
18

I found the problem. I forgot to inject the redux-form's reducer.

Padriac answered 23/10, 2016 at 17:54 Comment(2)
Aaaaaand... How do you added?Lithology
please provide solutionVicinal
R
1

I actually had a similar issue. I will post the code that I am working on for form validation with V6 of redux-form. It works right now but the things you want to look at are componentDidMount, handleInitialize, and handleFormSubmit. Where I figured this out link.

/**
* Created by marcusjwhelan on 10/22/16.
*/

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reduxForm, Field } from 'redux-form';  // V6 !!!!!!!!
import { createPost } from '../actions/index';

const renderInput = ({ input, label, type, meta: {touched, invalid, error }}) => (
  <div className={`form-group ${touched && invalid ? 'has-danger' : ''}`}>
    <label>{label}</label>
    <input className="form-control" {...input} type={type}/>
    <div className="text-help" style={{color: 'red'}}>
      { touched ? error : '' }
    </div>
  </div>
);

const renderTextarea = ({ input, label, type, meta: {touched, invalid, error }}) => (
  <div className={`form-group ${touched && invalid ? 'has-danger' : ''}`}>
    <label>{label}</label>
    <textarea className="form-control" {...input}/>
    <div className="text-help" style={{color: 'red'}}>
      { touched ? error : '' }
    </div>
  </div>
);

class PostsNew extends Component{
  componentDidMount(){
  this.handleInitialize();
}
handleInitialize(){
  const initData = {
    "title": '',
    "categories": '',
    "content": ''
  };
  this.props.initialize(initData);
}

handleFormSubmit(formProps){
  this.props.createPost(formProps)
}

render(){
  const { handleSubmit } = this.props;
  return (
    <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
      <h3>Create A New Post</h3>

      <Field
        label="Title"
        name="title"
        type="text"
        component={renderInput} />

      <Field
        label="Categories"
        name="categories"
        type="text"
        component={renderInput}
      />

      <Field
        label="Content"
        name="content"
        component={renderTextarea}
      />

      <button type="submit" className="btn btn-primary" >Submit</button>
    </form>
  );
}
}

function validate(formProps){
  const errors = {};

  if(!formProps.title){
    errors.title = 'Enter a username';
  }
  if(!formProps.categories){
    errors.categories = 'Enter categories';
  }
  if(!formProps.content){
    errors.content = 'Enter content';
  }
  return errors;
}

const form = reduxForm({
  form: 'PostsNewForm', 
  validate
});

export default connect(null, { createPost })(form(PostsNew));
Rackety answered 22/10, 2016 at 22:40 Comment(2)
I tried to use mine like this. But it is not working either.Padriac
You don't seem to be including the connect function in your code. You can see at the bottom of my code. Also I am not sure what you are doing with <Form.Field>. In mine I have the <Field in the component, And render the <input> inside of a component call. Also you might want to make this a container and not a functional component.Rackety
M
1

You need to connect form reducer to your combine reducers

form: formReducer

import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';

import authReducer from './authReducer';
import productsReducer from './productsReducer';

export default combineReducers({
    auth: authReducer,
    form: formReducer,
    products: productsReducer,
});
Meaghanmeagher answered 28/4, 2020 at 9:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.