I tried to solve this js react problem and get stuck on questions 2-4. Question 2: I don't know how to check the local state for each row in order to check for the duplicate rank select Question 3: Should I need props passed to the component to check for unique? Question 4: How do I check all rows have a select ranked and unique?
Here are the questions:
Adding a class of "done" to a row will highlight it green. Provide this visual feedback on rows which have a selected rank.
Adding a class of "error" to a row will highlight it red. Provide this visual feedback on rows which have duplicate ranks selected.
There is a place to display an error message near the submit button. Show this error message:
Ranks must be uniquewhenever the user has selected the same rank on multiple rows.The submit button is disabled by default. Enable it when all rows have a rank selected and all selected ranks are unique.
The orginal App.js
import React, { Component } from 'react';
import './App.css';
import MainPage from './components/MainPage';
class App extends Component {
render() {
return (
<MainPage />
);
}
}
export default App;
MainPage.js
import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
return new Animal(name);
}),
error: ''
};
}
render() {
const rows = this.state.animals.map((animal) => {
return (
<FormRow
animalName={animal.name}
key={animal.name}
/>
);
});
const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);
return (
<div>
<table>
<thead>
<tr>
<th></th>
{headers}
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
<div>{this.state.error}</div>
<input type="submit" />
</div>
);
}
}
export default MainPage;
FormRow.jsx
import React from 'react';
import _ from 'lodash';
class FormRow extends React.Component {
render() {
const cells = _.range(1, 6).map((i) => {
return (
<td key={`${this.props.animalName}-${i}`}>
<input
type="radio"
name={this.props.animalName}
value={i}
/>
</td>
);
});
return (
<tr>
<th>{this.props.animalName}</th>
{cells}
</tr>
)
}
}
export default FormRow;
Animal.js
class Animal {
constructor(name, rank) {
this.name = name;
this.rank = rank;
}
}
export default Animal;
My code is at GitHub (git@github.com:HuydDo/js_react_problem-.git). Thanks for your suggestion!
FormRow.jsx
import React from 'react';
import _ from 'lodash';
class FormRow extends React.Component {
constructor(){
super();
this.state = {
rowColor : false,
name: "",
rank: 0
// panda: 0,
// cat: 0,
// capybara: 0,
// iguana: 0,
// muskrat: 0
}
}
handleChange = (e) => {
if (this.state.rank === e.target.value){
console.log("can't select same rank.")
}
console.log(e.target.name)
console.log(e.target.value)
this.setState({
// [e.target.name]: e.target.value,
name: e.target.name,
rank: e.target.value,
rowColor: true
}, console.log(this.state))
}
handleChange2 = (e) => {
let newName = e.target.name
let newRank = e.target.value
let cRank = this.state.rank
let cName = this.state.name
console.log(this.state)
console.log(`${newRank} ${newName}`)
if(cName !== newName) {
if(cRank !== newRank) {
this.setState({
name : newName,
rank: newRank,
rowColor: true
},()=> console.log(this.state))
}
else {
console.log("can't select same rank")
}
}
// this.setState(previousState => {
// let cRank = previousState.rank
// let cName = previousState.name
// console.log(previousState)
// return {
// rank: newRank,
// name: newName,
// rowColor: true
// }
// },console.log(this.state.rank))
}
render() {
const cells = _.range(1, 6).map((i) => {
return (
<td key={`${this.props.animalName}-${i}`} onChange={this.handleChange2}>
<input
type="radio"
name={this.props.animalName}
value={i}
/>
</td>
);
});
return (
<tr className = {(this.state.rowColor) ? 'done':null} >
{/* <tr> */}
<th>{this.props.animalName}</th>
{cells}
</tr>
)
}
}
export default FormRow;
MainPage.jsx
import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
return new Animal(name);
}),
error: ''
};
}
getValue = ({name,rank}) =>{
console.log(`Name: ${name} rank: ${rank}`)
}
// handleSubmit = event => {
// event.preventDefault()
// this.props.getValue(this.state)
// }
checkForUnique = () => {
// Show this error message: `Ranks must be unique` whenever the user has selected the
// same rank on multiple rows.
this.setState({
error : "Ranks must be unique"
})
}
isDisabled = () =>{
// The submit button is disabled by default. Enable it when all rows have a
// rank selected and all selected ranks are unique.
return true
}
render() {
const rows = this.state.animals.map((animal) => {
return (
<FormRow
animalName={animal.name}
key={animal.name}
rank={animal.rank}
handleChange={this.handleChange}
getValue={this.getValue}
/>
);
});
const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);
return (
<div>
{/* <form onSubmit={this.onSubmit}> */}
<table>
<thead>
<tr>
<th></th>
{headers}
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
<div>{this.state.error}</div>
<input type="submit" value="Submit" disabled={this.isDisabled()} /> {/* <button type="submit">Submit</button> */}
{/* </form> */}
</div>
);
}
}
export default MainPage;
I tried to add handleChange and handleAnimalSelect methods, but I get an error. The new name and rank are not added to the arrays.
MainPage.jsx
import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
return new Animal(name);
}),
error: ''
};
}
isDisabled = () =>{
// The submit button is disabled by default. Enable it when all rows have a
// rank selected and all selected ranks are unique.
return true
}
render() {
const rows = this.state.animals.map((animal) => {
return (
<FormRow
animalName={animal.name}
key={animal.name}
rank={animal.rank}
getValue={this.getValue}
handleAnimalSelect={this.handleAnimalSelect}
/>
);
});
const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);
return (
<div>
{/* <form onSubmit={this.onSubmit}> */}
<table>
<thead>
<tr>
<th></th>
{headers}
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
<div>{this.state.error}</div>
<input type="submit" value="Submit" disabled={this.isDisabled()} />
{/* <button type="submit">Submit</button> */}
{/* </form> */}
</div>
);
}
}
export default MainPage;
FormRow.jsx
import React from 'react';
import _ from 'lodash';
import FormRow from './FormRow.jsx';
import Animal from './Animal.js';
class MainPage extends React.Component {
constructor(props) {
super(props);
this.state = {
animals: ['panda','cat','capybara','iguana','muskrat'].map((name) => {
return new Animal(name);
}),
error: ''
};
}
isDisabled = () =>{
// The submit button is disabled by default. Enable it when all rows have a
// rank selected and all selected ranks are unique.
return true
}
render() {
const rows = this.state.animals.map((animal) => {
return (
<FormRow
animalName={animal.name}
key={animal.name}
rank={animal.rank}
getValue={this.getValue}
handleAnimalSelect={this.handleAnimalSelect}
/>
);
});
const headers = _.range(1, 6).map((i) => <th key={`header-${i}`}>{i}</th>);
return (
<div>
{/* <form onSubmit={this.onSubmit}> */}
<table>
<thead>
<tr>
<th></th>
{headers}
</tr>
</thead>
<tbody>
{rows}
</tbody>
</table>
<div>{this.state.error}</div>
<input type="submit" value="Submit" disabled={this.isDisabled()} />
{/* <button type="submit">Submit</button> */}
{/* </form> */}
</div>
);
}
}
export default MainPage;
