简体   繁体   中英

Devexpress DataGrid child object editing in React

I have a DataGrid anche inside it I have a child array. It's defined like:

{
id: 2,
attachments: [
{attachmentId: 1001, mandatory: true, name: "ordine"}, 
{attachmentId: 1002, mandatory: true, name: "ordine 2"} ]
..and so on with other fields..
}

Now I want to edit it in mode="form" and I'm not understanding how can I define a editCellComponent to allow the user to add, remove or edit for attachments.

I'm trying to create a Component to manage it with no luck.

interface Props {
    data: any
}

export const AttachmentDataGrid : React.FC<Props> = ({ data } : Props) => {
  const [ attachments, setAttachments ] = useState<any[]>([]);

  useEffect(() => {
    setAttachments(data.value);
  }, []);

  const onValueChanged = (e : any) => {
    data.setValue(e.value);
  }

  const onSelectionChanged = () => {
    data.component.updateDimensions();
  }

  return <>
            <GroupItem caption="Attachment"
              name="phones-container">
                  { attachments.map((att, index) => {
                      return <GroupItem
                      name="attachments"> 
                       <Label text={`Attachments ${index + 1}`} />
                       {att.name}
                                  <SimpleItem dataField={`attachments[${index}].name`} />
                                  <SimpleItem dataField={`attachments[${index}].mandatory`} />
                      </GroupItem>
                    })}
              <SimpleItem itemType="button"
                cssClass="add-attachment-button"
                 onClick={() => { console.log('add-attachment') }}> 
                >
              </SimpleItem>
            </GroupItem>
         
          </> 
  
}

This component show me nothing T_T Did someone achieve something like this and can share code to let me understand how to control it?

I want something like this在此处输入图像描述

You can handle a React Component inside the editCellComponent template, where the callback provided by the devexpress component allows you to handle a nested state and to notify the DataGrid that a row state change is requested.

In case the user will confirm the Form Changes, the changes of the underlying component will be saved, you can check this Sandbox for an example: https://codesandbox.io/s/row-editing-and-editing-events-devextreme-data-grid-forked-my6phn?file=/App.js:2470-3127

Summarizing, the relevant part is the column:

<Column
            dataField="Attachments"
            width={250}
            cellRender={(v) => (
              <span>
                {v.value
                  ?.map(
                    (i) =>
                      `${i.name} - ${
                        i.mandatory ? "mandatory" : "not mandatory"
                      }`
                  )
                  .join("; ")}
              </span>
            )}
            editCellComponent={({ data }) => {
              const { value, setValue } = data;

              return (
                <AttachmentsGridEditor value={value} setValue={setValue} />
              );
            }}
          />

And the component itself (please consider these as pure examples, not ready for production usage):

import { useCallback, useEffect, useState } from "react";

export default function AttachmentsGridEditor({ value, setValue }) {
  const [localState, setLocalState] = useState(value);

  const triggerSampleCheckboxChange = useCallback(
    (idx) => {
      const vCopy = [...localState];
      vCopy[idx] = {
        ...vCopy[idx],
        mandatory: !vCopy[idx].mandatory
      };

      setLocalState([...vCopy]);
    },
    [localState, setLocalState]
  );

  // Because DevExpress does not trigger component re-render, a local state
  // has to be kept to allow sync between the two states.
  useEffect(() => {
    setValue([...localState]);
  }, [localState, setValue]);

  // TODO: normalize components, compute a better key
  return (
    <div>
      {localState.map((attachment, attachmentIndex) => (
        <div key={"attachment" + attachmentIndex + Math.random()}>
          <input type="text" readOnly defaultValue={attachment.name} />
          <input
            type="checkbox"
            defaultChecked={attachment.mandatory}
            onChange={() => triggerSampleCheckboxChange(attachmentIndex)}
          />
        </div>
      ))}
    </div>
  );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM