Reactjs antd defaultValue return undefined - reactjs

im trying to make an edit function, the problem come when im trying to get the value from the form, say a user is editing his name, but he does not edit his address, this will make address is undefined even though i already set a defaultValue inside it, this works before in my non antd form, here is my code
form :
<Form onFinish={this.edit}>
<Typography>Email</Typography>
<Form.Item
name="email"
>
<Input defaultValue={user.Email} value={user.Email} className="email form-control col-sm-6"/>
</Form.Item>
<Typography>Full Name</Typography>
<Form.Item
name="name"
>
<Input defaultValue={user.FullName} value={user.FullName} className="email form-control col-sm-6"/>
</Form.Item>
<Typography>Admin</Typography>
<Form.Item
name="admin"
>
{
(user.IsAdministrator)
? <div>
<Select value="yes">Admin
<Select.Option value="no">Not Admin</Select.Option>
</Select>
</div>
: <div>
<Select value="no">Not admin
<Select.Option value="yes">Admin</Select.Option>
</Select>
</div>
}
</Form.Item>
<Typography>Active Status</Typography>
<Form.Item
name="aktif"
>
{
(user.IsActive)
? <Toggle className="switch-lg" checked/>
: <Toggle className="switch-lg"/>
}
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login col-md-10">Submit</Button>
and here is how i get the value :
edit(values){
const name = values.name
const aktif = values.aktif
const index = this.state.id
console.log(values)
}
thanks before, anyhelp will be appreciated

As mentioned in the docs,
You cannot set value for each form control via value or defaultValue prop, you should set default value with initialValues of Form.
Example below:
<Form
onFinish={onFinish}
initialValues={{
residence: ['zhejiang', 'hangzhou', 'xihu'],
prefix: '86',
}}
>

Related

How to dynamically create a form that adds dynamic fields and nested array using the formik fieldArray

I am trying to create dynamic form with fieldArray in react. My code looks like this
<Formik initialValues={{
data:[],
}}
onSubmit={(values)=>{
console.log(values)
}}
>
{
(formik)=>(
<Form>
<h2>form starts here</h2>
<FieldArray name='data' render={
(arrayHelpers)=>{
return(
<div>
<button type='button' onClick={()=>arrayHelpers.insert(formik.values.data.length + 1,{question:'',quesType:'',answers:['']})}>Add</button>
{/* starts */}
{formik.values.data.map((d,index)=>(
<div key={index}>
<label htmlFor={`data.${index}.question`}>question</label>
<Field name={`data.${index}.question`} type='text' id={`data.${index}.question`}/>
<label htmlFor={`data.${index}.quesType`}>quesType</label>
<Field as="select" name={`data.${index}.quesType`}>
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</Field>
</div>
// end
))}
</div>
);
}
}/>
<button type='submit'>submit</button>
</Form>
)
}
</Formik>
so after clicking add button my initialValue looksLike
data[{question:'',questype:'',answers:[]}]
Now after the select option I want to add a button that will add values in the answers array. I tried looping the d.answers but the answers property was not accessible even though I have the property. So, How to achieve this? Thanks in advance!

Antd form: passing dynamic id alongside form-values

im working on a commenting system. Every ID has some comments. If I want to make a new comment, the ID has to be passed alongside the form-values.
ID is being rendered dynamically:
{data && data.formations.map(formation =>
<Row>
<Col span={2}>
<p>ID: {formation.id}</p>
</Col>
...
Form has a Textarea, and the value is being passed automatically due the name prop in Form.Item.
<Form onFinish={onFinish}>
<Form.Item name="comment">
<TextArea rows={4} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">Add comment</Button>
</Form.Item>
</Form>
Idealy, I want the ID passed alongside the values in the following function OnFinish:
const onFinish = (values) *id somehwere here* => {
console.log(values)
}
How to achieve this? Thanks in advance!
You could solve this by adding an hidden field which holds the ID :
<Form onFinish={onFinish}>
<Form.Item name="comment">
<TextArea rows={4} />
</Form.Item>
<Form.Item name="id">
<Input type="hidden" value={formation.id} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">Add comment</Button>
</Form.Item>
</Form>
Then in the onFinish callback you should get a new property id in the values object.
This is the common way to pass known/readonly values alongside form values (in the non SPA / synchronous web world, eg PHP).

How to use formik with Antd Design Form?

I am trying to implement formik validation with Ant design form, formik is able to capture the input/selected data but when I click onSubmit, it doesn't print anything in console.
export default function SearchForm() {
const formik = useFormik({
initialValues: {
city: "",
checkIn: "",
},
onSubmit: (values) => {
console.log(values)
},
});
//console.log(formik.values)
return (
<Form onSubmit={formik.handleSubmit}>
<FormLabel>Select City</FormLabel>
<Form.Item>
<Select
name="city"
value={formik.values.city}
placeholder="Please select a country"
onChange={(value) => formik.setFieldValue("city", value)}
>
<Select.Option value="mumbai">Mumbai</Select.Option>
<Select.Option value="bengaluru">Bengaluru</Select.Option>
<Select.Option value="delhi">Delhi</Select.Option>
<Select.Option value="hyderabad">Hyderabad</Select.Option>
<Select.Option value="chennai">Chennai</Select.Option>
</Select>
</Form.Item>
<FormLabel>Check-In-Date</FormLabel>
<Form.Item>
<DatePicker
name="checkIn"
value={formik.values.checkIn}
format={dateFormat}
onChange={(value) => formik.setFieldValue("checkIn", value)}
/>
</Form.Item>
<SubmitButton htmlType="submit">Book Now</SubmitButton>
</Form>
);
}
And by giving values, the placeholder text is not visible, and also in DatePicker, it is saving as Moment Object.
You can add Validation Schema in useFormik and import Yup, like this :
import * as Yup from 'yup';
const FormSchema = Yup.object().shape({
title: Yup.string().required('Please enter notification title')
});
<Formik
validationSchema={FormSchema}>
<Form>
<div className='grid-row'>
<div className='grid-1'>
<Field name='title' required={true} label='Title'component={Input} />
</div>
</Form>
</Formik>
finally, I got an answer!! When we use the Ant design form, it works a little different from the normal form, instead of using onSubmit we have to use onFinish and generally you pass value and function to capture event.target.value in normal form but in Ant design form we have to pass onChange={(value) => formik.setFieldValue("checkIn", value)} and it will simply capture the change.
<Form onFinish={formik.handleSubmit}>
<FormLabel>Select City</FormLabel>
<Form.Item>
<Select
name="city"
placeholder="Please select a country"
onChange={(value) => formik.setFieldValue("city", value)}
>
<Select.Option value="mumbai">Mumbai</Select.Option>
<Select.Option value="bengaluru">Bengaluru</Select.Option>
<Select.Option value="delhi">Delhi</Select.Option>
<Select.Option value="hyderabad">Hyderabad</Select.Option>
<Select.Option value="chennai">Chennai</Select.Option>
</Select>
</Form.Item>
<FormLabel>Check-In-Date</FormLabel>
<Form.Item>
<DatePicker
name="checkIn"
format={dateFormat}
onChange={(value) => formik.setFieldValue("checkIn", value)}
/>
</Form.Item>
<SubmitButton htmlType="submit">Book Now</SubmitButton>
</Form>

antd forms - complex child elements of <Form.Item>

I have a antd form like this:
return(
<Form
{...layout}
form={form}
onFinish={onFinish}
>
<Form.Item
label="Bezeichnung"
name="name"
initialValue={resource ? resource.name : ""}
rules={[{ required: true, message: 'Bitte Bezeichnung eingeben.' }]}
>
<Input />
</Form.Item>
<Form.Item
label="Farbe"
name="color"
initialValue={resource ? resource.color : undefined}
>
<Input />
</Form.Item>
<ColorPickerButton
onColorChange={(color) => {
form.setFieldsValue({
color: color.hex
});
}}
/>
</Form>
);
As you can see here, i hav an extra button (independenly of the form) which acts as a color-picker. The chosen color is then used with
form.setFieldsValue({
color: color.hex
});
My question is now: Is there a more convenient way of putting together the <Input /> component with the <ColorPickerButton />component to use it that way:
<Form.Item
label="Farbe"
name="color"
initialValue={resource ? resource.color : undefined}
>
<ColorPickerInput />
</Form.Item>
Do you want some kinds of "auto binding" between Form.Item and ColorPickerInput? You can try to pass form and name to ColorPickerInput component, and call form.setFieldsValue({[name]: value}) within ColorPickerButton.onColorChange to update it.

Other validation message is triggering instead of my message when using Ant design getFieldDecorator

I am using Ant design and this is my form when I click on save I am getting this type of validation msg instead of red bordered Antd validation msg
I want validation error like this which is shown in AntD documents.
https://codesandbox.io/s/do52z
I have writter my function like this
<Form id="myForm" onSubmit={this.handleSubmit}>
<Form.Item label="Code">
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form.Item>
</Form>
This is my custom Input
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
);
};
export default CustomInput;
and this is my save button
<Button
className="save-btn"
htmlType="submit"
form="myForm"
>
Save
</Button>
I think I am missing something little here. Thanks in advance
Ant design input doesn't have required prop..
Required prop should be give inside form.item rules prop.
Since you have given reqired to input tag it will cause Chrome to display a prompt that the user to fill out the field.
Update based on comment
Move formitem tag inside custominput component and try again.
<Form id="myForm" onSubmit={this.handleSubmit}>
<CustomInput
form={this.props.form}
type="text"
disabled={this.state.disableFields}
name="code"
id="code"
placeholder=""
required={true}
errorMsg={"Please input code!"}
/>
</Form>
..
const CustomInput = ({
form, id, name, placeholder, required, errorMsg, type, disabled,}: Props) => {
return(
<Form.Item label="Code">
{form.getFieldDecorator(id, {
rules: [
{
required: required,
message: errorMsg
}
]
})(
<Input
type={type}
name={name}
id={id}
disabled={disabled}
placeholder={placeholder}
className={name === "code" ? "code-input" : "input-box"}
/>
)}
</Form.Item>
)
};

Resources