I create a todo list system and I use a map to make a loop for all the items I have. But items are stuck for me in the same row in the table. This is a system I used to build in js vanila and now for practice I run it in react.
I would be happy for a solution. In js vanila I would use insertAdjacentHTML But I'm looking for the solution in react
demo for the app: https://v1-todolist.netlify.app
My Problem All items in one row.
I need not all items to be on the same line I need it to be dropped line like here Example of how the item should look properly. This system I built it in js vanila
if i add Div it not work It does not sit well in the table and I also get a validateDOMNesting (...) error: cannot appear as a child of .
my code App.js
import { useState } from "react";
import "./App.css";
import Form from "./Form";
import Alert from "./Alert";
function App() {
const [nameTask, setNameTask] = useState("");
const [priority, setPriority] = useState("Low");
const [list, setList] = useState([]);
const [alert, setAlert] = useState({ show: false, type: "", msg: "" });
const handlerSubmit = function (e) {
e.preventDefault();
if (!nameTask) return showAlert(true, "danger", "you cannot input empty");
const newList = {
id: new Date().getTime().toString(),
title: nameTask,
priority: priority,
};
setList([...list, newList]);
};
const showAlert = function (show = false, type, msg) {
setAlert({ show, type, msg });
};
return (
<article className="vh-100 gradient-custom-2">
{alert.show && <Alert {...alert} showAlert={showAlert} />}
<Form
list={list}
setNameTask={setNameTask}
setPriority={setPriority}
handlerSubmit={handlerSubmit}
/>
</article>
);
}
export default App;
Form.js
import React from "react";
const Form = function ({ handlerSubmit, setNameTask, setPriority, list }) {
return (
<div className="container py-5 h-100">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-md-12 col-xl-10">
<div className="card mask-custom">
<div className="card-body p-4 text-white">
<div className="text-center pt-3 pb-2">
<img
src="https://mdbootstrap.com/img/Photos/new-templates/bootstrap-todo-list/check1.png"
alt="Check"
width="60"
/>
<h2 className="my-4">Task List</h2>
</div>
<form className="form-task" onSubmit={(e) => handlerSubmit(e)}>
<div className="col-auto">
<input
name="name-task"
type="text"
className="form-control task-input"
id="autoSizingInput"
placeholder="Add Task"
onChange={(e) => setNameTask(e.target.value)}
/>
</div>
<select
className="form-select"
aria-label="Default select example"
onChange={(e) => setPriority(e.target.value)}
>
<option value="Low">Low</option>
<option value="Normal">Normal</option>
<option value="High">High</option>
</select>
<button type="submit" className="btn btn-primary">
submit
</button>
</form>
<table className="table text-white mb-0">
<thead>
<tr>
<th scope="col">Task</th>
<th scope="col">Priority</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
<tr className="fw-normal">
{list.map((item, index) => {
return (
<React.Fragment key={index}>
<th>
<span className="ms-2" data-name={`${item.title}`}>
{item.title}
</span>
</th>
<td className="align-middle priority-class">
<span className="badge ${value.color}">
{item.priority}
</span>
</td>
<td className="align-middle">
<h6 className="mb-0" data-id="${value.id}">
<a className="remove-link" href="#">
<span className="badge bg-gradient remove">
❌
</span>
</a>
<a className="complete-link" href="#">
<span className="badge bg-gradient complete">
✔
</span>
</a>
</h6>
</td>
</React.Fragment>
);
})}
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
);
};
export default Form;
CodePudding user response:
Check this CodeSandbox
I was able to solve your issu just by adding a flex propriety to the panel that contain your list and by changing React.fragment
by a div
.
However it would perhaps be better to swap the node with the class fw-normal
to a div
and change the React.fragment
to the node tr
.