Show value at the alert msg by selecting cell - reactjs

Goal:
When you press one of the cell (only for column country) containing the name of a country, a alert message with the name of the country should be displayed.
Problem:
What part am I missing in the source code.
Do not know what syntax code is needed in order to achieve the goal.
Any advice?
Info:
I'm newbie in reacjt.
Stackblitz:
https://stackblitz.com/edit/react-faabjl
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
sayHello() {
alert('');
}
render() {
return (
<div>
<Hello name={this.state.name} />
<table border="1">
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td onClick={this.sayHello}>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td onClick={this.sayHello}>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td onClick={this.sayHello}>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td onClick={this.sayHello}>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td onClick={this.sayHello}>Italy</td>
</tr>
</tbody>
</table>
</div>
);
}
}
render(<App />, document.getElementById('root'));

Your sayhello function by default contains the event object. By that you can extract the name of the country needs to be displayed.I have rewritten your code.However for large set of table data you need to use a map function to iterate over the whole array of objects and display the result.
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
sayHello(e) {
alert(e.target.innerHTML);
}
render() {
return (
<div>
<Hello name={this.state.name} />
<table border="1">
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td onClick={this.sayHello}>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td onClick={this.sayHello}>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td onClick={this.sayHello}>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td onClick={this.sayHello}>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td onClick={this.sayHello}>Italy</td>
</tr>
</tbody>
</table>
</div>
);
}
}
render(<App />, document.getElementById('root'));
You can use a map function like this.
let array = [{company:'Alfreds Futterkiste',contact:'Maria Anders',Country:'Germany'},{company:'centro',contact:'Franciso',country:'Mexico'}]
Now you can iterate over the array with map function.
array.map(element=>{
return <tr key={element.company}>
<td>{element.company}</td>
<td>{element.contact}</td>
<td onClick={this.sayhello}>{element.country}</td>
</tr>
}

I think this is what you want, for Hello component to work you need to update your state to be able to update its value, and to do so you have to bind your event listener to your class component like this:
this.sayHello = this.sayHello.bind(this);
The following is the full code snippet:
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
this.sayHello = this.sayHello.bind(this);
}
sayHello(e) {
this.setState({
name: e.target.textContent
});
alert(e.target.textContent);
}
render() {
return (
<div>
<Hello name={this.state.name} />
<table border="1">
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td onClick={this.sayHello}>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td onClick={this.sayHello}>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td onClick={this.sayHello}>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td onClick={this.sayHello}>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td onClick={this.sayHello}>Italy</td>
</tr>
</tbody>
</table>
</div>
);
}
}
render(<App />, document.getElementById('root'));
you can just treat sayHello() like a normal event in javascript
https://stackblitz.com/edit/react-3zzcoe?file=index.js

Related

Getting error 'TableData' is not defined react/jsx-no-undef in react js

I am new in react js, i have 2 files, App.js and Table.js, I have included Table.js file in App.js and when i used <TableData />, it gives me error, Line 12: 'TableData' is not defined react/jsx-no-undef, here i have added my whole code for that, can anyone please help me why it is giving me that error,
App.js :
import React, { Component } from 'react';
import './App.css';
import { Button, Table } from 'react-bootstrap';
import './Table.js';
class App extends Component {
render() {
return (
<div className="App">
<p>Edit <code>src/App.js</code> and save to reload.</p>
<Button variant="primary">Primary</Button>
<TableData />
</div>
);
}
}
export default App;
Table.js
import React, { Component } from 'react';
import { Button, Table } from 'react-bootstrap';
import './App.css';
class TableData extends Component {
render() {
return (
<Table striped bordered hover>
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<td>3</td>
<td colSpan="2">Larry the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</Table>
);
}
}
export default TableData;
You need to define TableData when importing.
import TableData from './Table.js'

Why Is My React Bootstrap CSS Not Working?

I literally threw away all my code just to isolate the issue and fix it, but it didnt work and the css is not showing
(main file)
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))
App.js
import Table from 'react-bootstrap/Table'
import React, { Component } from 'react'
class App extends Component {
render() {
return (
<Table striped bordered hover>
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<td>3</td>
<td colSpan="2">Larry the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</Table>
)
}
}
export default App
. .
Any help appreciated, i just want to use bootstrap css in my app
my path and folders:
What i did in this same case, is to install normal bootstrap package and import the default styles from your sass file.
#import '../bootstrap/css/bootstrap.min.css';

Getting this warning "Functions are not valid as a React child"

I am trying to render a list of movies from an array object in an html table format. I am getting this warning:
Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it.
import React from 'react';
import {movies} from '../services/fakeMovieService';
class Movies extends React.Component {
constructor(props) {
super(props);
this.tableFormat = this.tableFormat.bind(this);
}
tableFormat() {
movies.map((movie) => {
return (
<tr>
<td key={movie._id}>{movie.title}</td>
</tr>
);
});
}
render() {
return (
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
{this.tableFormat()}
</tbody>
</table>
);
}
}
export default Movies;
You forgot to call your function.
<tbody>
{this.tableformatter()}
</tbody>
But even by doing, I don't think the result is going to be what you expect.
To render an array of elements in React you should use the map function as said in the docs.
The following result would be :
<tbody>
{movies.map(movie =>
<tr key={movie.title}>
<td>{movie.title}</td>
</tr>
)}
</tbody>
EDIT:
I made a typo and put movies instead of movie.
The following code should do everything you are looking for using map and inline conditions:
const movies = [
{
title: "Spooky",
genre: 'eziojgf',
stock: 'nope',
rate: 87
},
{
title: "Sharknado",
genre: 'shitty',
stock: 'yes',
},
{
title: "haha yes"
},
{
title: "uhmmmm",
rate: -5
}
]
class Movies extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
{movies.map(movie =>
<tr key={movie.title}>
{['title', 'genre', 'stock', 'rate'].map(category => <td key={category}>{movie[category]}</td>)}
</tr>
)}
</tbody>
</table>
);
}
}
ReactDOM.render(<Movies />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.5.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.5.1/umd/react-dom.production.min.js"></script>
<div id='root'>
Please execute function as following:
<tbody>
{this.tableformatter()}
</tbody>
here is the right way how to resolve this with React
function TableFormatter ({title /* , and other props genre, rate etc. *//}) {
return (
<tr>
<td>{title}</td>
{/* you may want to add other td here *//}
</tr>
)
}
function Table({movies}) {
render() {
return (
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
{movies.map(movie => <TableFormatter key={movie.id} {...movie} />)}
</tbody>
</table>
);
}
}

Adjacent Jsx elements must be wrapped in an e

i have a very annoying error when trying to display stuff in react table , i would like to make a table and display all values in rows , but for some reason i am getting this error saying Adjacent jsx elemetns must be wrapped in an enclosing element next to the line where im trying to map over results. Any help is greatly appreciated !! thanks!!!
import React from "react";
import "./index.css";
// could also import the sass if you have a loader at dayz/dayz.scss
import moment from 'moment';
import { tasksRef, timeRef } from './firebase';
const defaultColor = "#000";
class Show extends React.Component {
state = {
Events: [],
loading: true
};
render(){
const { Events, Loading } = this.state;
const orderedcars = Events;
let List;
if (Loading) {
List = <div className="TaskList-empty">Loading...</div>;
} else {
List = (
<div>
<table>
<thead>
<tr>
<th scope="row">Event Name</th>
<th scope="row">Event date</th>
<th scope="row">Event timeRef</th>
</tr>
</thead>
<tbody>
{Events.map(car => (
<tr>
<td>{car.name}</td>
<td>{car.timeRef}</td>
<td>{car.description}</td>
</tr>
</tbody>
</table>
))}
</div>
);
}
return(
<div>
{List}
</div>
);
}
}
export default Show;
the problem is that the closing tbody and table atgs should be outside map function as follows
{Events.map(car => (
<tr key={car.name}>
<td>{car.name}</td>
<td>{car.timeRef}</td>
<td>{car.description}</td>
</tr>
))}
You want to place the closing </tbody> and </table> tags outside of the function given to Events.map.
List = (
<div>
<table>
<thead>
<tr>
<th scope="row">Event Name</th>
<th scope="row">Event date</th>
<th scope="row">Event timeRef</th>
</tr>
</thead>
<tbody>
{Events.map(car => (
<tr>
<td>{car.name}</td>
<td>{car.timeRef}</td>
<td>{car.description}</td>
</tr>
))}
</tbody>
</table>
</div>
);

Trying to use react to trigger different components with the same function

I am trying to make a an accordion using React but and I receive my data from a Json API which I dynamically use to make the table. All that works.
However when I try to make the toggleHidden function, it opens every single view instead of the one I just clicked on. How can I target a specific component when clicking instead of just using this
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Asset #</th>
<th>Description</th>
<th>Person</th>
<th>Username</th>
<th>Room</th>
<th>ID</th>
<th>Patches</th>
<th>Date</th>
<th>Java</th>
<th>AACV</th>
</tr>
</thead>
{this.state.items.map((data, key) => {
return (
<tbody>
<tr
id={data.name}
onClick=`{this.toggleHidden.bind(this)}
>`
<td>{data.name}</td>
<td >{data.height}</td>
<td>{data.mass}</td>
<td>{data.gender}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
</tr>
<td
className={data.name}
colSpan="10"
>
{!this.state.isHidden && <Filled/>}
</td>
</tbody>
)
})}
</Table>
toggleHidden (e) {
this.setState({
isHidden: !this.state.isHidden
})
}
I Would suggest you to use the power of components.
Create component for row inside the table, something like this:
export default class Row extends React.Component {
render() {
const { data } = this.props;
<tbody>
<tr
id={data.name}
onClick=`{this.toggleHidden.bind(this)}
>`
<td>{data.name}</td>
<td >{data.height}</td>
<td>{data.mass}</td>
<td>{data.gender}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
<td >{data.birth_year}</td>
<td>{data.eye_color}</td>
</tr>
<td
className={data.name}
colSpan="10"
>
{!this.state.isHidden && <Filled/>}
</td>
</tbody>
}
toggleHidden() {
this.setState(state => ({
isHidden: !state.isHidden
}));
}
}
and in your main component do something like this:
<Table striped bordered condensed hover>
<thead>
<tr>
<th>Asset #</th>
<th>Description</th>
<th>Person</th>
<th>Username</th>
<th>Room</th>
<th>ID</th>
<th>Patches</th>
<th>Date</th>
<th>Java</th>
<th>AACV</th>
</tr>
</thead>
{this.state.items.map((data, key) => <Row data={data} />}
</Table>
it's more readable, it's more react style, and it's let each row to handle their own state
(there might be some syntax error, but the concept is working)
Good Luck!
Well you need to make nested state for each key that means
const { Table, Icon } = semanticUIReact;
const ITEMS = [
{
asset: "Asset 1",
description: "Description"
},
{
asset: "Asset 2",
description: "Description2"
}
];
class Example extends React.Component {
constructor(props) {
super(props);
this.state = { items: ITEMS };
this.renderRow = this.renderRow.bind(this);
}
render() {
return (
<Table striped bordered condensed selectable>
<Table.Header>
<Table.Row>
<Table.HeaderCell>Asset</Table.HeaderCell>
<Table.HeaderCell>Description</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>{this.state.items.map(this.renderRow)}</Table.Body>
</Table>
);
}
renderRow(data, key) {
return (
<Table.Row onClick={() => this.toggleHidden(key)}>
<Table.Cell>{data.asset}</Table.Cell>
<Table.Cell textAlign="right">
{this.state[key] ? "This is hidden" : data.description}
</Table.Cell>
</Table.Row>
);
}
toggleHidden(key) {
this.setState({
[key]: !this.state[key]
});
}
}
ReactDOM.render(<Example />, document.getElementById("react"));
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/semantic-ui-react#0.79.1/dist/umd/semantic-ui-react.min.js"></script>
<div id="react"></div>

Resources