How to bind height in RectJS - html

I want to bind height of two blocks;
const [blockHeight, setBlockHeight] = useState(0);
const inputCommandsRef = useRef(null);
useEffect(() => {
setBlockHeight(inputCommandsRef.current?.clientHeight)
}, [inputCommandsRef])
<div className="row" ref={inputCommandsRef}>
<div style={{padding: '20px'}} className="col-xxl-9">
<textarea name="" id="" cols="30" rows="10"></textarea>
</div>
<div className="flex-line d-flex justify-content-start col-xxl-3"
style={{ maxHeight: `${maxHeight}px` }}>
<h1>maxHeight ${maxHeight}</h1>
<table>
....
</table>
</div>
</div>
Problem that when I change size of textArea the height of second block is not change (and value in h1 tag also), I just get once height and that is all.

You should not use useRef variables inside depsArray, they work in different way. You just need a ResizeObserver.
function Block() {
const [blockSize, setBlockSize] = useState({
width: 0,
height: 0
});
const inputCommandsRef = useRef(null);
useEffect(() => {
const { current } = inputCommandsRef;
if (!current) return;
const setSizes = () => {
setBlockSize({
width: current.clientWidth,
height: current.clientHeight
});
};
setSizes();
const obs = new ResizeObserver(setSizes);
obs.observe(current);
return () => {
obs.unobserve(current);
};
}, []);
return (
<div className="row" ref={inputCommandsRef}>
<div style={{ padding: "20px" }} className="col-xxl-9">
<textarea name="" id="" cols="30" rows="10"></textarea>
</div>
<div
className="flex-line d-flex justify-content-start col-xxl-3"
style={{ maxHeight: `${blockSize.height}px` }}
>
<h1>maxHeight ${blockSize.height}</h1>
</div>
</div>
);
}

Related

How to add multiple div panels to my main page in React

This question expands on my problem which got partially solved here. I have two components, ApplicationOverview.js and ApplicationModal.jsx and I want to dynamically add div panels to the ApplicationOverview.js Component from the Modal. In the Modal I have two input fields and I can add an image, which will be displayed on the div after I clicked on the 'Add' button. This is what the Modal looks like and this is what I am trying to achieve with n number of panels. (Note that the first 3 panels are hard coded)
So far, I can add a single div panel to my page, but whenever I try to add another one, it just changes the text of the panel that I just added. I am currently just toggling the visibility of that single div I am adding with a boolean (as you can see on the bottom of ApplicationOverview.js), but I can't figure out how I'd add multiple divs from my Modal to the page. Also, when I close the Modal but type something into the input fields, the text on the added div will still change without clicking on 'Add' beforehand.
ApplicationModal.jsx:
import React from "react";
var name = "";
var comment = "";
var filename = "";
const ApplicationModal = ({
setOpen,
setState,
setStateComment,
setFile,
file,
setBool,
}) => {
React.useEffect(() => {
function handleEscapeKey(event) {
if (event.code === "Escape") {
setOpen(false);
}
}
document.addEventListener("keydown", handleEscapeKey);
return () => document.removeEventListener("keydown", handleEscapeKey);
});
const handleComment = (e) => {
setStateComment(e.target.value);
};
const handleChange = (e) => {
setState(e.target.value);
};
const addNewApplication = () => {
setBool(true);
setOpen(false);
};
function openDialog() {
document.getElementById("inputUpload").click();
}
function loadFile(e) {
console.log(e.target.files);
setFile(URL.createObjectURL(e.target.files[0]));
}
document.addEventListener("click", function (e) {});
return (
<React.Fragment>
<div className="modalDark" style={{ paddingRight: "250px" }}>
<div class="modal-dialog">
<div class="modal-content" style={{ width: "800px" }}>
<div class="modal-close">
<div class="module-button" style={{ left: "750px" }}>
<button
class="btn btn-link "
onClick={() => setOpen(false)}
></button>
<div class="button-animation"></div>
<div class="button-content new">
<i class="icon icon-dc_close"></i>
</div>
</div>
</div>
<div class="modal-header">
<h3>Add new Application</h3>
</div>
<div class="modal-body">
<div
class="module-input form-group has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px", width: "350px" }}
>
<label for="demo-default">Customer Name</label>
<div class="input-animation-wrapper">
<input
type="text"
id="demo-default"
class="form-control "
maxLength="42"
placeholder="[Application Name]"
onChange={(e) => handleChange(e)}
/>
<div class="input-animation"></div>
</div>
</div>
<div
class="module-textarea form-group floating-label has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px" }}
>
<label for="demo-3">Customer Short text</label>
<div class="input-animation-wrapper" style={{ width: "350px" }}>
<textarea
id="demo-3"
class="form-control"
rows="9"
placeholder="Short description of Customer; max. 280 characters"
maxLength={180}
onChange={(e) => handleComment(e)}
style={{ width: "350px" }}
></textarea>
<div class="label-area"></div>
<div class="input-animation"></div>
</div>
</div>
<img
class="image"
alt="Customer Logo"
id="logo"
src={file}
style={{
left: "420px",
bottom: "280px",
position: "absolute",
height: "250px",
}}
/>
<div
class="module-button"
style={{
left: "500px",
bottom: "200px",
position: "absolute",
zIndex: "1",
}}
>
<button
type="file"
class="btn btn-light"
onClick={() => openDialog()}
id="fileUpload"
>
<input
type="file"
hidden={true}
accept="image/*"
id="inputUpload"
onChange={(e) => loadFile(e)}
></input>
</button>
<div class="button-animation"> </div>
<div class="button-content">
<span class="content-text">Upload Logo</span>
</div>
</div>
<div
class="module-button"
style={{ bottom: "50px", width: "100px", textAlign: "center" }}
>
<button
type="button"
class="btn btn-secondary btn"
onClick={() => addNewApplication()}
id="adding"
></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Add</span>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
};
export default ApplicationModal;
export { name, comment, filename };
ApplicationOverview.js:
import React from "react";
import "../Overview.css";
import ApplicationModal from "../components/ApplicationModal.jsx";
var id = 0;
const ApplicationOverview = () => {
const [open, setOpen] = React.useState(false);
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState("");
const [file, setFile] = React.useState("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/681px-Placeholder_view_vector.svg.png");
const [bool, setBool] = React.useState(false);
function addID()
{
id++;
console.log(id)
return id;
}
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} setState={setState} file={file} setBool={setBool} setFile={setFile} setStateComment={setStateComment} />}
<div class="component-headline">
<h4 style={{ color: "gray", display: "inline" }}>
Application overview
</h4>
<div
class="module-button"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
marginLeft: "1032px",
}}
onClick={() => setOpen(true)}
>
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div
class="button-content"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
}}
>
<span class="content-text" style={{ color: "black" }}>
Add Application
</span>
</div>
</div>
</div>
<hr style={{ marginTop: "-20px" }} />
<div class="center-content" id="center">
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Press</h3>
<p class="overview-p">This Application is used for maintenance</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Tooling Machine</h3>
<p class="overview-p">
This Application is used for drilling records
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Storing Unit</h3>
<p class="overview-p">
This Application is used for store parameters
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
{(stateComment || state) && bool && <div class='overview-box' id={addID()}> <img class='image' src={file} alt='car'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>{state}</h3> <p class='overview-p'>{stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div> }
</div>
</div>
);
};
export default ApplicationOverview;
So if I understand your problem is that you have a modal and when you fill the modal and send add it will add the text and images to ApplicationOverview. I think you want to be able to do that several times. You want your users to be able to complete the modal again and again so it keep adding at the bottom of the ApplicationOverview.
So you need your ApplicationModal to have its own state.
const [modalState, setModalState] = useState("");
const [modalCommentState, setCommentModalState] = useState("");
const [modalFile, setModalFile] = useState("");
so your handler function should be
const handleComment = (e) => {
setCommentModalState(e.target.value);
};
const handleChange = (e) => {
setModalState(e.target.value);
};
function loadFile(e) {
setModalFile(URL.createObjectURL(e.target.files[0]));
}
Your submit function
const addNewApplication = () => {
setOpen(false);
setStates( oldArray => [...oldArray, {
state:modalState,
stateComment:modalCommentState,
file: modalFile } ]);
};
in the ApplicationOverview.js
const [states, setStates] = useState([]);
in your HTML section you loop through the state with a map
{ states.map((state)=> {
return (
<div class='overview-box' id={addID()}>
<img class='image' src={state.file} alt='car'/>
<div class='box-content'>
<h3 class='overview-h3' id='new-headline'>{state.state}</h3>
<p class='overview-p'>{state.stateComment}</p>
<h3 class='overview-h3-second'>Connected Products</h3>
<h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p></h1>
<div class='module-button' id='configure'>
<button type='button' class='btn btn-secondary'></button>
<div class='button-animation'></div>
<div class='button-content'>
<span class='content-text'>Configure</span>
</div>
</div>
</div>
</div>
})}
So everytime the user submit the modal it will get added to the array of states and it will be display in the ApplicationOverview

Can't get my values/data to insert into second MySQL db even though now errors show

The issue: My first table bugtracker_table on dashboard.js works fine when I submit data to it but my second table ticket_table on projects.js do not submit values even though it's pretty much the same code.
I even have the terminal that says: Executing (default): INSERT INTO ticket_table (id,ticket_title,ticket_description,type_menu,priority_menu,status_menu,createdAt,updatedAt) VALUES (DEFAULT,?,?,?,?,?,?,?);
But there is no data in table.
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
const projectsToShow = projects.map((project) => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>,
};
});
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<Button icon="pi pi-times" className="p-button-rounded p-button-danger p-button-text mr-2 mb-2 x-button" onClick={handleClose}></Button>
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
{/* <Button onClick={handleClose}>Close</Button> */}
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projectsToShow}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="createdAt" header="Created On" style={{ minWidth: "150px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
Projects.js
import React, { useState, useEffect } from "react";
import { Column } from "primereact/column";
import { DataTable } from "primereact/datatable";
import { Button } from "primereact/button";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
// import { InputNumber } from "primereact/inputnumber";
import { Dropdown } from "primereact/dropdown";
import axios from "axios";
const Projectz = () => {
const [ticket_title, setTicketTitle] = useState("");
const [ticket_description, setTicketDescription] = useState("");
// const [time_takes, setTimeTakes] = useState("");
const [type_menu, setTypeMenu] = useState("");
const [priority_menu, setPriorityMenu] = useState("");
const [status_menu, setStatusMenu] = useState("");
const [projects, setProjects] = useState([]);
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/ticket_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/ticket_table", {
ticket_title: ticket_title,
ticket_description: ticket_description,
// time_takes: time_takes,
type_menu: type_menu,
priority_menu: priority_menu,
status_menu: status_menu,
});
};
const dropdownValues1 = [
{ name: "Issue", code: "ISS" },
{ name: "Bug", code: "BUG" },
{ name: "Error", code: "ERR" },
{ name: "Other", code: "OTH" },
];
const dropdownValues2 = [
{ name: "Low", code: "LOW" },
{ name: "Medium", code: "MED" },
{ name: "High", code: "HI" },
{ name: "Immediate", code: "IMM" },
];
const dropdownValues3 = [
{ name: "New", code: "NEW" },
{ name: "Open", code: "OP" },
{ name: "In Progress", code: "IP" },
{ name: "Resolved", code: "RES" },
{ name: "Additional Info Required", code: "AIR" },
];
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Tickets</h5>
<div>
<Button label="New Ticket" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Create Ticket</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={ticket_title} onChange={(e) => setTicketTitle(e.target.value)} type="text" placeholder="Enter ticket title"></InputText>
</div>
</div>
<h5>Ticket Description</h5>
<InputTextarea value={ticket_description} onChange={(e) => setTicketDescription(e.target.value)} type="text" placeholder="Enter ticket description" autoResize rows="3" cols="30" />
{/* <h5>Time Estimate (Hours)</h5> */}
{/* <InputNumber value={time_takes} onValueChange={(e) => setTimeTakes(e.value)} showButtons mode="decimal"></InputNumber> */}
<h5>Type</h5>
<Dropdown value={type_menu} onChange={(e) => setTypeMenu(e.value)} options={dropdownValues1} optionLabel="name" placeholder="Select" />
<h5>Priority</h5>
<Dropdown value={priority_menu} onChange={(e) => setPriorityMenu(e.value)} options={dropdownValues2} optionLabel="name" placeholder="Select" />
<h5>Status</h5>
<Dropdown value={status_menu} onChange={(e) => setStatusMenu(e.value)} options={dropdownValues3} optionLabel="name" placeholder="Select" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
<div>
<DataTable
// sortMode="single" sortField="representative.name"
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
</DataTable>
</div>
</div>
</div>
</div>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Ticket Info</h5>
<div>
<DataTable
// value={projects}
// sortMode="single" sortField="representative.name"
// sortOrder={1}
// scrollable
// scrollHeight="400px"
// responsiveLayout="scroll"
>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.ticket_title}</td>
<td>{project.ticket_description}</td>
{/* <td>{ticket.time_takes}</td> */}
<td>{project.type_menu}</td>
<td>{project.priority_menu}</td>
<td>{project.status_menu}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(Projectz);

How to make MySQL data a link in frontend using Reactjs?

Intended function: Projects names pulled from MySQL database that are listed in table column, will be a link to /projects page listing related unique information.
What is actually happening: Project names that are pulled from MySQL database that are listed in table column, are not links.
See pics for details: https://imgur.com/a/jp1JvV0
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projects}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
{/* <Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column> */}
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>
<Link to={`/projects/${project.id}`}>{project.project_name}</Link>
</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>\{" "}
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
You could do a map to the projects array into a new variable before passing it to the Datatable value parameter
const projectsToShow = projects.map(project => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>
}
})
then the DataTable can handle the display with projectsToShow instead of project
<DataTable
...
value={projectsToShow}
...
>

Show a spinner until the results load from the HTTP request for autocomplete field

I want to show a spinner until the results load from the HTTP request on autocomplete field. Below is the snippet of the code written.
HTML
<label class="col-2 col-form-label text-right font-weight-bold">City *</label>
<div class="col-2">
<div>
<input id="typeahead-prevent-manual-entry" type="text" class="form-control"
[(ngModel)]="myActivity.city"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
name="citySelected"
#citySelected="ngModel"/>
</div>
<div>
Typescript
formatter = (city: City) => city.name;
search = (text$: Observable<string>) => text$.pipe(
debounceTime(10),
distinctUntilChanged(),
filter(criterion => criterion.length >= 2),
map(criterion => criterion.length < 3 ? [] : this.searchLocalities(criterion).filter(city => new
RegExp(criterion, 'mi').test(city.name)).slice(0, 20))
);
searchLocalities(criterion: string): City[] {
this.isLoadingResult = true;
this.activityService.getLocalities(this.prvCodId, criterion).subscribe(
data => {
data.map(item => {
if (this.localities.find((city) => city.name === item.name) === undefined) {
this.localities.push(item);
}});
this.isLoadingResult = false;
});
return this.localities;
}
are you using material angular in your project? if yes you can easily use mat-proggress-spinner.
first of all import the module into your appModule:
import {MatProgressSpinnerModule} from '#angular/material/progress-spinner';
add it to your imports:
//
imports: [MatProgressSpinnerModule]
//
then in your template, you can use it as bellow:
<div class="col-2">
<mat-spinner *ngIf="isLoadingResult" diameter="30"></mat-spinner>
<div *ngIf="!isLoadingResult">
<input id="typeahead-prevent-manual-entry" type="text" class="form-control"
[(ngModel)]="myActivity.city"
[ngbTypeahead]="search"
[inputFormatter]="formatter"
[resultFormatter]="formatter"
name="citySelected"
#citySelected="ngModel"/>
</div>
<div>
but if you are not using material angular and you don't want to, you can just use a tag gif instead of mat-spinner.
put the gif in your assets and:
<img *ngIf="isLoadingResult" src="assets/images/loading.gif" />
in your html:
<div class="input-container">
<img class="loading-img" src="your loading img location">
<input type="text">
</div>
in your css:
.input-container {
display: flex;
position: relative;
width: 200px
}
.loading-img {
position: absolute;
right: 0;
top: 3px;
height: 20px;
width: 20px;
}
input {
width: 100%;
padding-right: 25px;
}
this will put the IMG in the right corner of the input.
You can use the mat-progress-bar library, see the example below.
//declaration
isApiCalling = false;
//use case
this.isApiCalling = true;
this._apiCall.get(this.url)
.subscribe(
data => {
this.isApiCalling = false;
},
err => {
this.isApiCalling = false;
}
);
<!-- actual term is isApiCalling -->
<mat-progress-bar mode="indeterminate" *ngIf="isApiCalling"></mat-progress-bar>

How to send a picture and name to the database?

Stack vue.js + laravel5.7 I need to load the image and name into the database using axios tools in the component. There is a problem in the code, I can’t understand what is wrong.
Separately, the name downloaded and displayed, it was useful to screw the picture, everything broke. The server on php7.1
Here is my template
<form v-on:submit.prevent="submitCategory()" class="col s12 l12">
<div class="col s12 l3">
<div class="input-field ">
<input id="name" type="text" v-model="posts.name">
<label for="name">Название</label>
<div class="file-field input-field">
<div class="btn">
<span>Загрузить изображение</span>
<input type="file" v-on:change="onFileChange">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
</div>
<div>
<button class="waves-effect waves-light btn">
Сохранить изменения
</button>
</div>
</div>
<div class="col s12 l3 center">
<div v-if="!posts.image">
<img src="/images/No_image.png" style="height: 200px"/>
</div>
<div v-else>
<img :src="posts.image" style="height: 200px"/>
<button #click="removeImage" class="btn">Удалить изо</button>
</div>
</div>
</form>
And this is my script
<script>
import axios from 'axios';
export default {
data: function() {
return {
posts: {
name:'',
image:'',
},
errors: []
}
},
methods:{
submitCategory() {
axios.post(`/categories`, this.posts)
.then(response => {
console.log(response)
//this.$router.push({path:'/'})
this.posts = response.data
})
.catch(e => {
this.errors.push(e)
})
},
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
console.log(files);
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
// var vm = this;
reader.onload = (e) => {
this.posts.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function (e) {
this.posts.image = '';
e.posts.target.reset();
}
}
}
</script>
It is expected that the name and the picture will be written into the jamb with categories by the columns name and image, but nothing happens.