import { useEffect, useState } from 'react';
interface TestInterface {
id: number;
field1: string;
field2: string;
}
let defs = [
{key:'-', value:'-'}, {key:'001', value:'A'},
{key:'002', value:'B'}, {key:'003', value:'C'},
{key:'004', value:'D'}, {key:'005', value:'E'},
{key:'006', value:'F'}, {key:'007', value:'G'}
];
let columns = new Map();
columns.set('001', ['dataA-1', 'dataA-2', 'dataA-3']);
columns.set('002', ['dataB-1', 'dataB-2', 'dataB-3']);
columns.set('003', ['dataC-1', 'dataC-2', 'dataC-3']);
columns.set('004', ['dataD-1', 'dataD-2', 'dataD-3']);
columns.set('005', ['dataE-1', 'dataE-2', 'dataE-3']);
columns.set('006', ['dataF-1', 'dataF-2', 'dataF-3']);
columns.set('007', ['dataG-1', 'dataG-2', 'dataG-3']);
const CustomTable = () => {
const [users, setUsers] = useState<TestInterface[]>([]);
const[count, setCount] = useState<number>(1);
useEffect(() => {
}, [users]);
const addRow = () => {
const user : TestInterface = { id: count, field1: '-', field2: '-' };
setCount(count+1);
setUsers([...users, user]);
}
const deleteRow = (i : number) => {
setUsers(users.filter((user) => (user.id !== i)));
}
const upRow = (id: number, index:number) => {
if (index === 0 || users.length < 2) {
return;
}
for (let j = 1; j < users.length; j++) {
const user2 : TestInterface = users[j];
if (user2.id === id) {
setUsers((prevState) => {
// オブジェクトをコピーしないと再描画されない。
let tempUsers : TestInterface[] = [...prevState];
const moving = tempUsers.splice(j, 1)[0];
tempUsers.splice(j - 1, 0, moving);
return tempUsers;
});
break;
}
}
}
const downRow = (id: number, index:number) => {
if (index === users.length -1 || users.length < 2) {
return;
}
for (let j = 0; j < users.length-1; j++) {
const user2 : TestInterface = users[j];
if (user2.id === id) {
setUsers((prevState) => {
// オブジェクトをコピーしないと再描画されない。
let tempUsers : TestInterface[] = [...prevState];
const moving = tempUsers.splice(j, 1)[0];
tempUsers.splice(j + 1, 0, moving);
return tempUsers;
});
break;
}
}
}
const onChange1 = (id: number, e: any) => {
setUsers((prevState) => {
// オブジェクトをコピーしないと再描画されない。
let tempUsers : TestInterface[] = [...prevState];
let test1: TestInterface = tempUsers.filter((elem) => elem.id === id)[0];
test1.field1 = e.target.value;
return tempUsers;
});
}
const onChange2 = (id: number, e: any) => {
setUsers((prevState) => {
// オブジェクトをコピーしないと再描画されない。
let tempUsers : TestInterface[] = [...prevState];
let test1: TestInterface = tempUsers.filter((elem) => elem.id === id)[0];
test1.field2 = e.target.value;
return tempUsers;
});
}
const Field2 = (props: any) => {
if (props.user.field1 === '-') {
return (
<select name="field2" onChange={(e) => onChange2(props.user.id, e)} value={props.user.field2}>
<option value="-">-</option>
</select>
);
}
else {
const options: string[] = columns.get(props.user.field1);
return (
<select name="field2" onChange={(e) => onChange2(props.user.id, e)} value={props.user.field2}>
{options.map((value: string, index: number) => (
<option value={value} key={index}>{value}</option>
))}
</select>
);
}
}
const setData = (e: any) => {
if (e.target.value === '1') {
const _users : TestInterface[] = [
{ id: 1, field1: '001', field2: 'dataA-1' },
{ id: 2, field1: '-', field2: '-' },
{ id: 3, field1: '002', field2: 'dataB-1' },
];
setCount(_users.length + 1);
setUsers(_users);
}
else if (e.target.value === '2') {
const _users : TestInterface[] = [
{ id: 1, field1: '003', field2: 'dataC-1' },
{ id: 2, field1: '-', field2: '-' },
{ id: 3, field1: '004', field2: 'dataD-1' },
{ id: 4, field1: '005', field2: 'dataE-3' },
];
setCount(_users.length + 1);
setUsers(_users);
}
else if (e.target.value === '3') {
const _users : TestInterface[] = [
{ id: 1, field1: '003', field2: 'dataC-1' },
{ id: 2, field1: '-', field2: '-' },
{ id: 3, field1: '004', field2: 'dataD-1' },
{ id: 4, field1: '004', field2: 'dataD-2' },
{ id: 5, field1: '005', field2: 'dataE-3' },
];
setCount(_users.length + 1);
setUsers(_users);
}
}
return (
<div>
データのロード
<select onClick={(e) => setData(e)}>
<option value="-">-</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<table>
<thead>
<tr>
<th>ID</th>
<th>フィールド1</th>
<th>フィールド2</th>
<th></th>
</tr>
</thead>
<tbody>
{users.map((user: TestInterface, index: number) => (
<tr
key={user.id}
>
<td>{user.id}</td>
<td>
<select name="field1" onChange={(e) => onChange1(user.id, e)} value={user.field1}>
{defs.map((item: any, index: number) => (
<option value={item.key} key={index}>{item.value}</option>
))}
</select>
</td>
<td>
<Field2 user={user} />
</td>
<td>
<button onClick={() => upRow(user.id, index)}>上へ</button>
<button onClick={() => downRow(user.id, index)}>下へ</button>
<button onClick={() => deleteRow(user.id)}>削除</button>
</td>
</tr>
))}
</tbody>
</table>
<button onClick={() => addRow()}>追加</button>
</div>
);
};
export default CustomTable;