Conflict on the React ant design table input total balance - antd

Im tried to do some calculate part for my react ant design 4 table, i don't have idea for how to get when i entered value after get automatically calculate total and then submit. any onw know how to do that correctly.
Thanks
stack blitz here
This is my code part
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Book',
dataIndex: 'book',
key: 'book',
},
{
title: 'Pen',
dataIndex: 'pen',
key: 'pen',
},
{
title: 'Tools',
key: 'tools',
dataIndex: 'tools',
},
{
title: 'Total',
key: 'total',
dataIndex: 'total',
},
];
const data = [
{
key: '1',
name: 'John Brown',
book: <Form.Item name="book1" rules={[{required: true, message: " is required"}]}><Input style={{width: 150}}/></Form.Item>,
pen: <Form.Item name="oen1" rules={[{required: true, message: "is required"}]}><Input style={{width: 150}}/></Form.Item>,
tools: <Form.Item name="tools1" rules={[{required: true, message: " is required"}]}><Input style={{width: 150}}/></Form.Item>,
total:'00000'
},
];
const onFinish = values => {
console.log(values);
};
ReactDOM.render(
<div>
<Form name="control-hooks" onFinish={onFinish}>
<Table columns={columns} dataSource={data} />
<div>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</div>
</Form>
</div>, document.getElementById('container'));

I assumed the rows can be more than one. You can achieve this by:
You need a state. In react, in order to change something on the UI (e.g. total column) you need a state. Put your data array in state.
const [data, setData] = useState([ ... ])
You need to know which row the input was when you type in. You may add some distinction on input that is equal to row key. Here I suggest to put some number on the name of input:
<Form.Item name="book-1">...</Form.Item>
<Form.Item name="pen-1">...</Form.Item>
<Form.Item name="tools-1">...</Form.Item>
Use onValuesChange prop of the <Form> it triggers every time you type on the inputs and return the form values. With this, you can extract the number on input name and use that as a reference to know which row is about to change and perform setState.
I also suggest to use InputNumber instead of Input if you only need a number input.
Here is the working link. You can start/play around there if I did not hit what you want.
You may also look on antd table editable rows. This might be easiest to use than this

Related

How to set array in useForm and validate the length of value?

I'm using react-hook-form.
What I wanna do is to push a value to an array and
validate the length of value.
This is defaultValue.
defaultValues: {
title: '',
role: '',
language: {source: '', target: []},
industry: '',
due_at: '',
content: '',
},
and this is input field that handles language.target.
<Controller
name="language.target"
control={control}
rules={{
required: true,
setValues: (v) => setValue([...getValues('language.target'), v.value]),
validate: (value) => {
return '';
},
}}
render={({field: {onChange}}) => (
<Select
options={languageIndex}
onChange={(value) => onChange(value.value)}
value={languageIndex.filter(
(item) => item.value === getValues('language.target')
)}
placeholder="Select"
/>
)}
/>
I tried this way to push a value like below and they didn't work..
setValues: (v) => setValue([...getValues('language.target'), v.value]),
setValues: (v) => [...getValues('language.target'), v.value],
also I have no idea how to validate the length of array.
If language.target.length is greater then 3,
I want to make it stop to set value.
If there's any good idea, please share with me! Thanks.

nested dataIndex in Table of Ant Design

this is my code below
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: 'status',
render: (text) => <a> {text} </a>
},
];
I wanna display data ( text/id ) like below code
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: ['status', 'id'],
render: (text) => <a> {text} / {id} </a>
},
];
I tried to like this samples
1. dataIndex: ['status', 'id']
2. dataIndex: 'status.id'
but that doesn`t work. (version 4.14.0)
how can I display like that? please reply here. thanks.
I'll answer assuming what you pass to the dataSource is an array of objects which looks like below.
interface DataModel {
id: number;
status: string;
}
If so, you can use the second parameter in the render method which will have the record. Hence record.id will give you the id.
const columns = [
{
key: '1',
title: 'id',
dataIndex: 'id'
},
{
key: '2',
title: 'status',
dataIndex: ['status'],
render: (text: any, record: any) => <a> {text} / {record.id} </a>
},
];
try this solution
{
title: 'Name',
dataIndex: 'address',
key: 'name',
render: ({ city, street }) => (
<Typography>{`${city} ${street}`}</Typography>
),
},
try this
{
title: "Task",
dataIndex: ["task","name"]
},

ANT design 4 table input filed validate

Im adding my react project for ant design4 table and ant design input fields. any one know to how can validate that input required
Thanks
stackablitz here
code here
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
render: text => <a>{text}</a>,
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Tags',
key: 'tags',
dataIndex: 'tags',
render: tags => (
<>
{tags.map(tag => {
let color = tag.length > 5 ? 'geekblue' : 'green';
if (tag === 'loser') {
color = 'volcano';
}
return (
<Tag color={color} key={tag}>
{tag.toUpperCase()}
</Tag>
);
})}
</>
),
},
{
title: 'Action',
key: 'action',
render: (text, record) => (
<Space size="middle">
<a>Invite {record.name}</a>
<a>Delete</a>
</Space>
),
},
];
const data = [
{
key: '1',
name: 'John Brown',
age: <input/>,
address: 'New York No. 1 Lake Park',
tags: ['nice', 'developer'],
},
{
key: '2',
name: 'Jim Green',
age: <input/>,
address: 'London No. 1 Lake Park',
tags: ['loser'],
},
{
key: '3',
name: 'Joe Black',
age: <input/>,
address: 'Sidney No. 1 Lake Park',
tags: ['cool', 'teacher'],
},
];
const onFinish = values => {
console.log(values);
};
ReactDOM.render(
<div>
<Form name="control-hooks" onFinish={onFinish}>
<Table columns={columns} dataSource={data} /> <div><Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button> </Form.Item>
Just enclose the <input/> in <Form.Item> and use the rules prop of it. You can see all the possible rules here. I suggest use the <Input/> of antd and set a width on it.
const data = [
{
key: "1",
name: "John Brown",
age: (
<Form.Item
name="age1"
rules={[{ required: true, message: "Age is required" }]}
>
<Input style={{ width: 150 }} />
</Form.Item>
),
address: "New York No. 1 Lake Park",
tags: ["nice", "developer"],
},
...
];
see this working link

Tabulator copyToClipboard method isn't working as anticipated

I am new to the Tabulator plug-in and I am attempting to copy data from one table to another using the Tabulator copyToClipboard method but with no success.
In my application I have created eleven <div> elements (one for the [Crew Leader] and one each for up to ten [Crew Members]) to serve as containers for the Tabulator tables to be instantiated. I am hoping to copy data from the [Crew Leader] table and paste it into each of the affected [Crew Member] tables thus mitigating data re-entry. This sequence of copy/paste events is triggered by the click event bound to a <button> in the header of the [Crew Leader] table. The following function is called by the <button> click event:
function CloneTable() {
// Verify the [Crew Leader] Tabulator table is present....
var tableLeader = Tabulator.prototype.findTable("#CrewLeaderTable");
if (tableLeader.length > 0) {
alert("The Tabulator table #CrewLeaderTable was found.\ntable.length = " + tableLeader.length);
tableLeader.copyToClipboard("all");
alert("The table contents were copied to the clipboard.");
}
else {
alert("The Tabulator table #CrewLeaderTable was not found.");
}
}
The first alert message verifies that the #CrewLeaderTable object has been found as anticipated. However, the second alert verification is never received thus indicating failure of the Tabulator copyToClipboard method.
I have read through as much of the relevant Tabulator documentation as I can find and I am hoping I have simply overlooked something in my setup.
The following is a copy of my Tabulator constructor:
var table = new Tabulator(divid, {
height: "100%",
layout: "fitDataFill",
movableRows: true, //enable user movable rows
tabEndNewRow: true, //create empty new row on tab
rowContextMenu: myActionContextMenu,
keybindings: {
"navUp": true, //enable navUp keybinding using the "up arrow" key
"navDown": true, //enable navDown keybinding using the "down arrow" key
},
columns: [
{ title: "Phase Code", field: "phaseCode", width: 144, editor: "select", editorParams: { values: function (cell) { return window.laborPhaseCodes; } } },
{ title: "Date Worked", field: "dateComp", hozAlign: "center", sorter: "date", editor: dateEditor },
{ title: "Start Time", field: "timeStart", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Finish Time", field: "timeFinish", hozAlign: "center", sorter: "time", editor: timeEditor },
{ title: "Memo", field: "memo", width: 144, hozAlign: "left", editor: "input" },
{ title: "<button type='button' id='btnClone' class='btn btn-success btn-sm py-0' style='font-size:10px;'>Clone</button>", headerSort: false, headerClick: tabCloneTable }
],
cellEdited: function (cell) {
}
});
I have spent a couple of days trying to figure out the best way to "clone" the data from one table into another. The Tabulator documentation is fairly comprehensive but I fear I have overlooked something. Any assistance is greatly appreciated.
It looks like copyToClipboard doesn't return the data, it is maintained internally and not accessible. But, with what you are doing set/getData works fine.
Here is an example, https://jsfiddle.net/nrayburn/19sjg74k/7/.
Basically, what you want to do is call getData on the parent table and setData on the child table.
const crewLeaderTable = Tabulator.prototype.findTable('#CrewLeaderTable')[0];
const crewMemberTable = Tabulator.prototype.findTable('#CrewMember1Table')[0];
const crewLeaderData = crewLeaderTable.getData();
// You could also use replaceData or addData, depending on the requirements
crewMemberTable.setData(crewLeaderData);

How to expand Antd table row by click a button

Version
3.0.3
Environment
pc, chrome
Reproduction link
https://codesandbox.io/s/my02ok19wy
Steps to reproduce
now, Table can expand row by two ways:
use icon in the first column
click the whole row with expandRowByClick as true.
But those are not what I want. I want to use the button in some other column, maybe the button Show More. Then, when I click Show More, the row will expand. How to realize this?
Like the demo shows, I want to expand the row by click Show More instead of click the button in the first cell. Thanks
What is expected?
expand one row by click one button not in the first cell
What is actually happening?
Must click the button in the first cell of the row. The button can't move to other cell.
It's possible but I prefer not to do the code for you, but I will explain how.
There is a props call expandedRowKeys where you specify keys of rows that you want to expand.
so
adding expandedRowKeys={[1,3]} to <Table /> will expand the first and the third row.
Now, you just need to implement the handleClickMore function to manipulate an array of row keys. and how something like
expandedRowKeys={this.state.expandedKeys}
You can use expandIcon and expandedRowRender for your purpose
This is the modified code:
import React from "react";
import ReactDOM from "react-dom";
import { version, Table, Button } from "antd";
import "antd/dist/antd.css";
const columns = [
{ title: "Name", dataIndex: "name", key: "name" },
{ title: "Age", dataIndex: "age", key: "age" },
{ title: "Address", dataIndex: "address", key: "address" },
{ title: "Action", dataIndex: "", key: "expand" }
];
const data = [
{
key: 1,
name: "John Brown",
age: 32,
address: "New York No. 1 Lake Park",
description:
"My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park."
},
{
key: 2,
name: "Jim Green",
age: 42,
address: "London No. 1 Lake Park",
description:
"My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park."
},
{
key: 3,
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park",
description:
"My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park."
}
];
ReactDOM.render(
<div style={{ margin: 24 }}>
<p style={{ marginBottom: 24 }}>
Current antd version: {version} <br />
You can change antd version on the left panel (Dependencies section).
</p>
<Table
// expandIconColumnIndex={3}
columns={columns}
expandedRowRender={(record) => (
<p style={{ margin: 0 }}>{record.description}</p>
)}
dataSource={data}
expandIcon={({ expanded, onExpand, record }) =>
expanded ? (
<Button
onClick={(e) => onExpand(record, e)}
>
Collapse
</Button>
) : (
<Button onClick={(e) => onExpand(record, e)}>Expand</Button>
)
}
/>
</div>,
document.getElementById("root")
);

Resources