Reputation: 2462
After solving some problems, I stuck with sending DatePicker data to my form. In my form I use mostly elements from redux-form-material-ui, but DatePicker is not a part of it.
I found 2 ways of creating DatePicker component with redux-form.
<Field
name="startDate"
autoOk={true}
floatingLabelText="startDate"
component={(startDate) => {
return <DatePicker {...startDate} />;
}}
onChange={(event, date) => {console.log(date);}}
/>
and
<DatePicker
name="startDate"
autoOk={true}
floatingLabelText="startDate"
onChange={(event, date) => {console.log(date)}} />
The problem is that I don't know the way to update the form data with it. The first example even doesn't show the picked date in text field. I can see in form.myForm
store, that I made date field active, but it is never updated with picked date. The second shows picked date, but it is not a part of form.myForm
object...
I found some examples in internet (e.g. https://github.com/erikras/redux-form/issues/364 ) but there is no fields
object in props, so cannot call this.props.fields.startDate.onChange
.
I'm not sure what is a good way of working with redux-form and material-ui, as there is not many working examples. I started to think of making a wrapper to EVERY component I use, which will provide onChange method, which will update my store with any change made in form. But then I don't need redux-form anymore, so I think there must some other solution, I could use.
"react": "15.1.0",
"react-tap-event-plugin": "1.0.0",
"redux": "3.0.5",
"redux-form": "^6.0.0-alpha.4",
"redux-form-material-ui": "^2.0.0",
Upvotes: 6
Views: 4669
Reputation: 4420
Not just for this Datepicker but for any custom input, create a separate component to manage the input type and process. Which makes easy to feed your redux-form fields. This is the simple process I was taught by my senior developers when I was a Grad.
In your case, firstly import following additional libraries to your redux-form component
import moment from 'moment'
import { change } from 'redux-form' //We use the change to dispatch the own props of the redux-form component to resetDateField
Create a separate component by importing DatePicker in it. And your component will look something like this:
const datePickerInput = ({input,name,label,...props}) => {
return (
<div>
<label htmlFor={input.name}>
<span>
{label}
</span>
</label>
<div>
<DatePicker
className='form-control'
{...input}
{...props}
/>
</div>
</div>
)
}
Now feed this component to your redux-form field's component.
<Field
name = "startDate"
label = "Start Date"
dateFormat = 'MMM Do YY'
component={datePickerInput}
selected = {/*pass state value of startDate or pass some default null for startDate if nothing selected*/}
onChange={ (date) => {this.handleChangeStartDate(date, 'startDate')} } //bind this function in constructor and also setState value for your start date as null or some default
/>
the onChange function is to be handled something like this using moment:
handleChangeStartDate(date, target) {
const {resetDateField } = this.props
this.setState({
[target]: moment(date)
})
resetDateField('startDate', '' )
}
Now hook this resetDateField in your reduxForm @connect by passing dispatch and ownProps and returning resetDateField value expecting a dispatch of change for current form, field, and field value that you want to change using this resetDateField.
Upvotes: 1
Reputation: 3135
import React from 'react';
import DatePicker from 'material-ui/DatePicker';
export default ({ input, label, meta: { touched, error }, ...custom }) => {
return (
<DatePicker
onChange={(e, val) => {return input.onChange(val)}}
{...custom}
value={input.value}
/>
);
}
Considering this as in file renderDatePicker.js
, usage would be,
<Field name="created_on" component={RenderDatePicker} floatingLabelText="Created Date"/>
Where Field
is imported from redux-form
.
Remember to provide {created_on: new Date('someiso8601')}
in this.props.initialize
to autopopulate it.
Upvotes: 5
Reputation: 6358
I used react-datepicker with redux form. The key was to set "selected" property correctly.
const selectedDate = this.props.fields.date.value ?
moment(this.props.fields.date.value, 'DD/MM/YYYY') :
moment();
<DatePicker
{...date}
className="form-control"
dateFormat="DD/MM/YYYY"
selected={selectedDate}
/>
Upvotes: 3
Reputation: 1286
Here is how I use it in my code.
<DatePicker
selected={dateField.value}
onChange={param => dateField.onChange(param)} />
dateField
simply comes from:
const {fields: {dateField}, handleSubmit} = this.props;
Upvotes: 2