Show react component on click - reactjs

So I'm creating a website for the receptionists at a doctor's office. In order to make a new booking, I have a plus button, and when you click it, I want the makeBooking component to pop up and then there's also a cancel button.
Currently, I am struggling to make the component appear onClick.
This is my code:
This is in the appointments component above return
// handleBooking
const [showResults, setShowResults] = React.useState(false)
const handleBooking = () => setShowResults(true)
This is in return:
<button class='addBtn' id="btn"><div className='plus-icon' onClick={handleBooking}><UilPlus/></div></button>
{ showResults ? <MakeBooking /> : null }
And this is my component:
import React from 'react';
import { UilTimes } from '#iconscout/react-unicons';
const MakeBooking = () => {
return (
<div>
<div className='appointments-form'>
<form id="homeForm">
<button class='closeBtn' id="btn"><div className='close-icon'><UilTimes/></div></button>
<div className='heading'>
<h1>Make booking</h1>
<h3>Let's get this clients pet booked!</h3>
</div>
<div className='new-book-container home'>
<input list="docList" className='booking-input home' type='text' placeholder='doctor'/>
<datalist id="docList">
<option value="Sarah"/>
<option value="Josh"/>
<option value="Daina"/>
<option value="Tanielle"/>
<option value="Tony"/>
</datalist>
<input list="clientList" className='booking-input home' type='text' placeholder='client'/>
<datalist id="clientList">
<option value="Sarah"/>
<option value="Josh"/>
<option value="Daina"/>
<option value="Tanielle"/>
<option value="Tony"/>
</datalist>
<input className='booking-input home' type='date' placeholder='Date'/>
<input className='booking-input home' type='time' placeholder='time'/>
<input className='booking-input home' type='number' placeholder='room'/>
<button className='primary-btn' id='btn'>Book appointment</button>
</div>
</form>
</div>
</div>
);
};
export default MakeBooking;

Try this it will work:
const [showResults, setShowResults] = React.useState(false)
const handleBooking = event => {setShowResults(true)};
{ showResults && <MakeBooking /> }

Related

Edit Data in Parent from Child

Apparently I'm not doing this right, but I'm trying to mutate a map in the parent component from a child component in React 18.2. The parent contains a modal which opens a form. The user then inputs their mutate option (delete/add) and subsequent data from there. I've been going through other questions trying to find an answer for why it's not working as intended, but I can't seem to find much info. Would appreciate any help. This is what I currently have:
Parent.Js
const ParentComponent = ({show, onCloseModalButton}) => {
const resorts = new Map()
resorts.set("Keystone", [39.6069742, -105.97011])
resorts.set("Breckenridge", [39.4808, -106.0676])
resorts.set("Vail", [39.6061, -106.3550])
resorts.set("Crested Butte", [38.8991, -106.9658])
resorts.set("Winter Park", [39.8841, -105.7627])
resorts.set("Copper Mountain", [39.5022, -106.1497])
const [formOption, setFormOption] = React.useState("")
const [formData, setFormData] = React.useState({
resortName: "",
longitude: Number,
latitude: Number,
})
const handleOptionChange = e => {
setFormOption(e.target.value)
}
const handleFormDataChange = e => {
setFormData({
...formData,
[e.target.name]: e.target.value,
})
}
const submitForm = e => {
e.preventDefault()
if (formOption === "Add") {
resorts.set(formData.resortName, [formData.latitude, formData.longitude])
}
if (formOption === "Delete") {
resorts.delete(formData.resortName)
}
}
return (
<div>
<Modal show={show} onCloseModalButton={onCloseModalButton} resorts={resorts} submitForm={submitForm} handleOptionChange={handleOptionChange} handleFormChange={handleFormDataChange} option={formOption} form={formData} />
</div>
)
}
export default ParentComponent;
Modal.js
const Modal = ({show, onCloseModalButton, resorts, submitForm, handleOptionChange, handleFormChange, option, form}) => {
if (!show) {
return null
}
return ReactDOM.createPortal (
<div className='modal-bg'>
<div className='modal'>
<form onSubmit={submitForm}>
<label>Modify:
<select
name="option"
value={option}
onChange={handleOptionChange}
>
<option value="" disabled={true}>-- Choose an Option --</option>
<option value="Add">Add</option>
<option value="Delete">Delete</option>
</select>
</label>
{option === "" ? null :
option === "Add" ?
<div>
<label>Resort Name
<input
type="text"
name="resortName"
value={form.resortName}
onChange={handleFormChange}
/>
</label>
<br></br>
<label>Longitude
<input
type="number"
name="longitude"
value={form.longitude}
onChange={handleFormChange}
/>
</label>
<br></br>
<label>Latitude
<input
type="number"
name="latitude"
value={form.latitude}
onChange={handleFormChange}
/>
</label>
<button type='submit'>Submit</button>
</div> :
<div>
<label>Delete
<select
name="delete"
value={form.resortName}
onChange={handleFormChange}
>
{[...resorts.keys()].map((item)=> {
return <option key={item} value={item}>{item}</option>
})}
</select>
</label>
<button type='submit'>Submit</button>
</div>
}
</form>
<button onClick={onCloseModalButton}>Close Modal</button>
</div>
</div>
, document.body
)
}
export default Modal;

Typing in the search box, system got stuck, unable to perform continuous typing [duplicate]

hey I'm new to react js.
can anyone help to answer this Q : How do I prevent my input field from losing focus when typing?
Every time I type in one of my input fields, the field loses focus.
note: the first <div className="container_info"> iputs work just fine.
import React, { Fragment, useState } from "react";
import {
FaRegSave
} from "react-icons/fa";
import axios from 'axios';
import { Tabs, Tab } from '#material-ui/core'
const InputEemp = (index) => {
/* information publiques */
const [fname, setFname] = useState("");
const [lname, setLname] = useState("");
const [gender, setGender] = useState("");
const [tel_pro_portable, setTelPportable] = useState("");
const [lieu_travail, setLieu_Travail] = useState("");
const [adresse_elec_pro, setAdresseEpro] = useState("");
const [tele_pro, setTelePro] = useState("");
const [departement, setDepartement] = useState("");
const [titre_post, setTitrePost] = useState("");
const [gestionnaire, setGestionnaire] = useState("");
const [mentor, setMentor] = useState("");
const [temp_travail, setTempTravail] = useState("");
const [autre, setAutre] = useState("");
/* end of information publiques */
//appbar************
const [tabValue, setValue] = React.useState(0);
const handlerTabs = (e, val) => {
console.warn(val);
setValue(val);
}
function TabPanel(props) {
const { children, value, index } = props;
return (
<div>
{
value === index && (<div>{children}</div>
)
}
</div>
)
}
const addEmpll = async e => {
e.preventDefault();
try {
await axios.post('http://localhost:5000/employees', {
f_name: fname,
l_name: lname,
gender: gender,
tel_pro_portable: tel_pro_portable,
lieu_travail: lieu_travail,
adresse_elec_pro: adresse_elec_pro,
tele_pro: tele_pro,
departement: departement,
titre_post: titre_post,
gestionnaire: gestionnaire,
mentor: mentor,
temp_travail: temp_travail,
autre: autre
}, {
headers: {
'Content-Type': 'application/json'
}
})/* .then(res => {
console.log(res.data);
}); */
window.location = ('/');
} catch (err) {
console.log(err.message);
}
};
return (
<Fragment>
<div className="container_emp">
<form onSubmit={addEmpll}>
<div className="container_info">
<div className="header">Profile de l'Employe : <button type="submit" className="sauver_btn btn btn-success"><FaRegSave /> Sauver</button>
<hr className="hr_padding" />
</div>
<div className="side_content imgCenter"><img src=".\nouser.png" alt="emp" className="rounded-circle bg-secondary" style={{ "width": "120px" }} /></div>
<div className="content">
<div className="content_cc">
<div className="nom_label"><label className="font-weight-bold text-secondary col">Nom :</label></div>
<div className="nom_input"><input type="text" className="form-control col" placeholder="insérez votre nom" value={fname} onChange={e => setFname(e.target.value)} /></div>
<div className="prenom_label"><label className="font-weight-bold text-secondary col">Prénom :</label></div>
<div className="prenom_input"><input type="text" className="form-control col" placeholder="insérez votre Prénom" value={lname} onChange={e => setLname(e.target.value)} /></div>
<div className="sexe_label"><label className="font-weight-bold text-secondary col">Sexe :</label></div>
<div className="F_radio">
<label className="radio-inline pr-5">
<input type="radio" name="gender" value="Masculin" onChange={e => setGender(e.target.value)} /> Masculin
</label>
</div>
<div className="M_radio">
<label className="radio-inline">
<input type="radio" name="gender" value="Féminin" onChange={e => setGender(e.target.value)} /> Féminin
</label>
</div>
</div>
</div>
<div className="footer imgCenter"> <input type="file" className="form-control-file" id="exampleFormControlFile1" text="Changer l'image"></input></div>
</div>
<div className="emp_info1">
<hr className="hr_padding" />
{/* <AppBar position="static"> */}
<Tabs value={tabValue} onChange={handlerTabs}>
<Tab className="bg-dark text-white" label="Information Publiques" />
<Tab className="bg-dark text-white" label="Information Personnelle" />
<Tab className="bg-dark text-white" label="Paramètre RH" />
<Tab className="bg-dark text-white" label="Configuration de la paie" />
<Tab className="bg-dark text-white" label="Prêt logement" />
</Tabs>
{/* </AppBar> */}
<TabPanel value={tabValue} index={0}>
<div className="info_publique">
<div className="info_contact">
<div className="info_contact_child">
<div className="info_contact_label text-info font-weight-bold"><h4>Information de contact</h4></div>
<div className="tele_por">Tél. portable professionnel :</div>
<div className="telePor_input"><input type="text" className="form-control col" placeholder="insérez votre Tél. portable professionnel" value={tel_pro_portable} onChange={e => setTelPportable(e.target.value)} /></div>
<div className="lieu_tr">Lieu de Travail :</div>
<div className="lieu_input"><input type="text" value={lieu_travail} onChange={e => setLieu_Travail(e.target.value)} className="form-control col" placeholder="insérez votre Lieu de Travail" /></div>
<div className="adresse">Adresse électronique professionnel :</div>
<div className="adrees_input"><input type="text" value={adresse_elec_pro} onChange={e => setAdresseEpro(e.target.value)} className="form-control col" placeholder="insérez votre Adresse électronique professionnel" /></div>
<div className="tele_prof">Télephone professionnel :</div>
<div className="tele_pro_input"><input type="text" value={tele_pro} onChange={e => setTelePro(e.target.value)} className="form-control col" placeholder="insérez votre Télephone professionnel" /></div>
</div>
</div>
<div className="info_post">
<div className="info_post_child">
<div className="info_post_label text-info font-weight-bold"><h4>Post</h4></div>
<div className="dep_label">Département :</div>
<div className="dep_input">
<select className="form-control" value={departement} onChange={e => setDepartement(e.target.value)}>
<option value={0}>Select Département</option>
<option>IT</option>
<option>dep 1</option>
<option>dep 2</option>
</select>
</div>
<div className="titre_label">Titre du poste :</div>
<div className="titre_input">
<select className="form-control" value={titre_post} onChange={e => setTitrePost(e.target.value)}>
<option value={0}>Select Titre poste</option>
<option>poste 1</option>
<option>poste 2</option>
</select>
</div>
<div className="gestionnaire_label">Gestionnaire :</div>
<div className="gestionnaire_input">
<select className="form-control" value={gestionnaire} onChange={e => setGestionnaire(e.target.value)}>
<option value={0}>Select Gestionnaire</option>
<option>Gestionnaire 1</option>
<option>Gestionnaire 2</option>
</select>
</div>
<div className="mentor_label">Mentor :</div>
<div className="mentor_input">
<select className="form-control" value={mentor} onChange={e => setMentor(e.target.value)}>
<option value={0}>Select Mentor</option>
<option>Mentor 1</option>
<option>Mentor 2</option>
</select>
</div>
<div className="T_travail_label">Temps de travail :</div>
<div className="T_travail__input">
<select className="form-control" value={temp_travail} onChange={e => setTempTravail(e.target.value)}>
<option value={0}>Select Temps travail</option>
<option>Temps travail 1</option>
<option>Temps travail 2</option>
</select>
</div>
</div>
</div>
<div className="autre_info">
<textarea className="form-control" rows="2" placeholder="Autre information" value={autre} onChange={e => setAutre(e.target.value)}></textarea>
</div>
</div>
</TabPanel>
<TabPanel value={tabValue} index={1}>this is : Information Personnelle</TabPanel>
<TabPanel value={tabValue} index={2}>this is : Paramètre RH</TabPanel>
<TabPanel value={tabValue} index={3}>this is : Configuration de la paie</TabPanel>
<TabPanel value={tabValue} index={4}>this is : Prêt logement</TabPanel>
</div>
</form>
</div>
</Fragment>
)
};
export default InputEemp;
Issue
The TabPanel component is declared inside the parent InputEemp, so it's recreated each render cycle. In other words, each render cycle each TabPanel is a new React component; the old TabPanel component is unmounted and the new TabPanel component is mounted, thus losing the focus from the old one.
It's generally considered a React anti-pattern to defined React components inside other React components.
Solution
Move the TabPanel component declaration outside the InputEemp component.
Example:
function TabPanel(props) {
const { children, value, index } = props;
return <div>{value === index && <div>{children}</div>}</div>;
}
const InputEemp = (index) => {
/* information publiques */
...
/* end of information publiques */
...
return ( ... );
};

how do i get specific data from the state on a button click in react

Here i have 3 products each have it's own addtocart button and it's option like color, size, quantity. so when i click addtocart button after selecting the options it updating the state and giving me exactly i wanted. The problem is when i selelct any product options and then i click on another product addtocart button it shows the selceted option. not the product options of the addtocart button i clicked
for example: i select the 1st product and choose it's options and i did'nt click on the 1st product addtocart button either i clicked 2nd product button but it returns 1st product selected options it should return 2nd product options.
i need to implement which ever the product button i clicks it should only return that product selected options only.it should'nt return any other product selected options.
how do i make this happen. Help me out.
function Card() {
const [items, setItems] = useState({});
const handleChageCategory = (key, event) => {
setItems((oldState) => ({ ...oldState, [key]: event.target.value }));
};
const submitHandler = () => {
console.log(items);
setItems({});
};
return (
<div className="main-container">
<div className="container">
<div className="image-container">
<img
src="https://images.pexels.com/photos/9558601/pexels-photo-9558601.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
alt=""
/>
</div>
<h2> T-Shirt </h2>
</div>
<div className="form-conatiner">
<div className="selectors">
<p>Solid Round Neck T-shirt</p>
<select
id="color"
name="color"
required
onChange={(event) => handleChageCategory("color", event)}
>
<option>Color</option>
<option value="black">Black</option>
<option value="green">Green</option>
<option value="orange">Orange</option>
</select>
<select
name="quantity"
required
onChange={(event) => handleChageCategory("quantity", event)}
>
<option>Quantity</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select
name="size"
required
onChange={(event) => handleChageCategory("size", event)}
>
<option>Size</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
<option value="small">Small</option>
</select>
<div>
<button onClick={submitHandler}>Add to Cart</button>
</div>
</div>
</div>
{/* second product */}
<div className="container">
<div className="image-container">
<img
src="https://images.pexels.com/photos/440320/pexels-photo-440320.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
alt=""
/>
</div>
<h2> i-Watch </h2>
</div>
<div className="form-conatiner">
<div className="selectors">
<p>Dizo watch with amlod </p>
<select
id="2"
name="color"
required
onChange={(event) => handleChageCategory("brand", event)}
>
<option>Brand</option>
<option value="Apple">Apple</option>
<option value="Samsung">Samsung</option>
<option value="Pixel">Pixel</option>
</select>
<select
name="qantity"
required
onChange={(event) => handleChageCategory("qantity", event)}
>
<option>Quantity</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select
name="type"
required
onChange={(event) => handleChageCategory("type", event)}
>
<option>type</option>
<option value="29mm">29mm</option>
<option value="34mm">34mm</option>
<option value="42mm">42mm</option>
</select>
<div>
<button onClick={submitHandler}>Add to Cart</button>
</div>
</div>
</div>
{/* third product */}
<div className="container">
<div className="image-container">
<img
src="https://images.pexels.com/photos/1661471/pexels-photo-1661471.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
alt=""
/>
</div>
<h2> Hoodie </h2>
</div>
<div className="form-conatiner">
<div className="selectors">
<p>Adidas hoodie with zip </p>
<select
id="2"
name="color"
required
onChange={(event) => handleChageCategory("color", event)}
>
<option>Color</option>
<option value="Gray">gray</option>
<option value="White">white</option>
<option value="Cyan">cyan</option>
</select>
<select
name="qantity"
required
onChange={(event) => handleChageCategory("qantity", event)}
>
<option>Quantity</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select
name="size"
required
onChange={(event) => handleChageCategory("size", event)}
>
<option>type</option>
<option value="39(S)">39(S)</option>
<option value="42(M)">42(M)</option>
<option value="46(L)">46(L)</option>
</select>
<div>
<button onClick={submitHandler}>Add to Cart</button>
</div>
</div>
</div>
</div>
);
}
export default Card;
const [items, setItems] = useState([]);
The handleChangeCategory Logic
const handleChageCategory = (key,product, event) => {
const isExist = items.find((item)=>item.id===product.id)
let updatedItem
if(isExist){
updatedItem = {...isExist, [key]: event.target.value}
setItems((oldState)=>(oldState.map(item=>item.id===updatedItem.id ? updatedItem: item)))
}else{
updatedItem = { ...product, [key]: event.target.value };
setItems((oldState)=>([...oldState, updatedItem]))
}
};
Submit handler logic:
const submitHandler = (product) => {
const isExist = items.find(item=>item.id===product.id)
const newCartItem = isExist? isExist: product
console.log(newCartItem);
setItems((oldState)=>(oldState.filter(item=>item.id!==newCartItem.id)))
}
I know this is an expensive operation and it might hamper user experience but you wanted to do it this way. To handle add to cart, I think the good way is to open a modal or new page after clicking Add To Cart button that also solves your problem because in this way the user is not able to update one product value and click another product button.
A more efficient way to implement a product list is to use a product component for each item which accepts the product data through props. There you will implement all the logic related to the product and check the selected fields and so on.
Full code here.
So here I created Product, which has a selectedValues state that contains the values of all the selectors as an object, and also an handleAddToCart function that sends this product to the parent component function and add the product to the cart there.
Product.js:
const Product = (props) => {
const [selectedValues, setSelectedValues] = useState({});
const { name, description, img, selectors } = props;
//(`selectors` is an array of objects. Each object is a selector with an id field and an array of the `options`).
const handleChangeCategory = (e) => {
setSelectedValues((prevState) => {
return { ...prevState, [e.target.name]: e.target.value };
});
};
const handleAddToCart = () => {
props.addToCart({ name, description, img, selectedValues });//calling the function from the props.
};
return (
<div className="product">
<div className="image-container">
<img width="150px" src={img} alt="" />
</div>
<h2> {name}</h2>
<div className="form-conatiner">
<p>{description}</p>
<div className="selectors">
{selectors.map((s) => {
return (
<select
id={s.id}
name={s.id}
required
onChange={handleChangeCategory}
>
{s.options.map((opt) => (
<option value={opt}>{opt}</option>
))}
</select>
);
})}
</div>
<button onClick={handleAddToCart}>Add to Cart</button>
</div>
</div>
);
};
export default Product;
And this is the parent component, where you have the cart and the addToCartHandler function. And in the JSX you simply create a product by calling the Product component and passing the data and the selectors you want to have for this product.
App.js (parent component):
export default function App() {
//Some dummy cart.
const DUMMY_CART = [];
//Function that adds a product to the DUMMY_CART
const addToCartHandler = (product) => {
//Do some logic with the cart of course. I'm just pushing it here to show you the result.
DUMMY_CART.push(product);
console.log('Added product:', product);
console.log('Cart:', DUMMY_CART);
};
return (
<div>
{/* Product 1 */}
<Product
img="https://images.pexels.com/photos/9558601/pexels-photo-9558601.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
name="T-Shirt"
description="Solid round neck T-Shirt"
selectors={[
{ id: 'color', options: ['Color', 'blue', 'grin', 'yellow'] },
{ id: 'quantity', options: ['Quantity', 1, 2, 3] },
{ id: 'size', options: ['Size', 'medium', 'large', 'small'] },
]}
addToCart={(product) => addToCartHandler(product)}
/>
</div>
);
}
Hope this helps. Please check the full code to see how it works.

componentDidUpdate function doesn't get called

I've created a React component to render another component inside.when I change the select element in the parent component the componentDidUpdate function doesn't get called in the child component
component1:
let ExtraParam = [];
const handleChange = (e) => {
ExtraParam[e.target.name] = e.target.value;
}
const Flights = () => {
return (
<div>
<div className="row">
<div className='col-6 col-md-3 mt-5'>
<select onChange={handleChange} name="age" className="browser-default custom-select">
<option>Choose your option</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</div>
<Datatable Api='/api/Flights' Columns={columns} extraParam {ExtraParam} />
</div>
)
}
component2:
componentDidUpdate(prevProps) {
if (this.props.extraParam !== prevProps.extraParam)
{
console.log('changed');
}
}

React not changing local state dropdown value

I'm building a PO # entry system to enter the PO number, the due date and the priority. Both the PO number and the due date get changed as they should, but the priority doesn't.
Here's the component code:
import React, { useState, useContext, useEffect } from 'react';
import M from 'materialize-css';
import OrderContext from '../../context/order/orderContext';
import AlertContext from '../../context/alert/alertContext';
const POEntry = () => {
const orderContext = useContext(OrderContext);
const alertContext = useContext(AlertContext);
const { submitPO } = orderContext;
const { setAlert } = alertContext;
const [newOrder, setNewOrder] = useState({
poNum: '',
dueDate: '',
priority: '',
});
const { poNum, dueDate, priority } = newOrder;
const onChange = (e) => {
setNewOrder({
...newOrder,
[e.target.name]: e.target.value,
});
};
const onSubmit = (e) => {
e.preventDefault();
if (poNum === '') {
setAlert('Please fill in all fields', 'danger');
} else {
console.log(poNum);
console.log(dueDate);
submitPO({
poNum,
dueDate,
priority,
});
}
};
useEffect(() => {
M.AutoInit();
// eslint-disable-next-line
}, []);
return (
<div className="row">
<form className="col s12" onSubmit={onSubmit}>
<div className="row">
<div className="col s12">
<div className="input-field col s4">
<i className="fas fa-archive prefix"></i>
<label htmlFor="poNum">Enter PO Number...</label>
<input
id="poNum"
name="poNum"
type="text"
value={poNum}
onChange={onChange}
/>
</div>
<div className="input-field col s4">
<i className="fas fa-calendar-day prefix"></i>
<input
id="dueDate"
name="dueDate"
type="date"
value={dueDate}
onChange={onChange}
/>
</div>
<div class="input-field col s4">
<select value={priority} onChange={onChange}>
<option value="low">Low Priority</option>
<option value="norm">Normal Priority</option>
<option value="high">High Priority</option>
</select>
<label>Priority Level</label>
</div>
</div>
</div>
<div className="col s12">
<button className="btn btn-primary btn-block">Submit PO</button>
</div>
</form>
</div>
);
};
export default POEntry;
To reiterate, the poNum and dueDate state variables get changed in the state properly, but when I select a priority, it creates a new state value labeled : instead of updating the priority value.
It's probably something easy, but I'm at my wits end here. Help!
You are missing a name attribute for your priority select.
You need to do:
<select value={priority} onChange={onChange} name="priority">
<option value="low">Low Priority</option>
<option value="norm">Normal Priority</option>
<option value="high">High Priority</option>
</select>

Resources