Reputation: 481
I have a simple form field and I am trying to format and set the field value when onChange event is triggered using setFieldsValue which is not working.
I am trying to show the formatted value in the same text field.
Please find the sandbox link here codeSandbox
I dont want to create one more controlled component with state and set the value as I have 20 fields in the original form data. How could we set the form value on onChange itself.
Upvotes: 4
Views: 15216
Reputation: 172
You can change the form value using the event too.
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Form, Input, Button } from "antd";
const FormItem = Form.Item;
class Demo extends React.Component {
changePhone = () => {
const { setFieldsValue, getFieldValue } = this.props.form;
let drivers = getFieldValue("drivers");
console.log("driver data was", drivers);
setFieldsValue({
drivers: `1234`
});
};
handlePhoneChange = event => {
const value = event.target.value;
const { getFieldValue } = this.props.form;
let drivers = getFieldValue("drivers");
// if (!drivers.startsWith("+1 - ") && drivers.length > 3) // Another way
if (!drivers.startsWith("+1 -"))
// event.target.value = `+1 - `; // Another way
event.target.value = `+1 - ${value}`;
else
event.target.value = `${value}`;
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
<Form>
<FormItem
label="phone"
style={{
display: "inline-block"
}}
>
{getFieldDecorator(`drivers`, {
initialValue: ""
})(<Input onChange={this.handlePhoneChange} />)}
</FormItem>
</Form>
<Button type="primary" onClick={this.changePhone}>
change phone
</Button>
</div>
);
}
}
const Wrapped = Form.create()(Demo);
ReactDOM.render(<Wrapped />, document.getElementById("container"));
https://codesandbox.io/s/clever-hill-vuxtj
Upvotes: 0
Reputation: 19224
You are loosing the value being set because the onChange
for Antd forms are async and are being run after the onChange
that you have written. To get over this, you can simply add a setTimeout
to the setFieldsValue
:
onChange={e => {
const value = e.target.value;
const { setFieldsValue, getFieldValue } = this.props.form;
setTimeout(() => {
setFieldsValue({
drivers: `+1 - ${value}`
});
}, 0);
}}
A more pragmatic way to do this, would be to use the normalize
function of getFieldDecorator
:
{getFieldDecorator(`drivers`, {
initialValue: "",
normalize: (value) => {
return `+1 ${value}`;
}
})}
However, this would add +1
on every change and that doesn't look like what you would want to do. So alternatively:
normalize: (value) => {
if(!value.startsWith('+1')) {
return `+1 ${value}`;
}
return value;
}
Upvotes: 2