フォームフィールドを含むダイアログを表示するクイックアクションボタンをレコード表示ビューに追加したいと思います。
フォームが送信されたときに、提供されたデータがフォームフィールドデータといくつかのオプションを使用して更新アクションをディスパッチするようにします。
データプロバイダーに更新アクションをディスパッチするアクションボタンを作成する方法を知っていますが、ダイアログでフォームを処理する方法について行き詰まっています。
そこで、TextInput
(from react-admin
)が付いたダイアログを表示するボタンを作成することから始めました。
const ValidateButton: FC<ButtonProps> = ({ record }) => {
const [open, setOpen] = useState<boolean>(false);
const handleInit = () => {
setOpen(true)
}
const handleCancel = () => {
setOpen(false);
}
const handleSubmit = () => {
setOpen(false);
}
return (
<>
<Button
label="Validate"
onClick={handleInit}
>
<ValidateIcon />
</Button>
<Dialog
open={open}
>
<DialogTitle>Validate</DialogTitle>
<DialogContent>
<TextInput
source="comment"
label="Validation comment"
/>
</DialogContent>
<DialogActions>
<Button
label="Cancel"
onClick={handleCancel}
/>
<Button
label="Validate"
onClick={handleSubmit}
/>
</DialogActions>
</Dialog>
</>
);
}
これにより、次のエラーが発生しました。
Error: useField must be used inside of a <Form> component
上手。かなりクリアな。だから私はそれをSimpleForm
コンポーネントにラップしてみました:
<DialogContent>
<SimpleForm
form={createForm({ onSubmit: handleSubmit })}
resource="rides"
record={record}
>
<TextInput
source="comment"
label="Validation comment"
/>
</SimpleForm>
</DialogContent>
それから私は得ました:
TypeError: can't access property "save", context is undefined
useSaveContext
node_modules/ra-core/esm/controller/details/SaveContext.js:23
20 | */
21 | export var useSaveContext = function (props) {
22 | var context = useContext(SaveContext);
> 23 | if (!context.save || !context.setOnFailure) {
24 | /**
25 | * The element isn't inside a <SaveContextProvider>
26 | * To avoid breakage in that case, fallback to props
は、[ValidateButton
ビューの表示]ツールバーに実装されています。
const RideShowActions: FC<ShowActionsProps> = ({ basePath, data }) => {
if (!data) {
return null;
}
return (
<TopToolbar>
<ValidateButton />
{[
'created',
'validated',
'confirmed',
].includes(data?.status) && <CancelButton basePath={basePath} record={data} />}
<EditButton basePath={basePath} record={data} />
</TopToolbar>
);
};
export const RideShow: FC<ShowProps> = (props) => (
<Show
title={<RideTitle />}
actions={<RideShowActions />}
{...props}
>
<SimpleShowLayout>
// Show classic stuff.
</SimpleShowLayout>
</Show>
);
最後のエラーは、SimpleForm
上に配置する必要があるためだと思います<Edit>
。
私の目標は、ダイアログの編集フォームと同じ機能とUX / UIデザインの入力を取得し、カスタムアクションを実行することです。
私が欠けているものは何ですか?どうすればそれを達成できますか?
注:のTextField
コンポーネントを直接使用しようとしました@material-ui/core
。それは機能しますが、私にとって役立つすべてのreact-admin機能を失いますReferenceInput
。
DialogForm
フォーム自体やアクションボタンなどの一般的なロジックを組み合わせて、カスタムコンポーネントを作成することで、最終的に解決策を見つけました。
import { FC, MouseEventHandler } from 'react';
import { Button } from 'react-admin';
import { Dialog, DialogProps, DialogTitle, DialogContent, DialogActions } from '@material-ui/core'
import { Form } from 'react-final-form';
import { Config } from 'final-form';
export interface DialogFormProps {
open: DialogProps['open'],
loading?: boolean;
onSubmit: Config['onSubmit'],
onCancel: MouseEventHandler,
title?: string,
submitLabel?: string;
cancelLabel?: string;
}
export const DialogForm: FC<DialogFormProps> = ({
open,
loading,
onSubmit,
onCancel,
title,
cancelLabel,
submitLabel,
children,
}) => {
return (
<Dialog
open={open}
>
<Form
onSubmit={onSubmit}
render={({handleSubmit}) => (
<form onSubmit={handleSubmit}>
{title && (
<DialogTitle>
{title}
</DialogTitle>
)}
<DialogContent>
{children}
</DialogContent>
<DialogActions>
<Button
label={cancelLabel || 'Cancel'}
onClick={onCancel}
disabled={loading}
/>
<Button
label={submitLabel || 'Validate'}
type="submit"
disabled={loading}
/>
</DialogActions>
</form>
)}
/>
</Dialog>
)
};
export default null;
上記の例をコピーして貼り付けると、そのまま使用できます。
ボタンを使用した実装例を次に示します。
const ValidateButton: FC<ButtonProps> = ({ record }) => {
const [open, setOpen] = useState<boolean>(false);
(undefined);
const [mutate, { loading }] = useMutation();
const notify = useNotify();
const refresh = useRefresh();
const handleInit = () => {
setOpen(true)
}
const handleCancel = () => {
setOpen(false);
}
const handleSubmit: DialogFormProps['onSubmit'] = (values) => {
console.log(values);
mutate(
// Your mutation logic.
);
}
return (
<>
<Button
label="Validate"
onClick={handleInit}
>
<ValidateIcon />
</Button>
<DialogForm
open={open}
loading={loading}
onSubmit={handleSubmit}
onCancel={handleCancel}
title="Validate that thing"
submitLabel="Let's go!"
>
<DialogContentText>
Some text.
</DialogContentText>
<ReferenceInput
source="referenceId"
label="Reference"
reference="service"
filter={{ userId: record?.customerId }}
>
<SelectInput
optionText="name"
resettable
fullWidth
/>
</ReferenceInput>
</DialogForm>
</>
);
}
それが何とか役立つことを願っています!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加