I'm trying to make a little D&D initiative tracker. I'm trying to modify a form to take multiple inputs and generate a dynamic table.
My current issue is that when I submit the form, a 4x4 table is created with each input displaying across each column of a row instead of one row with one input per column. I'm still a little fuzzy on props so I'm not sure if that's where my disconnect is or somewhere else.
Code is based on this.
This is DynamicTable.jsx;
import React from 'react';
export default class DynamicTable extends React.Component {
constructor(props) {
super(props);
this.state = {
initiative: "",
name: "",
armorClass: "",
hitPoints: "",
combatants: []
}
}
updateInitiative(event) {
this.setState({initiative: event.target.value});
}
updateName(event) {
this.setState({name: event.target.value});
}
updateArmorClass(event) {
this.setState({armorClass: event.target.value});
}
updateHitPoints(event) {
this.setState({hitPoints: event.target.value});
}
handleClick() {
var combatants = this.state.combatants;
combatants.push(this.state.initiative);
combatants.push(this.state.name);
combatants.push(this.state.armorClass);
combatants.push(this.state.hitPoints);
this.setState({
combatants: combatants,
initiative: "",
name: "",
armorClass: "",
hitPoints: ""
});
}
handleCombatantChanged(i, event) {
var combatants = this.state.combatants;
combatants[i] = event.target.value;
this.setState({
combatants: combatants
});
}
handleCombatantDeleted(i) {
var combatants = this.state.combatants;
combatants.splice(i, 1);
this.setState({
combatants: combatants
});
}
renderRows() {
var context = this;
return this.state.combatants.map(function(o, i) {
return (
<tr key={"combatant-" + i}>
<td>
<input
id="initiative"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="name"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="armorClass"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<input
id="hitPoints"
type="text"
value={o}
onChange={context.handleCombatantChanged.bind(context, i)}
/>
</td>
<td>
<button onClick={context.handleCombatantDeleted.bind(context, i)}>
Finish him!
</button>
</td>
</tr>
);
});
}
render() {
return (
<div>
<table>
<td>
<th>Initiative</th>
<input
id="initiative"
type="text"
value={this.state.initiative}
onChange={this.updateInitiative.bind(this)}
/>
</td>
<td>
<th>Name</th>
<input
id="name"
type="text"
value={this.state.name}
onChange={this.updateName.bind(this)}
/>
</td>
<td>
<th>Armor Class</th>
<input
id="armorClass"
type="text"
value={this.state.armorClass}
onChange={this.updateArmorClass.bind(this)}
/>
</td>
<td>
<th>Hit Points</th>
<input
id="hitPoints"
type="text"
value={this.state.hitPoints}
onChange={this.updateHitPoints.bind(this)}
/>
</td>
<td><th></th>
<button onClick={this.handleClick.bind(this)}>
Add Combatant
</button>
</td>
</table>
<table className="">
<thead>
<tr>
<th>Initiative</th>
<th>Name</th>
<th>Armor Class</th>
<th>Hit Points</th>
<th>Kill?</th>
</tr>
</thead>
<tbody>
{this.renderRows()}
</tbody>
</table>
</div>
);
}
}
This is App.js;
import DynamicTable from './DynamicTable';
function App() {
return (
<div className="App">
<DynamicTable />
</div>
);
}
export default App;