2

I am pretty new to ReactJs & trying to make a project to learn. I am using PrimeReact UI Component Library. Everything is working fine but facing issue with accessing row data into functions.

Reference - https://www.primefaces.org/primereact/splitbutton/

If I click on action button then it is showing data

Please help me out in this. Thanks in Advance.

import { DataTable } from "primereact/datatable";
import { SplitButton } from "primereact/splitbutton";

/* split button items*/
const items = [
  {
    label: "Update",
    icon: "pi pi-refresh",
    command: (e) => {
      console.log(this);
      console.log(e); /* Need to receive row data here */
      /* I am getting {item:{label: 'Update',icon: 'pi pi-refresh',command: (e) },originalEvent:{...}} I have check originalEvent.target but no data is there */
    },
  },
  {
    label: "Delete",
    icon: "pi pi-times",
    command: (e) => {
      console.log(this);
      console.log(e); /* Need to receive row data here */
    },
  },
];

/* data to show */
const griddata = [
  {
    name: "Tivaprasad Reddy",
    employeeId: "da9d1448-e1bd-4dad-9d57-dddf655c8ecf",
    mobile: "7099111460",
    Status: "SCREENING",
    addedBy: "anil kumar",
    addedOn: "2022-02-22T15:04:00.382+00:00",
  },
  {
    name: "Mukesh Bhutani",
    employeeId: "bcdefa7a-6c4d-4ac1-bd6d-025e88e08f62",
    mobile: "9582111515",
    Status: "SCREENING",
    addedBy: "anil kumar",
    addedOn: "2022-02-22T15:05:02.416+00:00",
  },
];
const splitBtn = (d) => {
  console.log(d); /* Getting data here*/
};
const buttonTemplate = (data) => (
  <>
    <SplitButton
      label="Action"
      className="p-button-sm"
      model={items}
      onClick={(e) => splitBtn(data)}
    ></SplitButton>
  </>
);
return (
  <div>
    <div className="card">
      <DataTable
        value={griddata}
        scrollable
        scrollHeight="500px"
        responsiveLayout="scroll"
      >
        <Column field="name" header="Name"></Column>
        <Column field="Title" header="Title"></Column>
        <Column field="Status" header="Status"></Column>
        {/* <Column field="Action" header="Action" body={editTemplate}></Column> */}
        <Column field="Action" header="Action" body={buttonTemplate}></Column>
      </DataTable>
    </div>
  </div>
);

data table with split button

0

4 Answers 4

4

This confused me for a while too until I came to realize it was actually pretty simple :')

You just have to use the "rowData" parameter that comes in the callback function of the "body" property of the "Column" element.

Here <Column field="Action" header="Action" body={buttonTemplate}></Column> the "buttonTemplate" callback function is already carrying the row data and presenting it in the first parameter.

So convert the "items" variable into a function that passes over that "data" parameter to your items just like this

const items = (data) => ([
  {
    label: "Update",
    icon: "pi pi-refresh",
    command: (e) => {
      console.log(e, data);
    },
  },
  {
    label: "Delete",
    icon: "pi pi-times",
    command: (e) => {
      console.log(e, data);
    },
  },
]);

const buttonTemplate = (data) => (
  <>
    <SplitButton
      label="Action"
      className="p-button-sm"
      model={items(data)}
      onClick={(e) => splitBtn(data)}
    ></SplitButton>
  </>
);

I hope this has been helpful

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I was able adopt this approach for Primevue (Vue) too
0

There are several datatable properties and you can use to achieve this by using onRowClick().

const [values, setValues] = useState({});

<DataTable
        value={griddata}
        scrollable
        scrollHeight="500px"
        responsiveLayout="scroll"
        onRowClick={(e) => { setValues(e.data) }} // setting row data in a state
      >
        <Column field="name" header="Name"></Column>
        <Column field="Title" header="Title"></Column>
        <Column field="Status" header="Status"></Column>
        <Column field="Action" header="Action" body={buttonTemplate}></Column>
      </DataTable>

Now you can get your row data by using the state variable you have used on row click.

const items = [
  {
    label: "Update",
    icon: "pi pi-refresh",
    command: (e) => {
      console.log(values); // row data
    },
  },
  {
    label: "Delete",
    icon: "pi pi-times",
    command: (e) => {
      console.log(values); // row data
    },
  },
];

1 Comment

This is working just onclicking row.. Issues: 1) If we click on update without click row.. we will get '{}'. 2) Major one is that if we click on 1st row then click on 3rd row's split button it will provide 1st row's data only.
0

You can go this way (PrimeReact):

const items =(data: any) => ([
  {
    label: "Replicate",
    icon: "pi pi-copy",
    command: async (event: MenuItemCommandEvent) => {
      console.log(event, data)
    },
  },
  {
    label: "Delete",
    icon: "pi pi-trash",
    command: () => {
    },
  },
]);


<DataTable
>
  <Column
    body={(rowData) => (
      <SplitButton
        label="Edit"
        icon="pi pi-pencil"
        model={items(rowData)}
      />
    )}
    exportable={false}
    header="Actions"
  ></Column>
</DataTable>

Thanks @Ahmed Hassan for his idea

Comments

0

In case your looking for primeng solution:

// .html
<p-splitButton
(onMenuShow)="targetRow = selectedRow"
/>

// in .ts
targetRow;
items: MenuItem[] = [
    {
      label: 'Label',
      command: () => {
        console.log(this.targetRow)
      }
    },
  ];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.