Push selected option on click - node.js

Im using Node.js, but i really don't know how i can do this guys, pls help
i need push selected option when user click on button, like a cart.
to before submit
const classes = useStyles();
const [codigo, setCodigo] = useState('');
const [nome, setNome] = useState('');
const [descricao, setDescricao] = useState('');
const [preco, setPreco] = useState('');
const [peso, setPeso] = useState('');
const [itemServico, setItemServico] = useState('');
const [servicos, setServicos] =useState([ ]);
useEffect(() =>{
async function loadServicos(){
const response = await api.get("/api/servicos");
console.log(response.data);
setServicos(response.data);
}
loadServicos();
},[])
how can i do this,
<Grid item xs={12} sm={12}>
<FormControl className={classes.formControl}>
<InputLabel id="demo-simple-select-label"></InputLabel>
<Select
native
labelId="demo-simple-select-label"
id="selectServico"
>
{servicos.map((opcao) => (
<option aria-label="None" value={opcao._id}>{opcao.codigo_servico}" - "{opcao.nome_servico}</option>
))}
</Select>
<Button onClick={itemServico.push(document.getElementById("selectServico"))}>Adicionar</Button>
</FormControl>
</Grid>

You need something like this. Please note that I couldn't througly test this as I don't have the full context of your app.
export default function App() {
const [servicos, setServicos] =useState([]);
const [itemServico, setItemServico] = useState([]);
const select = useEffect();
const add = () => {
if(!itemServico.includes(select.current.value))
setItemServico([...itemServico, select.current.value])
}
return (
<div className="App">
<Select
native
labelId="demo-simple-select-label"
id="selectServico"
ref={select}
>
{servicos.map((opcao) => (
<option aria-label="None" value={opcao._id}>{opcao.codigo_servico}" - "{opcao.nome_servico}</option>
))}
</Select>
<Button onClick={add}>Adicionar</Button>
</div>
);
}
We create a reference to the Select element by using the useRef hook. This will allow us to access the Select's value at any time.
We also create a function, add, that adds the selected option's value to the itemServico array. But it only does so if the value being added does not already exists in the array.
Finally, we use the onClick prop of the button to call the add function. This, in a nutshell, is what you would need.

Related

How can I recall a GET request with new parameters and have it get the new items with the parameters in MERN stack?

Initially I used a GET request to call every single item in my MongoDB database to my frontend but now I'm trying to implement a filter system where users would narrow down the options presented by the database using filters.
Here is the concept of what i'm trying to do, this is what it looks like:
If someone selects the filter options "SDG 2: Zero Hunger", "1: Discussion Project", and "Demographic", the user will click submit and then only the first card that has all those things will show up on the right of it, not the second one underneath it.
I'm struggling as to how I would send the information as to how to filter the database because I get the error Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.
How could I code it so that once a user clicks submit, it sends an object containing the filter table data, ex. const filterData = {sdg, assignment_type, theme} (where each refers to its respective thing), to the backend where I perform a GET request to the database in which I use the following code to pull the filtered data:
// filtering a project, calling this everytime filter is changed
const filterProject = async (req, res) => {
const {sdg, assignment_type, theme} = req.body
const filteredProjects = await Project.find({sdg: sdg, assignment_type: assignment_type, theme: theme})
res.status(200).json(filteredProjects)
}
Here is the code for my filtering page right now:
// Filterpage.js
import ProjectDetails from '../ProjectDetails'
import Dropdown from './Dropdown'
import { useEffect, useState } from 'react'
const FilterBody = () => {
const [projects, setProjects] = useState(null)
useEffect(() => {
const fetchProjects = async () => {
const response = await fetch('/api/projects') // Change localhost to server name when deploying
const json = await response.json() // contains array of projects
if (response.ok) {
setProjects(json)
}
}
fetchProjects()
}, [])
return (
<div className="filterHome">
<div className="filterTableContainer">
<div className="filterTableTitle">
Filter Table
</div>
<div className="filterSDGDropDown">
<Dropdown />
</div>
</div>
{/* Lists projects */}
<div>
<div className="projects">
{projects && projects.map((project) => (
<ProjectDetails key={project._id} project={project}/>
))}
</div>
</div>
</div>
)
}
export default FilterBody
Here is the actual filter table, I'm calling this class in Filterpage.js
// Dropdown.js - WHERE THE ACTUAL FILTER TABLE IS
import React, { useEffect, useState } from 'react'
class Dropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
sdg: 'SDG 1: No Poverty',
assignment_type: 1,
theme: 'Demographic'
};
this.handleSDGChange = this.handleSDGChange.bind(this);
this.handleAssignmentChange = this.handleAssignmentChange.bind(this);
this.handleThemeChange = this.handleThemeChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
// Handling all 3 input changes
handleSDGChange(event) {
this.setState({sdg: event.target.value});
}
handleAssignmentChange(event) {
this.setState({assignment_type: event.target.value});
}
handleThemeChange(event) {
this.setState({theme: event.target.value});
}
// Handling all 3 input submissions
handleSubmit(event) {
alert(this.state.sdg + '--- Assignment Type: ' + this.state.assignment_type + '--- Theme: ' + this.state.theme);
event.preventDefault();
// TODO, SEND DATA TO BACKEND TO BE FILTERED
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>SDG:</label>
<select value={this.state.sdg} onChange={this.handleSDGChange}>
<option value="SDG 1: No Poverty">SDG 1: No Poverty</option>
<option value="SDG 2: Zero Hunger">SDG 2: Zero Hunger</option>
<option value="SDG 3: Good Health & Well Being">SDG 3: Good Health & Well Being</option>
</select>
<label>Assignment Type:</label>
<select value={this.state.assignment_type} onChange={this.handleAssignmentChange}>
<option value="1">1: Discussion Project</option>
<option value="2">2: PDF Case study</option>
<option value="3">3: Community Project</option>
</select>
<label>Theme:</label>
<select value={this.state.theme} onChange={this.handleThemeChange}>
<option value="Demographic">Demographic</option>
<option value="Economical">Economical</option>
<option value="Socio-cultural">Socio-cultural</option>
<option value="Technological">Technological</option>
<option value="Ecological">Ecological</option>
<option value="Poltical">Poltical</option>
</select>
<input type="submit" value="Submit" />
</form>
);
}
}
export default Dropdown
Here is my projects.js routes backend code:
const express = require('express')
const {
createProject,
getProject,
getProjects,
deleteProject,
updateProject,
filterProject
} = require('../controllers/projectController')
const router = express.Router()
// GET all workouts
router.get('/', getProjects) // Base route for /api/projects
// FILTER workouts
router.get('/filter', filterProject)
// GET a single workout
router.get('/:id', getProject)
// POST all workouts
router.post('/', createProject)
// DELETE a single workout
router.delete('/:id', deleteProject)
// UPDATE a single workout
router.patch('/:id', updateProject)
module.exports = router
And here is my projectController.js which handles all the requests in the backend (i only included the relevant ones):
const Project = require('../models/projectModel')
const mongoose = require('mongoose')
// get all projects
const getProjects = async (req, res) => {
const projects = await Project.find({}).sort({ createdAt: -1 }) // Specify
// const test = await Project.find({sdg: "SDG 1: No Poverty", assignment_type: 1})
// console.log(test)
res.status(200).json(projects)
}
// filtering a project, calling this everytime filter is changed
const filterProject = async (req, res) => {
const {sdg, assignment_type, theme} = req.body
const filteredProjects = await Project.find({sdg: sdg, assignment_type: assignment_type, theme: theme})
res.status(200).json(filteredProjects)
}
module.exports = {
getProjects,
getProject,
createProject,
deleteProject,
updateProject,
filterProject
}
In addition, is there a way to use react context so that every time the user clicks submit, it will just update the results without refreshing the page?

Queshtion about removing an item for a map

Im having trouble configuring a remove function for my shopping-list project, the purpose of the project is to make a shopping list with a checkbox, a quantity and an item name, but there's another feature that i can't figure out how to add it, i want to a button
( ), that will remove the selected item, now, the item are mapped, which means they are in lines, if i write ("milk", "2") and then ("milk","3"), it will go line after line, like this:
milk - 2
milk - 3.
now, i want to add a delete button, next to every line that is created, that will be able to delete that line which is connected to him, im guessing i need to define an index, and the map function will do it for me, and it will be easier, but i havent found any explanation about it, so, if you can add to the code a remove button, and explain how did u do it, that would be lovely, thanks in advance guys!
import React, { useState } from 'react';
export const ShoppingListPageContainer = () => {
const [item, setItem] = useState('');
const [quantity, setQuantity] = useState('');
const [list, setList] = useState([]);
const add = () => {
const date = { item, quantity };
if (item || quantity) {
setList((ls) => [...ls, date]);
setItem('');
setQuantity('');
}
};
return (
<div>
<label>
<input
name='item'
value={item}
onChange={(e) => setItem(e.target.value)}
/>
<input
type='number'
name='quantity'
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
/>
<button onClick={add}>add</button>
</label>
{list.map((a) => {
return (
<div>
<il>{a.item}</il>
<il>{' - ' + a.quantity + ' '}</il>
<input type='checkbox' />
<button />
</div>
);
})}
</div>
);
};
Steps:
create function which will accept id as parameter and delete the item in list which matches that id. (Note: id should be uniq).
For example:
const deleteItem = (id) => {
//logic delete by id from list
}
Add this button on map and bind id.
For example:
list.map((a)=><div>
<il>{a.item}</il>
<il>{" - "+ a.quantity + " "}</il>
<button onClick={deleteItem.bind(this, a.id)} />
</div>)
By this way you can delete only one item at a time.
By binding ID to function you will call function with binded id only.
I hope this will help you to progress... Best of luck!
export const ShoppingListPageContainer = () => {
const [item, setItem] = useState("");
const [quantity, setQuantity] = useState("");
const [list, setList] = useState([]);
const handleAddItem = () => {
const date = { item, quantity };
if (item || quantity) {
const newList = [...list, date]
setList(newList);
setItem("");
setQuantity("");
}
};
const handleRemoveItem = (index)=>{
const newList = list.filter((item)=>list.indexOf(item) !==index)
setList(newList)
}
return (
<div>
<label>
<input
name="item"
value={item}
onChange={(e) => setItem(e.target.value)}
/>
<input
type="number"
name="quantity"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
/>
<button onClick={handleAddItem}>add</button>
</label>
{list.map((a,i) => (
<div>
<il>{a.item}</il>
<il>{` ${a.quantity} `}</il>
<input type="checkbox" />
<button onClick={()=>{handleRemoveItem(i)}} />
</div>
))}
</div>
);
};
This may help you however if it does not please check the implementation of the filter method
https://www.w3schools.com/jsref/jsref_filter.asp

Button press triggers the last button's press

I'm new to react an am trying to create an app to use in my portfolio. Essentially the program is a menu that has access to different menus(json files: texas_pick.js, breakfast.js...), the program is meant to display the menu options in form of buttons, the buttons' details are retrieved from their respective json file. The problem that I am facing is that when making a click on a menu option the data of the last menu item is retrieved. I programmed the backend to only push the item's name and price to the database, and the frontend, to retrieve this data and display it on a table. The data retrieved is only the last button's and not any others. I believe the problem to possibly be within my button code. Any help/tips/recommendations you could give are greatly appreciated.
I clicked every menu item and only the data from the last one was retrieved
import React from 'react'
import {useEffect,useState} from 'react'
import axios from 'axios'
import Texas_Pick from '../../json_files/texas_pick.json'
import './Mid_Container.css'
function Mid_Container() {
const [items, setItems] = useState(Texas_Pick);
const [order, setOrder] = useState({
item: '',
cost: ''
})
const createOrder = () => {
axios
.post("http://localhost:5000/orders", order)
.then(res => {window.location.reload(false)})
.catch(err => console.error(err));
}
const item1 = items[0];
const item2 = items[1];
const item3 = items[2];
const item4 = items[3];
const item5 = items[4];
const item6 = items[5];
return (
<div className="Mid_Container">
<button
style={{backgroundImage: `url(${item1.image})`}}
value={order.item=item1.item,order.cost=item1.price}
onClick={createOrder}
>
<p id="pPrice">${item1.price}</p>
<p id="pItem" >{item1.item}</p>
</button>
<button
style={{backgroundImage: `url(${item2.image})`}}
value={order.item=item2.item,order.cost=item2.price}
onClick={createOrder}
>
<p id="pPrice">${item2.price}</p>
<p id="pItem" >{item2.item}</p>
</button>
<button
style={{backgroundImage: `url(${item3.image})`}}
value={order.item=item3.item,order.cost=item3.price}
onClick={createOrder}
>
<p id="pPrice">${item3.price}</p>
<p id="pItem" >{item3.item}</p>
</button>
<button
style={{backgroundImage: `url(${item4.image})`}}
value={order.item=item4.item,order.cost=item4.price}
onClick={createOrder}
>
<p id="pPrice">${item4.price}</p>
<p id="pItem" >{item4.item}</p>
</button>
</div>
)
}
export default Mid_Container
I think that you should have this approach:
function SomeComponent() {
// Mocking your datas
const [items, setItems] = React.useState([
{
price: "1",
item: "i am the first",
image: "image1.png",
},
{
price: "7",
item: "I am the second",
image: "image2.png",
},
{
price: "3",
item: "i am the third",
image: "image3.png",
},
]);
const [order, setOrder] = React.useState();
const [myResponse, setMyResponse] = React.useState();
const createOrder = (clickedItem) => {
setOrder(clickedItem);
console.log(clickedItem);
// axios
// .post("http://somewhere", clickedItem)
// .then((res) => {
// setMyResponse(res); // or setMyResponse(res.json());
// })
// .catch((err) => console.error(err));
};
console.log('Log selected order in render loop ==> ', order);
console.log('Log response in render loop ==> ', myResponse);
return (
<div>
<div className="Mid_Container">
{items.length && items.map((currItem, index) => {
return (
<button
key={index}
style={{ backgroundImage: `url(${currItem.image})` }}
onClick={() => createOrder(currItem)}
>
<p id="pPrice">${currItem.price}</p>
<p id="pItem">{currItem.item}</p>
</button>
);
})}
</div>
</div>
);
}
Mapping on your items with map function, and pass the current item to your onClickEvent.
I also think you don't need a value attribute on your buttons. It's also not the place to do operations like you do :)
You also don't have to reload the page in the "then" of your promise. React is made to do SPA (single page application), so in the "then", you can put some code like "setResult(myResponse)" to store in you component the new data you got from your API.

Reserving seats system in react

I am trying to make a reserving seats for my airline website. I have done a reserve seats button, when pressed, a page pops up, where it has the array of current available seats and checkboxes besides it in-order to choose your seats. All of these are going fine, but the thing is that when I checkboxes or remove the checkboxes, I need to save the values that I've checked in another array to send them back to the backend and in the backend, I am going to compare it to the previous array and remove the seats that have been chosen.
function Row(props){
const [AvailableFSeats, setfs] = useState();
const [fList,setfList]= useState([]);
const checkf= [];
useEffect(() => {
setfList(props.row.AvailableFSeats);
},[])
const handleChange = (event) => {
setState({
...state,
[event.target.name]: event.target.checked,
});
//checkf should be the array that contains the chosen seats in the current action.
if(event.target.name==="AvailableFSeats"&&event.target.checked===true){
checkf.push(event.target.label);}
}
const {AvailableFFSeats, AvailableEESeats, AvailableBBSeats} = state;
return(
<Box sx={{ display: 'flex' }}>
<FormControl sx={{ m: 3 }} component="fieldset" variant="standard">
<FormLabel component="legend">First Class Seats</FormLabel>
<FormGroup>
{fList.map(AvailableFSeats => (
<FormControlLabel
control={
<Checkbox checked={AvailableFFSeats} onChange={handleChange} name="AvailableFSeats" />
}
label={AvailableFSeats}
/>)
)}
</FormGroup>
</FormControl>
</Box>
)
}

Use mapping function to render buttons and how can each button works independently in React js

I have 3 sets of button here, I want to disable 'cancel button' after clicking once, and vice versa.
However when I disable the 'cancel' button from first set, the 'cancel' button from other sets will be disabled too.
In this case I want to disable the 'cancel' button from first set only.
How do I solve this issue or is there any approach to do so.
any help and suggestions will be appreciated
note ** I am using Mapping function to render the buttons
my client side:
function App() {
const [taskNumber, setTaskNumber] = useState('')
const [disable, setDisable] = useState(true)
const onChange = (e) => {
setTaskNumber(e.target.value)
}
const onClick = () => {
console.log('world')
setDisable(!disable)
}
const button = (index) => {
return (
< div >
<button onClick={() => onClick()} disabled={!disable}>hello</button>
<button onClick={() => onClick()} disabled={disable}>cancel</button>
</div >
)
}
let items = []
for (let i = 0; i < taskNumber; i++) {
// items.push(button(i))
items.push(i)
}
<Form>
<Form.Group as={Col}>
<Form.Label>Number of Task</Form.Label>
<Form.Control
type="number"
min='1'
placeholder="Enter number of task"
name='taskNumber'
value={taskNumber}
onChange={onChange}
/>
</Form.Group>
</Form>
{items.map((number) => {
return button(number)
})}
My React user Interface
You were close, you can use an array in disable to control which element is enabled.
*** edit ***
I didn't have access to the form components you were using so I just made a more basic example for you to refer to. See my codesandbox:
https://codesandbox.io/s/prod-fast-0zneb?file=/src/App.js

Resources