Adjacent Jsx elements must be wrapped in an e - reactjs

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>
);

Related

How to drag and drop HTML table rows between two tables using ReactJS

There are two table components in the code with same number of columns. Need to move row from One table to Another table using Drag and Drop.
Example:
Table 1:
<table className='table1'>
<thead>
<tr><th>Col 1</th><th>Col 2</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>2</td></tr>
<tr><th>Col 2</th><th>Col 2</th></tr>
<tr><th>Col 3</th><th>Col 2</th></tr>
</tbody>
</table>
Table 2:
<table className='table2'>
<thead>
<tr><th>Col 1</th><th>Col 2</th></tr>
</thead>
<tbody>
<tr><td>2</td><td>23/td></tr>
<tr><th>Col 4</th><th>Col 23</th></tr>
<tr><th>Col 5</th><th>Col 32</th></tr>
</tbody>
</table>
Table 1 and Table 2 need to be drag and droppable. Can anyone help regarding this?
Here is the code, I'm trying to fetch some data from JSON file. Tables are filled by the data, I can drag within the tables, when I drag and drop to another table, I can't move the row to another table, but both are Drag and Droppable. There are no errors shown, when doing drag and drop.
import "./styles.css";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import "bootstrap/dist/css/bootstrap.min.css";
import userdata from "./tempData.json";
import user2data from "./tempData_2.json";
import { useState } from "react";
export default function App() {
const [users, setUsers] = useState(userdata.data);
const [userrs, setUserrs] = useState(user2data.data);
const handleDragEnd = (e) => {
if (!e.destination) return;
let tempData = Array.from(users);
let [source_data] = tempData.splice(e.source.index, 1);
tempData.splice(e.destination.index, 0, source_data);
setUsers(tempData);
};
const handleDraggEnd = (e) => {
if (!e.destinationn) return;
let temppData = Array.from(userrs);
let [sourcee_data] = temppData.splice(e.source.index, 1);
temppData.splice(e.destinationn.index, 0, sourcee_data);
setUserrs(temppData);
};
return (
<div className="App mt-4">
<DragDropContext onDragEnd={handleDragEnd}>
<table className="table borderd">
<thead>
<tr>
<th />
<th>Username</th>
<th>Age</th>
<th>Gender</th>
</tr>
</thead>
<Droppable droppableId="droppable-2">
{(provider) => (
<tbody
className="text-capitalize"
ref={provider.innerRef}
{...provider.droppableProps}
>
{users?.map((user, index) => (
<Draggable
key={user.name}
draggableId={user.name}
index={index}
>
{(provider) => (
<tr {...provider.draggableProps} ref={provider.innerRef}>
<td {...provider.dragHandleProps}> = </td>
<td>{user.name}</td>
<td>{user.age}</td>
<td>{user.gender}</td>
</tr>
)}
</Draggable>
))}
{provider.placeholder}
</tbody>
)}
</Droppable>
</table>
</DragDropContext>
<DragDropContext onDragEnd={handleDraggEnd}>
<table className="table borderd">
<thead>
<tr>
<th />
<th>Username</th>
<th>Age</th>
<th>Gender</th>
</tr>
</thead>
<Droppable droppableId="droppable-1">
{(provider) => (
<tbody
className="text-capitalize"
ref={provider.innerRef}
{...provider.droppableProps}
>
{userrs.map((user, index) => (
<Draggable
key={user.name}
draggableId={user.name}
index={index}
>
{(provider) => (
<tr {...provider.draggableProps} ref={provider.innerRef}>
<td {...provider.dragHandleProps}> = </td>
<td>{user.name}</td>
<td>{user.age}</td>
<td>{user.gender}</td>
</tr>
)}
</Draggable>
))}
{provider.placeholder}
</tbody>
)}
</Droppable>
</table>
</DragDropContext>
</div>
);
}

values.map is not a function n reactjs while passing array in state and mapping the current state

I have passed an array of objects in useState hook as the initial state and i want to iterate over it using map method in other component, i have passed the current state as prop in the other object and have used map method over it but console message still shows values.map is not a function, i know we can only use map method on array i have done that only still the error shows.
created state and passed an array of objects-
const [values, setValues] = useState([
{
name: "Vansh",
age: 22,
email: "vansh#gmail.com",
},
]);
Passed values as props in Home component-
<Home
addFormData={addFormData}
setAddFormData={setAddFormData}
values={values}
setValues={setValues}
/>
Code of my home component-
const Home = ({ values }) => { return (
<div>
<table>
<thead>
<tr>
<th>name</th>
<th>age</th>
<th>email</th>
</tr>
</thead>
<tbody>
{values.map((val, index) => (
<tr>
<td key={val.index}>{val.name}</td>
<td key={val.index}>{val.age}</td>
<td key={val.index}>{val.email}</td>
</tr>
))}
</tbody>
</table>
<Link to="/form">
<button>FORM</button>
</Link>
</div> ); };
Please see the code it's working fine export below your missing export.
const Home = ({ values }) => {
// console.log(values);
return (
<div>
<table>
<thead>
<tr>
<th>name</th>
<th>age</th>
<th>email</th>
</tr>
</thead>
<tbody>
{values.map((val, index) => (
<tr>
<td key={val.index}>{val.name}</td>
<td key={val.index}>{val.age}</td>
<td key={val.index}>{val.email}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Home;
Please see the code SandBoxLink

Problem in implementing two search filters in react table

I am implementing a table in react and I want to search data in tables based on two factors, i.e., Filter-By-Name and Filter-By-Consultant. You can see the expected output here
Now the problem is that I have implemented Search-By-Name successfully and it works fine. Now I coded the Search-By-consultant but I don't know how to call it in the table body along with Search-By-Name.
Here is my Bookings.js. I Know I have to call FilteredConsultants in the table body along with FilteredNames but how to do that?
import React, {useState, useEffect} from 'react';
import axios from 'axios';
import {Link} from 'react-router-dom';
import '../../static/Bookings.css';
import {BsFilterRight} from "react-icons/bs";
const Bookings= ()=>{
const[Bookings, setBooking]=useState([]);
const[searchByName, setSearchByName]=useState('');
const[FilteredNames, setFilteredNames]=useState([]);
const[searchByConsultant, setSearchByConsultant]=useState('');
const[FilteredConsultants, setFilteredConsultants]=useState([]);
useEffect(()=>{
loadUsers();
}, []);
useEffect(()=>{
setFilteredNames(
Bookings.filter(Booking=>{
return Booking.name.toLowerCase().includes(searchByName.toLowerCase())
})
)
}, [searchByName, Bookings]);
useEffect(()=>{
setFilteredConsultants(
Bookings.filter(Booking=>{
return Booking.consultant.toLowerCase().includes(searchByConsultant.toLowerCase())
})
)
}, [searchByConsultant, Bookings]);
const loadUsers= async()=>{
const result =await axios.get("http://localhost:3001/Bookings");
setBooking(result.data.reverse());
};
const deleteUser=async id => {
await axios.delete(`http://localhost:3001/Bookings/${id}`);
loadUsers();
}
return(
<div className="Booking-page-container">
<h2 className="text-center mb-4">Bookings Page</h2>
<table class="table table-bordered table-striped border shadow">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">
<BsFilterRight/>
<input
placeholder="search by name..."
onChange={e=>setSearchByName(e.target.value)}
/>
</th>
<th scope="col">
<BsFilterRight/>
<input
placeholder="search by consultant..."
onChange={e=>setSearchByConsultant(e.target.value)}
/>
</th>
<th scope="col">Email</th>
<th>Action</th>
</tr>
</thead>
<thead class="thead-dark">
<tr>
<th scope="col"></th>
<th scope="col">Name</th>
<th scope="col">Consultant</th>
<th scope="col">Email</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{FilteredNames.map((Booking,index)=>(
<tr>
<th scope="row">{index+1}</th>
<td>{Booking.name}</td>
<td>{Booking.consultant}</td>
<td>{Booking.email}</td>
<td>
<Link class="btn btn-primary mr-2" to={`/Bookings/view/${Booking.id}`}>View</Link>
<Link class="btn btn-outline-primary mr-2" to={`/Bookings/edit/${Booking.id}`}>Edit</Link>
<Link class="btn btn-danger" onClick={()=>deleteUser(Booking.id)}>Delete</Link>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default Bookings;
Right now, once searchByConsultant or searchByName is changed Table is displaying Bookings filtered by only one of the values.
It you would like to filter with 'and' condition, then you would need to construct filter using both of values.
useEffect(()=>{
setFilteredNames(
Bookings.filter(Booking=> {
const byName = !searchByName || Booking.name.toLowerCase().includes(searchByName.toLowerCase());
const byConsultant = !searchByConsultant || Booking.consultant.toLowerCase().includes(searchByConsultant.toLowerCase());
return byName && byConsultant;
})
)
}, [searchByName, searchByConsultant, Bookings]);
+ FilteredConsultants seems that isn't really used here

Show value at the alert msg by selecting cell

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

Display no results when table empty in React

I have a table of rows that display contact information. I'd like to have it render a messasge of "No contacts" when the listItems array is 0. I tried creating a const noEntries variable and setting it with the array to 0, and using {noEntries No entries}, but this is throwing an error.
class ContactList extends Component {
constructor(props) {
super(props);
this.createContact = this.createContact.bind(this);
}
delete(key) {
this.props.delete(key);
}
createContact(item) {
return <tr key={item.key}>
<td>{item.firstname}</td>
<td>{item.lastname}</td>
<td>{item.phone}</td>
<td><i className="fas fa-trash-alt" onClick={() => { if (window.confirm('Are you sure you want to delete ' + item.firstname + ' ' + item.lastname + ' from your contacts?')) this.delete(item.key)}}></i></td>
</tr>
}
render() {
const contactEntries = this.props.entries;
const listItems = contactEntries.map(this.createContact);
return (
<table className="mui-table mui-table--bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
{listItems}
</tbody>
</table>
);
}
};
export default ContactList;
in your render() do like this:
render() {
const contactEntries = this.props.entries;
const listItems = contactEntries.map(this.createContact);
return (
contactEntries.length > 0?
<table className="mui-table mui-table--bordered">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody>
{listItems}
</tbody>
</table>:<span>No results</span>
);
}
check the number of records in contactEntries using ternary operator if length ==0 then return no data component else return rows
const listItems = contactEntries && contactEntries.length >0
? contactEntries.map(this.createContact)
: <tr key={item.key}>
<td rowspan="3">No data</td
</tr>

Resources