Reputation: 3
I'm new with React and TypeScript. I want to add a new row in a table when someone clicks a button (FontAwesomeIcon). I actually don't even know where to start.
Here's my code
import React from "react";
import './SchemeFillData.scss';
import {faPlus} from "@fortawesome/free-solid-svg-icons/faPlus";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
export function SchemeFillData() {
return <div className='schemedata'>
<table className='schemedata__attr'>
<thead>
<th className='schemedata__attr__title' colSpan={2}>
Atrybuty
<FontAwesomeIcon className='schemedata__add' icon={faPlus} size='lg' color='lightgray'/>
</th>
</thead>
<tbody>
<tr>
<td className='scheme__attr__cell'>
<input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text'
id='unit'/>
</td>
<td className='scheme__attr__cell'>
<select id="defVat" className='schemedata__select attr__select'>
<option value="" disabled selected>Wybierz kolumnę</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>;
}
What do I need to do? Where to start? Thanks for the answers :)
Upvotes: 0
Views: 2203
Reputation: 180
using typescript, you can do it like this :
I made a codesandbox demo if you want to check
import React, { useState }from "react";
import "./styles.css";
// this type describe how the data of each rows should be shaped
type RowData = {
message: string;
}
// here we define an inteface to describe the shape of our component state
// this is an object with a key 'rows' who contains an array of RowData
interface IState {
rows: RowData[];
}
export default function App() {
// here we are controlling the parameters of useState function with our IState interface
const [state, setState] = useState<IState>({rows: []});
const addRow = () => {
setState({
rows: [...state.rows, { message: "my new element" }]
})
}
const { rows } = state;
return (
<div className='schemedata'>
<table className='schemedata__attr'>
<thead>
<th className='schemedata__attr__title' colSpan={2}>
Atrybuty
<button onClick={addRow}>Add row</button>
</th>
</thead>
<tbody>
{ rows.map(element => (
<tr>
<td className='scheme__attr__cell'>
<input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text' id='unit'/>
</td>
<td className='scheme__attr__cell'>
<select id="defVat" className='schemedata__select attr__select'>
<option value="" disabled selected>{element.message}</option>
</select>
</td>
</tr>
))
}
</tbody>
</table>
</div>
);
}
enter code here
Upvotes: 0
Reputation: 2282
You can try something like this maybe :
import React, { useState } from "react";
import './SchemeFillData.scss';
import {faPlus} from "@fortawesome/free-solid-svg-icons/faPlus";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
export function SchemeFillData() {
const [array, setArray] = useState([]);
function addNewRow() {
setArray([...array, {}]);
}
return <div className='schemedata'>
<table className='schemedata__attr'>
<thead>
<th className='schemedata__attr__title' colSpan={2}>
Atrybuty
<FontAwesomeIcon className='schemedata__add' icon={faPlus} size='lg' color='lightgray' onClick={addNewRow} />
</th>
</thead>
<tbody>
<tr>
<td className='scheme__attr__cell'>
<input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text'
id='unit'/>
</td>
<td className='scheme__attr__cell'>
<select id="defVat" className='schemedata__select attr__select'>
<option value="" disabled selected>Wybierz kolumnę</option>
</select>
</td>
</tr>
{array && array.map((_, index) => (
<tr key={index}> <td className='scheme__attr__cell'> <input className='schemedata__input attr__input' placeholder='Nazwa atrybutu' type='text' id='unit'/> </td> <td className='scheme__attr__cell'> <select id="defVat" className='schemedata__select attr__select'> <option value="" disabled selected>Wybierz kolumnę</option> </select> </td> </tr>
)}
</tbody>
</table>
</div>;
}
Upvotes: 1
Reputation: 115
Ok, you should read the react documentation to know how this frameworks work, but essentially, you need to render your "table-rows" from a state variable. So to make it simple to understand, lets say you have a variable rows=[]. You need to make a function that adds something to that row :
const addRow = (someText) => {
this.rows.push({content: someText}
}
And you should call that function whenever someone clicks on your button. That will add a new object in your array. And if you have your rows mapped to that variable it should work as a basic version:
<tbody>
{this.state.rows.map(( obj, index ) => {
return (
<tr key={index}>
<td>{obj.content}</td>
</tr>
);
})}
</tbody>
Upvotes: 0