Setting the value of an input field in antd react JS - reactjs

I want to set the value of a field based on what I have in the database. Make it ineditable but also want the ability for customers to copy that value. I am able to read the values on submit but I dont know how to set them initially. I am using this
form.setFieldsValue({
clientID: 'value from database',
});
but its not working.
const APIAccess = () => {
const [form] = Form.useForm();
const dbvalues = "some value from database"
form.setFieldsValue({
clientID: dbvalues,
});
const handleSubmit = (value) =>
{
const payload = {
"appName" : form.getFieldValue('appName') ,
}
return (
<Form
name="control-hooks"
form={form}
>
<Form.Item
label="App Name"
name="appName"
rules={[
{
required: true,
message: 'Please select an App Name!',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Your Client ID"
name="clientID"
>
<Input.Group >
<Space>
<Input/>
<Tooltip title="copy your Client ID">
<Button icon={<CopyOutlined />} onClick={() => {navigator.clipboard.writeText(clientID)}}/> </Tooltip>
</Space>
</Input.Group>
</Form.Item>
<Form.Item
>
<Button type="primary" htmlType="submit" onClick={handleSubmit}>
Save
</Button>
</Form.Item>
</Form>)

You don't want to programmatically set each initial value. Instead, pass all the initial values to the Form component:
<Form
initialValues={{
clientID: some_client_id,
}}
/>

Related

How do you get a nested value item in ant design

im quite new on reactJS and also ant design. right now im trying to get a value from a Form.List that i want to make it / render it as json nested data output.
my full code :
import { MinusCircleOutlined, PlusOutlined } from '#ant-design/icons';
import { Button, Form, Input, Space, DatePicker, Select } from 'antd';
import axios from 'axios'
import { useNavigate } from 'react-router-dom'
import Cookies from "js-cookies";
import moment from 'moment';
import 'moment/locale/zh-cn';
const Stockpickingnew = ({ title }) => {
const options = [
{
value: '1',
label: 'True',
},
{
value: '0',
label: 'False',
},
{
value: '7',
label: 'product_tmpl_id'
},
];
const Navigate = useNavigate()
const dateFormat = ['DD-MM-YYYY'];
//---------------------------------------------------------------------------------------------------------------
let headers = {
"Authorization": "Bearer " + Cookies.getItem('access_token')
}
const onFinish = (values) => {
console.log('Success:', values);
let stockpick = {
date: moment(values.date).format("DD-MM-YYYY"),
origin: values.origin,
picking_type_id: values.picking_type_id,
location_id: values.location_id,
location_dest_id: values.location_dest_id,
stock_move_ids: [{
demand: values.demand,
done: values.done,
product_uom: values.product_uom,
product_tmpl_id: values.product_tmpl_id,
}]
};
console.log(JSON.stringify(stockpick))
let params = JSON.stringify(stockpick)
axios.post('http://127.0.0.1:5000/api/stockpickings', params, { headers })
.then(() => {
Navigate('/')
})
.catch(error => {
if (error.response) {
console.log(error.response);
}
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
//---------------------------------------------------------------------------------------------------------------
return (
<>
<div className='new'>
<div className="top">
<h1>{title}</h1>
</div>
<div className="bottom">
<div className="stockPicking">
<Form
name="stockPickings"
layout="vertical"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<div className="left">
<Form.Item
label="Origin :"
name='origin'
>
<Select
options={options}
placeholder="Origin"
/>
</Form.Item>
<Form.Item
label="Picking Type :"
name='picking_type_id'
>
<Select
options={options}
placeholder="Picking Type"
/>
</Form.Item>
<Form.Item
label="Date :"
name='date'
>
<DatePicker
format={dateFormat}
onChange={(dateInMomentFormat, dateInStringFormat) => {
console.log(dateInStringFormat);
}}
/>
</Form.Item>
</div>
<div className="right">
<Form.Item
label="Location :"
name='location_id'
>
<Select
options={options}
placeholder="Location"
/>
</Form.Item>
<Form.Item
label="Destination :"
name='location_dest_id'
>
<Select
options={options}
placeholder="Destination"
/>
</Form.Item>
</div>
<div className="stockMove">
<Form.Item>
<Form.List name="stock_move_ids">
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<Space
key={field.key}
style={{
display: 'flex',
marginBottom: 8,
}}
align="baseline"
>
<Form.Item
{...field}
name={[field.name, 'demand']}
key={[field.key, 'demand']}
rules={[
{
required: true,
message: 'Missing Demand',
},
]}
>
<Input placeholder="Demand" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'done']}
key={[field.key, 'done']}
>
<Select
options={options}
placeholder="Done"
/>
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'product_uom']}
key={[field.key, 'product_uom']}
rules={[
{
required: true,
message: 'Missing product_uom',
},
]}
>
<Select
options={options}
placeholder="product_uom"
/>
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'product_tmpl_id']}
key={[field.key, 'product_tmpl_id']}
rules={[
{
required: true,
message: 'Missing product_tmpl_id',
},
]}
>
<Select
options={options}
placeholder="product_tmpl_id"
/>
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add field
</Button>
</Form.Item>
</>
)}
</Form.List>
</Form.Item>
</div>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</div>
</div>
</div>
</>
)
}
export default Stockpickingnew
im sorry if it's really hard to read but basically, what i really want to do is my Form.List can get a value as nested data like :
stock_move_ids: [{
demand: values.demand,
done: values.done,
product_uom: values.product_uom,
product_tmpl_id: values.product_tmpl_id,
}]
my console.log (values) and console.log JSON.stringify(stockpick) do have different result as image below.
first one is from console.log values and the bottom one is from console.log stockpick
Screenshoot here
stock_move_ids values have 0th index you can access it like this.
let stockpick = {
date: moment(values.date).format("DD-MM-YYYY"),
origin: values.origin,
picking_type_id: values.picking_type_id,
location_id: values.location_id,
location_dest_id: values.location_dest_id,
stock_move_ids: [
{
demand: values?.stock_move_ids?.[0]?.demand,
done: values?.stock_move_ids?.[0]?.done,
product_uom: values?.stock_move_ids?.[0]?.product_uom,
product_tmpl_id: values?.stock_move_ids?.[0]?.product_tmpl_id,
},
],
};

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>

Display an error if the password and login are incorrect in Form. Antd React

The task is as follows, when you press the LOGIN button, a request is sent to the server with a password and login, if they are incorrect, then under the password entry line you need to display the corresponding error and all input fields should be highlighted in red.
How can you achieve this?
I tried to do it for a very long time using built-in validators in Form.Item . So, since I don't need to worry about changing the color of input fields, the validator does it itself, but I got confused about these validators and I got an infinite loop.
Here is some of the code for the Login page.
export const LoginPage = () => {
const { dispatch } = useAuthContext()
const onFinish = (values: any) => {
APIs.requestLogin(values.username, values.password, false)
.then((response: any) => {
dispatch({ type: SIGN_IN, payload: response.data })
})
.catch(() => {
console.log('error')
})
}
return (
<div className={classes.root}>
<div className={classes.container}>
<Form
className={classes.form_container}
name="normal_login"
initialValues={{ remember: true }}
onFinish={onFinish}
>
<Form.Item
className={classes.form_input}
name="username"
rules={[{ required: true, message: 'Please enter your username!' }]}
>
<Input
autoFocus={true}
className={classes.input_style}
placeholder="Username"
prefix={<UserOutlined className="site-form-item-icon" />}
/>
</Form.Item>
<Form.Item
className={classes.form_input}
name="password"
rules={[{ required: true, message: 'Please enter your password!' }]}
>
<Input.Password className={classes.input_style} placeholder="Password" prefix={<LockOutlined />} />
</Form.Item>
<Form.Item className={classes.form_submit}>
<Button className={classes.form_button_submit} type="primary" htmlType="submit">
LOGIN
</Button>
</Form.Item>
</Form>
<div className={classes.image} />
</div>
</div>
)
}

Antd Select not setting initial value

I have an issue in setting the initial value in antd Select
const options=[{name:'john',id:1},{name:'jack',id:2},{name:'jill',id:3}]
<Form initialValues={{user:3}}>
<Form.Item name="user" label="Select user">
<Select value="3">
{options.map((user,index)=><Option key={index} value={user.id}>{user.name}</Option>)}
</Select>
</Form.Item>
</Form>
It's not selecting the initial value. Any idea in this. is this a correct way of implementing it, please help
The below is a simple demo of Select Component in Antd Form
I am wondering whether the options come from the store or other components? So the form does not get the initial values once the form is mounted. If it comes from other source, you need to subscribe the initial values if it changes to reset the antd form like
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, Button, Checkbox, Select } from 'antd';
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};
const tailLayout = {
wrapperCol: {
offset: 8,
span: 16,
},
};
// useEffect(() => {
// form.resetFields()
// form.setFieldsValue({
// productName: productName
// })
// }, [initialValues]);
const userNameOptions = [{name:'john',id:1},{name:'jack',id:2},{name:'jill',id:3}]
const Demo = () => {
const onFinish = (values) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
username: 3
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Select value='3'>
{userNameOptions.map((item, index) => (
<Select.Option key={index} value={item.id}>
{item.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
label="Password"
name="password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout} name="remember" valuePropName="checked">
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, document.getElementById('container'));
I have this working in ant design 4.
If you only need to set the value once use defaultValue and pass a string prop
defaultValue={!!props.DefaultString && claimId}
You can however set the values for both the current value and the options by using form.setFieldsValue in useEffect.
e.g.
useEffect(() => {
form.setFieldsValue({
SelectValue: !!props.selectItemValue && props.props.claimId,
SelectableOptions: (!!props.selectableOptions? props.selectableOptions : undefined)
);
}
}, [props,form]);
<Form.Item name="SelectValue" >
<Select >
{!!props.selectableOptions && props.selectableOptions.map((opt) => <Option key={opt.id} value={opt.id}>{opt.name}</Option>)}
</Select>
</Form.Item>
NB: Use the props directly rather than the fieldValue for the options

Antd form remote submit

I want to trigger the submit button outside the antd form
Here is my code
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[
{
required: true,
message: 'Please input your username!',
},
]}
>
<Input />
</Form.Item>
<Form.Item {...tailLayout}>
// Submit button here works well
</Form.Item>
</Form>
I want this outside form tag, please suggest
<Button type="primary" htmlType="submit">
Submit
</Button>
You can try this way:
const [form] = Form.useForm();
const handleFinish = (values) => {
console.log("values: ", values);
};
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<MyForm form={form} onFinish={handleFinish} />
<Button onClick={() => form.submit()}>Submit</Button>
</div>
);
export const MyForm = ({ form, onFinish }) => {
return (
<Form
form={form}
onFinish={onFinish}
initialValues={{ username: "John Doe" }}
>
<Form.Item name="username">
<Input />
</Form.Item>
</Form>
);
};
If the form and the button are not in the same component then it is hard to create same reference for the form in 2 different place. But I found an other easy way:
<Form id="myForm">...</>
...
<Button form="myForm" key="submit" htmlType="submit">
Submit
</Button>
This is the answer from this issue
write a custom function like this:
function handleSubmit(){
form.validateFields().then((values) => {
// do something with values
})
}
and call it from Button onClick. so you don't need Form onFinish props.
sorry i was searching and see this old question.
as in the comment you should use
const [form] = Form.useForm();
that's a lot of function you can use one of them is submit.
form.submit();
you can refer to document and search for useform:
https://ant.design/components/form/

Resources