How to use React Router <Link > with an id from antd table column - reactjs

In my project, I have an antd table. In that table, I'm listing athletes. When I click on the athlete's name, I should be navigated to the athlete profile page.
Route for athlete profile /athletes/{id}
But with the table, I can't get any value for this id.
Here is my data source
[
{
email: "x#x.com",
firstName: "X",
id: 402,
lastName: "X"
},
{
email: "y#y.com",
firstName: "Y",
id: 403,
lastName: "Y"
},
{
email: "z#z.com",
firstName: "Z",
id: 404,
lastName: "Z"
}
]
And following is the code for the column object
const columns = [
{
title: "First Name",
dataIndex: "firstName",
className: "col-first-name",
render: (text) => (
<Link to={"/athletes/" + ???}>{text}</Link>
),
},
{
title: "Last Name",
dataIndex: "lastName",
className: "col-last-name"
},
{
title: "Email",
dataIndex: "email",
className: "col-email",
}
];
(I have added "???" where the id should be, in the above code)
Is there any way to add the id property into the ? Can anyone help me with this?
react-router version - "^5.1.2"
antd version - ^3.25.3

You need to pass another parameter inside render which is record which contains all data about that specific row. Something like this:
const columns = [
{
title: "First Name",
dataIndex: "firstName",
className: "col-first-name",
render: (text,record) => (
<Link to={"/athletes/" + record.id}>{text}</Link>
),
},
{
title: "Last Name",
dataIndex: "lastName",
className: "col-last-name"
},
{
title: "Email",
dataIndex: "email",
className: "col-email",
}
];
I created this demo for reference: https://stackblitz.com/edit/react-ym57ax?file=index.js

The render function receive three parameters: first one is retrieved using the dataIndex, second one is the complete record and last one is the index.
You can use:
const columns = [{
title: "First Name",
dataIndex: "firstName",
className: "col-first-name",
render: (text, record) => (
<Link to={`/athletes/${record.id}`}>{text}</Link>
),
}, {
title: "Last Name",
dataIndex: "lastName",
className: "col-last-name"
}, {
title: "Email",
dataIndex: "email",
className: "col-email",
}];

Related

How can I get the Material-UI DataGrid valueGetter to read data from a distinct object in an array?

I am developing a React Admin Page for Woocommerce. I want to retrieve the 'option' value from a specific object (product attribute with name = "Farbe") to display in a MUI DataGrid. I think that valueGetter would be the right approach, but can't get it to work.
Here's what I have:
The Woocommerce Product (row record):
{
"id": 232,
"date_created": "2022-08-14T08:02:18",
...
"attributes": [
{
"id": 0,
"name": "Farbe",
"option": "0045"
},
{
"id": 1,
"name": "Material",
"option": "Cotton"
},
...
],
...
}
The DataGrid column:
I am trying to select the object that has the value 'Farbe' on the key 'name' and access the value of the property 'option'
export const VariationColumns = [
{ field: 'id', headerName: 'Id', type: 'int', width: 100},
{ field: 'sku', headerName: 'SKU', type: 'string', width: 200},
{ field: 'name', headerName: 'Name', type: 'string', width: 500,
valueGetter: ( params ) => { return params.row.attributes[name =>'Farbe'].option }},
]
But it can't find the 'option' property:
"TypeError: Cannot read properties of undefined (reading 'option')"
Also tried:
valueGetter: ( params ) => { return params.row.attributes[name =>'Farbe'].option.value
valueGetter: ( params ) => { return params.row.attributes.name['Farbe'].option
valueGetter: ( params ) => { return params.row.attributes.name['Farbe'].option.value
Is there maybe a completely different approach needed to achieve this?
Any hint is greatly apreciated
Assuming that your rows prop looks like the record you provided above, you'd get it like so:
const rows = [
{
id: 232,
date_created: "2022-08-14T08:02:18",
attributes: [
{
id: 0,
name: "Farbe",
option: "0045",
},
{
id: 1,
name: "Material",
option: "Cotton",
},
],
},
];
const variationColumns = [
{ field: "id", headerName: "Id", type: "int", width: 100 },
{ field: "sku", headerName: "SKU", type: "string", width: 200 },
{
field: "attributes",
headerName: "Name",
type: "string",
width: 500,
valueGetter: (params) => {
return params.value.find((item) => item.name === "Farbe").option;
},
},
];
The key points are:
valueGetter params are cell params vs row params
The field property in the columns needs to match the field in your rows, so if you want to grab attributes you need to have field: "attributes" in your columns.
You can use params.value.find((item) => item.name === "Farbe").option) to return the object in the array that matches your desired search string, then access its option property.

Adding serial number to the react bootstrap table

I am using a React-bootstrap table in my project, I want to add a column in my table with a serial number but am unable to generate the serial number so kindly guide me on how to do it.
Currently am writing the below code to generate serial number but not getting the numbers in the columns.
const columns = [
{ text: 'Sn',
cell: (row, index) => index + 1 ,
headerAttrs: { width: "50px" }
},
{
text: "Customer Id",
dataField: "customerId",
classes: "alignment"
},
{
text: "Email",
dataField: "email",
classes: "alignment",
headerAttrs: { width: "200px" }
},
{
text: "Role",
dataField: "role"
},
{
text: "Date Created",
dataField: "dateCreated",
formatter: dateFormatter
},
{
text: "Customer Type",
dataField: "plan"
},
];
You can use the following formatter property to get the respective serial number.
{
dataField: 'sl.no',
text: 'Sl no.',
formatter: (cell, row, rowIndex, formatExtraData) => {
return rowIndex + 1;
},
sort: true,
},
👎The counter restarts in the next page.

React ant design table cell collapse issue

Im using my react type script project for ant design table
i want to know how to do that following image like as table, im search any tutorial but not seen anything, any one know how to do that correctly.
code sand box here
Thanks
image here
code here
class App extends React.Component {
columns: any = [
{
title: "Name",
dataIndex: "name",
key: "name"
},
{
title: "Age",
dataIndex: "age",
key: "age"
},
{
title: "Address",
dataIndex: "address",
key: "address"
},
{
title: "Tags",
key: "tags",
dataIndex: "tags"
},
{
title: "Action",
key: "action"
}
];
data: any = [
{
key: "1",
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"]
},
{
key: "2",
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park",
tags: ["loser"]
},
{
key: "3",
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park",
tags: ["cool", "teacher"]
}
];
render() {
return <Table columns={this.columns} dataSource={this.data} />;
}
}
You want to create 2 sub rows in each row, but only for some columns. you can use rowspan for this.
you can duplicate your rows (row1-row1-row2-row2-row3-row3-...), and put the subrow values in them (row1_subrow1-row1_subrow2-row2_subrow1-row2_subrow2-...), then use rowspan for the columns you want to expand (like Section and Name in your image), and expand the odd rows and collapse the even rows for this columns.
the full code : (Codesandbox Demo)
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Table } from "antd";
let multiRowRender = (value, row, index) => {
const obj = {
children: value,
props: {}
};
if (index % 2 === 0) {
obj.props.rowSpan = 2;
}
if (index % 2 === 1) {
obj.props.rowSpan = 0;
}
return obj;
};
const columns = [
{
title: "Number",
dataIndex: "number"
},
{
title: "Issue",
dataIndex: "issue"
},
{
title: "Name",
dataIndex: "name",
render: multiRowRender
},
{
title: "Section",
dataIndex: "section",
render: multiRowRender
}
];
let data = [
{
key: "1",
name: "John Brown",
issues: [32, 100],
numbers: [18889898989, 545054],
section: "sec 1"
},
{
key: "2",
name: "Jim Green",
issues: [42, 50],
numbers: [18889898888, 1420054],
section: "sec 2"
}
];
let data2 = [];
data.forEach(d => {
data2.push({ ...d, issue: d.issues[0], number: d.numbers[0] });
data2.push({
...d,
issue: d.issues[1],
number: d.numbers[1],
key: d.key + "-row2"
});
});
data = data2;
ReactDOM.render(
<Table columns={columns} dataSource={data} bordered />,
document.getElementById("container")
);
Codesandbox Demo

How to hide backgrid column?

Hi friends. I'm using backgrid in my project. I want to hide Id column from backgrid. Here is my code.
var columns = [
{ name: "id", label: "Id", cell: "integer", editable: false },
{ name: "payment_date", label: "Payment Date", cell: "date" ,editable: false },
{ name: "number_of_task", label: "Total Task", cell: "integer" ,editable: false },
{ name: "amount", label: "Amount", cell: "integer" ,editable: false }
];
add a renderable: false attribute. See renderable here http://wyuenho.github.io/backgrid/api/index.html#!/api/Backgrid.Column
Simply remove the column definition. You don't need a column definition for each addribute in your data; you only need the column definition of attributes you want visible in the table.
var columns = [
{ name: "payment_date", label: "Payment Date", cell: "date" ,editable: false },
{ name: "number_of_task", label: "Total Task", cell: "integer" ,editable: false },
{ name: "amount", label: "Amount", cell: "integer" ,editable: false }];
The attribute renderable:false didn't work for me hence used below as workaround
var HideCell = Backgrid.HideCell = Backgrid.Cell.extend({
/** #property */
className: "hide-cell",
initialize: function () {
Backgrid.Cell.prototype.initialize.apply(this, arguments);
},
render: function () {
this.$el.hide();
return this;
}
});
use in column as cell "hide"
var columns = [
{ name: "id", label: "Id", cell: HideCell, editable: false }
];

Backgrid unable to render columns

I am just learning the basics of backgrid.js. So when I attempt to replicate the code on the main page Backgrid.js, I am unable to render a grid due to a particular error when passing in an array of objects for the columns. I believe I am using proper format
var columns = [
{ name: "name", label: "Name", cell: "string" },
{ name: "address", label: "Address", cell: "string" },
{ name: "tel", label: "Phone", cell: "integer" },
{ name: "email", label: "Email", cell: "string" },
{ name: "type", label: "Contact Type", cell: "string" }
];
The error Uncaught TypeError: Object [object Object] has no method 'listenTo' occurs in the process of initializing the grid at this step:
var grid = new Backgrid.Grid({
columns: columns,
collection: this.collection
});
Is there an issue with how I am initializing the grid?
The issue was with the version of backbone.js I was using. I reccommend using the proper version of libraries.
Backgrid.js depends on 3 libraries to function:
jquery >= 1.7.0, underscore.js ~ 1.4.0, and backbone.js ~ 0.9.10.
Here's a simple structure on how to use it.
HTML
<div id="container"></div>
JS
$(function(){
/** Columns definition */
var columns = [
{ name: "name", label: "Name", cell: "string" },
{ name: "address", label: "Address", cell: "string" },
{ name: "tel", label: "Phone", cell: "integer" },
{ name: "email", label: "Email", cell: "string" },
{ name: "type", label: "Contact Type", cell: "string" }
];
/** Model instance */
var mdl = Backbone.Model.extend({});
/** Collection instance */
var col = Backbone.Collection.extend({
model: mdl
});
/** Test array of JSON (usually coming from a server) */
var json = [
{"name": "Goose", "address": "a 1st address", "tel": 25500100, "email": "w#test.net","type": 1},
{"name": "Ducky", "address": "a 2nd address", "tel": 25500123, "email": "w#test1.net","type": 2}
];
/** Create the Grid */
var grid = new Backgrid.Grid({
columns: columns,
collection: new col(json)
});
/** Add the Grid to the container */
$("#container").append(grid.render().$el);
});

Resources