using ant design switch inside Forms - reactjs

What's the correct way to use ant design switch inside, I could not get much from the official documentation.
Switch-Ant Design
Here's how I am using it.
<Form form={form} layout="vertical">
<Form.Item
label="Description"
name="description"
rules={[{ required: true, message: 'Enter a description' }]}
>
<Input placeholder="Enter Description" />
</Form.Item>
<Form.Item name="switch" noStyle valuePropName="checked">
<Switch checkedChildren="Yes" unCheckedChildren="No" />
<span>Chargable</span>
</Form.Item>
<Button
onClick={() => {
form
.validateFields()
.then((values) => {
form.resetFields()
onCreate(values)
})
.catch((info) => {
console.log('Validate Failed:', info)
})
}}
>
Save
</Button>
</Form>
onCreate does no take the value from the switch, It does take it from the description
const onCreate = (values) => {}

I was able to fix it but doing the following.
<td>
<Form.Item valuePropName="checked" name="status" noStyle>
<Switch checkedChildren="Yes" unCheckedChildren="No" />
</Form.Item>
<span className="ml-2">Status Enabled</span>
</td>

I guess your values are {description: "foo", switch: undefined}?
In my demo, switch demo, I add initialValue to Switch, so when I get values from the form, I get {description: "111", switch: true}.
I don't know whether this is what your mean.
or you can use like this
<Form.Item label="foo">
<Form.Item name="bar">
<Switch />
</Form.Item>
<span className="ant-form-text">Some text you want</span>
</Form.Item>

This is because you must only have one child inside a Form.Item component. Remove the span besides your Switch component and it will work.

Related

How to get error message by getFieldError in AntD Form?

I'm validating form with Ant Design but I have a problem with getFieldError(). I need to get the error messages by the field name of Form.Item but it not works.
Here's my code not works below:
...
<Form form={form} name="login_form" onFinish={onFinish} scrollToFirstError>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Password cannot be empty!',
},
]}
help='' // hide validating message.
>
<>
{({ getFieldError }) => console.log(getFieldError('password'))}
//it not logging anything when submit form trigger error
<Input.Password placeholder="Enter your password" />
</>
</Form.Item>
</Form>
How can I solved this problem?
Your console.log will invoke, every time your component renders, so you need to rerender your component whenever validation applies on the form. To handle this situation you can use render prop with Form component, like this:
function CustomFormItem({ error, ...other }) {
console.log(error)
return <Input.Password placeholder="Enter your password" {...other} />;
}
function MyForm() {
const [form] = Form.useForm();
const onFinish = (values) => {
console.log(values);
};
return (
<Form
form={form}
name="login_form"
onFinish={onFinish}
scrollToFirstError
>
{(values,formInstance) => {
return (
<>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Password cannot be empty!',
},
]}
help="" // hide validating message.
>
<CustomFormItem error={formInstance.getFieldError('password')} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</>
);
}}
</Form>
);
}
Consider that with above implementation, render prop will call with every change on the form.
Use can use getFieldError(); like the code example below
Function as Child Component is not working perfectly inside <Form.Item> component as of now.
<Form {...layout} form={form} name="control-hooks" onFinish={onFinish}>
{(values, formInstance) => {
console.log(formInstance.getFieldError("password")[0]);
return (
<>
<Form.Item
name="password"
label="Password"
rules={[
{
required: true
}
]}
>
<Input />
</Form.Item>
</>
);
}}
</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.

Reactjs antd defaultValue return undefined

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',
}}
>

Dynamic Form with initial values

Sorry for my english.
Like in this example
https://codesandbox.io/s/wonderful-lichterman-br63z?file=/index.js
Form.List is rendering the Array of "Fields" which initally is empty.
I would like to put my own array to be rendered from the start.
Expected result
you can do it using initialValues prop of Form.
Working example: https://codesandbox.io/s/bold-turing-g8ft6?file=/index.js
Docs: https://ant.design/components/form/#API
The docs are a bit short on explanation for the Form.List, and since a code sample is worth a thousand words...
This renders the dynamic form list with one item already visible:
const initialValues = {
users: [
{ age: undefined } // undefined will render the placeholder
]
};
<Form initialValues={initialValues}>
<Form.List name="users">
{(fields, { add }) => {
return (
<div>
{fields.map(field => (
<Row key={field.key}>
<Col>
<Form.Item
placeholder="age"
name={[field.age, 'age']}
>
<Input />
</Form.Item>
</Col>
<Col>
<Form.Item
placeholder="sex"
name={[field.sex, 'sex']}
>
<Input />
</Form.Item>
</Col>
<Col>
<Form.Item
placeholder="name"
name={[field.name, 'name']}
>
<Input />
</Form.Item>
</Col>
</Row>
))}
<button onClick={() => add()}>Add</button>
</div>
)
}}
</Form.List>
</Form>

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