Unable to pass values from dropdown to componentDidMount function - javascript

In the below code, I am trying to assign the value of ParentId in { ParentId: 'ou-wmno-yeeol4ok' } from the implemented dropdown select instead of getting it hardcoded, but I don't know how to pass this.state.value in componentDidMount() function.
Interestingly if I try to do something like this { ParentId: this.state.value } it doesn't work.
Can someone please take a look and help me out. Thanks.
import React, {Component} from 'react'
import axios from '../../axios'
export default class users extends Component {
constructor(props) {
super(props);
this.state = {
Users: [],
value: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
//alert('Your favorite flavor is: ' + this.state.value);
console.log( this.state.value);
event.preventDefault();
}
componentDidMount(){
axios
.post(`/`, { ParentId: 'ou-wmno-yeeol4ok' })
.then(res => {
const data = res.data
const valuesArray = JSON.parse(data)
console.log(valuesArray)
const users = valuesArray.Accounts.map(u =>
<tr key={u.Id}>
<td>{u.Name}</td>
<td>{u.Arn}</td>
<td>{u.Id}</td>
<td>{u.Email}</td>
<td>{u.JoinedMethod}</td>
<td>{u.JoinedTimestamp}</td>
<td>{u.Status}</td>
</tr>
)
this.setState({
users
})
})
.catch((error) => {
console.log(error)
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<div>
<h1 id='awsorg'>AWS Accounts in Organization</h1>
<div>
<label>
Select AWS Organization
<select id="dropdown" value={this.state.value} onChange={this.handleChange}>
<option value="test-1">test-1</option>
<option value="ou-wmno-yeeol4ok">Suspended</option>
<option value="test-3">test-3</option>
<option value="test-4">test-4</option>
</select>
<input type="submit" value="Submit" />
</label>
</div>
<table id='accounts'>
<tbody>
<tr>
<th>Name</th>
<th>Arn</th>
<th>id</th>
<th>Email</th>
<th>JoinedMethod</th>
<th>JoinedTimestamp</th>
<th>Status</th>
</tr>
{this.state.users}
</tbody>
</table>
</div>
</form>
)
}
}

{ ParentId: 'this.state.value' }
not works because the this.state.value surrounded with this char '
try this
componentDidMount(){
let parentId = this.state.value
axios.post(`/`, { ParentId: parentId })
... rest of the code ..

Related

pass id in react.js to make update view

I have listing view working correctly and I want to pass data to update view by Id - in URL Id is passed correctly, but without data saved to this Id. In console log id is tagged as undefined
UpdateCar.jsx
import React, { Component } from 'react';
import CarServices from '../../Services/CarServices';
class UpdateCar extends Component {
constructor(props) {
super(props)
this.state = {
carId: this.props.match.id,
brand: '',
color: ''
}
this.changeBrandHandler = this.changeBrandHandler.bind(this);
this.changeColorHandler = this.changeColorHandler.bind(this);
this.getCarId = this.getCarId.bind(this);
this.updateCar = this.updateCar.bind(this);
}
componentDidMount() {
CarServices.getCarById(this.state.carId).then((res) => {
let car = res.data;
this.setState({
brand: car.brand,
color: car.color
});
});
}
changeBrandHandler = (event) => {
this.setState({ brand: event.target.value });
}
changeColorHandler = (event) => {
this.setState({ color: event.target.value });
}
updateCar = (e) => {
e.preventDefault();
let car = { brand: this.state.brand, color: this.state.color };
console.log('test: ' + JSON.stringify(car));
console.log('id => ' + JSON.stringify(car.carId));
}
cancel() {
this.props.history.push('/showCars');
}
render() {
return (
<div>
<div className='container'>
<div className='row'>
<div className='card col-md-6 offset-md-3 offset-md-3'>
<h3 className='text-center'> Edit car </h3>
<div className='cardBody'>
<form>
<div className='form-group'>
<label> Brand: </label>
<input placeholder="brand" name="brand" className="form-control"
value={this.state.brand} onChange={this.changeBrandHandler} />
<label> Color: </label>
<input placeholder="color" name="color" className="form-control"
value={this.state.color} onChange={this.changeColorHandler} />
</div>
<button className="btn btn-success" onClick={this.updateCar}>Save</button>
<button className="btn btn-danger" onClick={this.cancel.bind(this)} style={{ marginLeft: "10px" }}>Cancel</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default UpdateCar;
CarServices.js
When I hardcode id in url it works correclty - I don't know why I don't have any data from database in placeholders
import axios from 'axios';
const CAR_API_BASE_URI = "http://localhost:8080/car"
class CarServices{
getCars(){
return axios.get(CAR_API_BASE_URI);
}
addCar(car){
return axios.post(CAR_API_BASE_URI, car);
}
getCarById(id){
return axios.get(CAR_API_BASE_URI + '/' + id);
//return axios.get("http://localhost:8080/car/2"); - correclty view data from database saved with id:2
}
}
export default new CarServices();
ListCar.jsx
import React, { Component } from 'react';
import CarServices from '../../Services/CarServices';
class ListCar extends Component {
constructor(props){
super(props)
this.state = {
cars: []
}
this.addCar = this.addCar.bind(this);
this.editCar = this.editCar.bind(this);
}
addCar(){
this.props.history.push('/addCar');
}
editCar(id){
this.props.history.push(`/editCar/${id}`);
}
componentDidMount(){
CarServices.getCars().then((res)=>{
this.setState({ cars: res.data})
})
}
render() {
return (
<div>
<h2 className='text-center'>Car list </h2>
<div className='row'>
<button className='btn btn-primary' onClick={this.addCar} style={{marginLeft: "15px"}} >Add car</button>
</div>
<div className='row'></div>
<table className='table table-striped table-bordered'>
<thead>
<tr>
<th className='text-center'>Id</th>
<th className='text-center'>brand</th>
<th className='text-center'>color</th>
<th className='text-center'>action</th>
</tr>
</thead>
<tbody>
{
this.state.cars.map(
car =>
<tr key = {car.carId}>
<td className='text-center'>{car.carId}</td>
<td className='text-center'>{car.brand}</td>
<td className='text-center'>{car.color}</td>
<td className='text-center'>
<button onClick ={ () => this.editCar(car.carId)} className="btn btn-info">Update </button>
<button style={{marginLeft: "10px"}} className="btn btn-danger">Delete </button>
<button style={{marginLeft: "10px"}} className="btn btn-info">View </button>
</td>
</tr>
)}
</tbody>
</table>
</div>
);
}
}
export default ListCar;
Assuming the UpdateCar component is correctly rendered on a Route and receives the route props, the issue is likely that this.props.match.id won't necessarily be defined in the constructor when the component is mounting.
If you must reference props in the constructor then reference the passed props argument.
constructor(props) { // <-- reference this props
super(props)
this.state = {
carId: props.match.id, // reference props arg
brand: '',
color: ''
}
...
}
It's better to reference props directly though as it's considered anti-pattern in React to store props into local state.
componentDidMount() {
const { match } = this.props;
if (match.id) {
CarServices.getCarById(match.id)
.then((res) => {
const { brand, color } = res.data;
this.setState({ brand, color });
})
.catch(error => {
// catch and handle any Promise rejections or thrown errors
});
}
}
Don't forget to also handle the id route path parameter changing while the UpdateCar component is mounted.
componentDidUpdate(prevProps) {
const { match } = this.props;
if (prevProps.match.id !== match.id) {
CarServices.getCarById(match.id)
.then((res) => {
const { brand, color } = res.data;
this.setState({ brand, color });
})
.catch(error => {
// catch and handle any Promise rejections or thrown errors
});
}
}

Removing element from table - react

I'm trying to create a CRUD application in react, and I have encountered several problems.
How can I remove an item from the table?
Is it possible to pass id to Info component in render method? How can I later link it to the element?
Why does the e.PreventDefault () method cause an error when I try to delete?
import React, { Component } from 'react';
const Info = ({ index, login, pass }) => (
<>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}{alert(index)}</td>
<td>{login}</td>
<td>{pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</>
);
class List extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
login: "",
pass: "",
};
this.add = this.add.bind(this);
this.show = this.show.bind(this);
this.del = this.show.bind(this);
}
add(e) {
e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
show(e) {
e.preventDefault();
if (!this.state.login.length || !this.state.pass.length) {
return;
}
else {
const newUser = {
login: this.state.login,
pass: this.state.pass,
};
this.setState(state => ({
data: state.data.concat(newUser),
}))
}
}
del(index) {
const tab = this.state.data.filter((temp) => temp.index !== index);
this.setState(({
data: tab
}));
}
render() {
return (
<div>
<form onSubmit={this.show}>
<label>Login</label><br></br><input type='text' name='login' onChange={e => this.add(e)}></input><br></br>
<label>Password</label><br></br><input type='text' name='pass' onChange={e => this.add(e)}></input><br></br>
<input type="submit" value="Add"></input>
</form>
<table>
{this.state.data.map((val, index) => (
<>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}</td>
<td>{val.login}</td>
<td>{val.pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</>
))}
</table>
</div>
)
}
}
export default List;
There are small corrections in your code.
this.del = this.show.bind(this); should be this.del = this.del.bind(this);
You are trying to remove the element from the state data using index (this.state.data.filter((temp) => temp.index !== index);) but the element inside the data doesn't have an index property.
In that case, you can use splice to delete the element from the data.
class List extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
login: "",
pass: "",
};
this.add = this.add.bind(this);
this.show = this.show.bind(this);
this.del = this.del.bind(this);
}
add(e) {
e.preventDefault();
this.setState({
[e.target.name]: e.target.value,
});
}
show(e) {
e.preventDefault();
if (!this.state.login.length || !this.state.pass.length) {
return;
}
else {
const newUser = {
login: this.state.login,
pass: this.state.pass,
};
this.setState(state => ({
data: state.data.concat(newUser),
}))
}
}
del(index) {
let {data}=this.state
data.splice(index, 1);
this.setState(({
data
}));
}
render() {
return (
<div>
<form onSubmit={this.show}>
<label>Login</label><br></br><input type='text' name='login' onChange={e => this.add(e)}></input><br></br>
<label>Password</label><br></br><input type='text' name='pass' onChange={e => this.add(e)}></input><br></br>
<input type="submit" value="Add"></input>
</form>
<table>
{this.state.data.map((val, index) => (
<React.Fragment>
<thead>
<tr>
<th>ID</th>
<th>LOGIN</th>
<th>PASSWORD</th>
</tr>
</thead>
<tbody>
<tr>
<td key={index}>{index}</td>
<td>{val.login}</td>
<td>{val.pass}</td>
</tr>
</tbody>
<input type="submit" value='X' onClick={() => this.del(index)}></input>
</React.Fragment>
))}
</table>
</div>
)
}
}
ReactDOM.render(<List />, document.querySelector("#app"))
Here is the demo jsFiddle
Hope it helps :)

My component (app) not rendering input from a child component(InputForm)

I have a parent component App rendering a list of new restaurants from a child component InputForm.
I have a addedrestaurant state inside App and a handler to save the input from a callback props passed to the child component InputForm.
I have console.log the restaurant attribute in the InputForm component, it is always empty even if I have user input in the form and have handlers for change in the component.
class App extends React.Component {
constructor(props) {
super(props)
this.handlerestaurantclick = this.handlerestaurantclick.bind(this)
this.saveRating = this.saveRating.bind(this)
this.saveRestaurant = this.saveRestaurant.bind(this)
this.state = {
restaurants: restaurants,
addedrestaurants: [],
showcomponent: false,
restaurantClicked: -1,
}
}
saveRestaurant(restaurant) {
this.setState(
(prevState) => {
let resto = prevState.addedrestaurants;
resto.push(restaurant);
return { resto };
})
console.log("after:" + this.state.addedrestaurants)
}
render() {
return <Inputform onSave={this.saveRestaurant} />
}
}
class Inputform extends React.Component {
constructor(props) {
super(props);
this.handlechange = this.handlechange.bind(this);
this.handleSave = this.handleSave.bind(this);
this.state = {
restaurant: Object.assign({}, Init_value),
error: {}
}
}
handlechange(e) {
const name = e.target.name;
const value = e.target.value;
this.setState((prevState) => {
prevState.restaurant[name] = value;
return { restaurant prevState.restaurant };
})
}
handleSave = (e) => {
this.props.onSave(this.state.restaurant);
this.setState({
restaurant: Object.assign({}, Init_value),
error: {}
})
e.preventDefault()
}
render() {
return (
<form className="inputform">
<div>
<h4>
Add new Restaurant
<FontAwesomeIcon icon={faBars} />
</h4>
</div>
<div className="inputcontainer ">
<input className="InputItem restaurant-name" type="text" name="restaurantName" placeholder="Name" value={this.state.restaurant.restaurantName} onChange={this.handlechange} />
</div>
<div className="inputcontainer adress">
<textarea className="InputItem" name="address" rows="4" cols="18" placeholder="Adress" value={this.state.restaurant.address} onChange={this.handlechange}>
</textarea>
</div>
<div className="inputcontainer rating">
Rating
<select >
<option> </option>
<option >0 </option>
<option >1</option>
<option>2</option>
<option>3</option>
<option>4</option><option>5</option>
</select>
</div>
<div className="inputcontainer">
<textarea className="InputItem" rows="4" cols="18" placeholder="comment"> </textarea>
</div>
<input className="inputitem submitbutton" type="submit" value="submit" onClick={this.handleSave} />
</form>
)
}
}
You made couple of mistakes. I have mention it in the below code as #cluemediator Fixed.
import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";
import "./style.css";
class App extends React.Component {
constructor(props) {
super(props)
// #cluemediator Fixed: Remove both line because method is not exist.
// this.handlerestaurantclick = this.handlerestaurantclick.bind(this)
// this.saveRating = this.saveRating.bind(this)
this.saveRestaurant = this.saveRestaurant.bind(this)
this.state = {
restaurants: [], // #cluemediator Fixed: remove "restaurants" because "restaurants" is not defined.
addedrestaurants: [],
showcomponent: false,
restaurantClicked: -1,
}
}
saveRestaurant(restaurant) {
this.setState(
(prevState) => {
let resto = prevState.addedrestaurants; resto.push(restaurant); return { resto };
})
console.log("after:" + this.state.addedrestaurants)
}
render() {
return <Inputform onSave={this.saveRestaurant} />
}
}
class Inputform extends React.Component {
constructor(props) {
super(props);
this.handlechange = this.handlechange.bind(this);
this.handleSave = this.handleSave.bind(this);
const Init_value = {}; // #cluemediator Fixed: define variable because it's used at below
this.state = {
restaurant: Object.assign({}, Init_value),
error: {}
}
}
handlechange(e) {
const name = e.target.name;
const value = e.target.value;
this.setState((prevState) => {
prevState.restaurant[name] = value;
return { restaurant: prevState.restaurant }; // #cluemediator Fixed: Add colon symbol
})
}
handleSave = (e) => {
this.props.onSave(this.state.restaurant);
this.setState({
restaurant: Object.assign({}, Init_value),
error: {}
})
e.preventDefault()
}
render() {
return (
<form className="inputform">
<div>
<h4>
Add new Restaurant
<FontAwesomeIcon icon={faBars} />
</h4>
</div>
<div className="inputcontainer ">
<input className="InputItem restaurant-name" type="text" name="restaurantName" placeholder="Name" value={this.state.restaurant.restaurantName} onChange={this.handlechange} />
</div>
<div className="inputcontainer adress">
<textarea className="InputItem" name="address" rows="4" cols="18" placeholder="Adress" value={this.state.restaurant.address} onChange={this.handlechange}>
</textarea>
</div>
<div className="inputcontainer rating">
Rating
<select >
<option> </option>
<option >0 </option>
<option >1</option>
<option>2</option>
<option>3</option>
<option>4</option><option>5</option>
</select>
</div>
<div className="inputcontainer">
<textarea className="InputItem" rows="4" cols="18" placeholder="comment"> </textarea>
</div>
<input className="inputitem submitbutton" type="submit" value="submit" onClick={this.handleSave} />
</form>
)
}
}
render(<App />, document.getElementById("root"));
Hope this will work for you!

Reactjs: Warning: A component is changing a controlled

I am writing a react crud app, my crud is working nice but it has an console error and below this:
Warning: A component is changing a controlled input of type text to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info:
I tried a lot reading too many thing on stackoverflow, can anyone help me please?
this is my home.js file:
import React from "react"
import Table from "./table"
import Form from "./form"
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
current: 'SAVE', // button name
employees: [{name: 'jhon', age: '23', email: 'a#a'}, {name: 'doe', age: '24', email: 'b#a'}],
currentEmp: {},
isFormVisible: false
};
this.onSubmit = this.onSubmit.bind(this);
this.onDelete = this.onDelete.bind(this);
this.setIndex = this.setIndex.bind(this);
}
onSubmit(name, age, email, index=null) {
if(!index && this.state.current == 'SAVE'){
this.setState({ employees: [...this.state.employees, { name: name, age: age, email: email }] });
}
else if(this.state.current == 'Update'){
var emp = this.state.employees;
emp[this.state.index].name = name; //use index from state
emp[this.state.index].age = age;
emp[this.state.index].email = email;
this.setState({
currentEmp: {},
employees: emp,
current: 'SAVE'
});
}
else{
this.setState({
currentEmp: {},
current: 'SAVE',
});
}
};
setIndex(index){
var emp = this.state.employees[index];
emp.index = index;
this.setState({
currentEmp: emp,
current: 'Update',
index //set index in state
});
}
// delete employee
onDelete(event, index) {
this.setState({
employees: this.state.employees.filter((item, itemIndex) => (index != itemIndex)),
});
};
render() {
return (
<React.Fragment>
<h1>Employee Information System</h1>
{this.state.isFormVisible && <div>
<Form
currentEmp={this.state.currentEmp}
submitMe={this.onSubmit}
currentButtonName={this.state.current} />
</div>
}
<button onClick={() => this.setState({isFormVisible: true})}>ADD NEW</button>
<hr/>
<table className="table table-striped table-dark">
<Table onUpdateTry={this.edit} editThis={this.setIndex} employees={this.state.employees} deleteMe={this.onDelete} />
</table>
<p className="test">Ignore this please ! Just showed if sass works or not</p>
</React.Fragment>
);
}
}
export default Home;
and this is my form.js file
import React, { Fragment } from "react"
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {name: '', age: '', email: ''};
this.onHandleChange = this.onHandleChange.bind(this);
this.submit = this.submit.bind(this);
}
submit(event, name, age, email) {
if (this.props.submitMe) {
this.props.submitMe(name, age, email);
}
this.setState({name: '', age: '', email: ''}); // clear form after click on submit
}
onHandleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
componentDidUpdate(prevProps){
if(prevProps.currentEmp != this.props.currentEmp){
this.setState({
index: this.props.currentEmp.index,
name: this.props.currentEmp.name,
age: this.props.currentEmp.age,
email: this.props.currentEmp.email,
});
}
}
render() {
return (
<form>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.name} name="name" type="text" />
</div>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.age} name="age" type="number"/>
</div>
<div className="form-group">
<input onChange={(event) => this.onHandleChange(event)} value={this.state.email} name="email" type="text"/>
</div>
<button onClick={(event) => this.submit(event, this.state.name, this.state.age, this.state.email)} type="button">{this.props.currentButtonName}</button>
<button onClick={() => this.setState({isFormVisible: false})}>HIDE ME</button>
</form>
);
}
}
export default Form;
and this is my table.js file:
import React, {Fragment} from "react"
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
employees: this.props.employees
};
//this.onDelete = this.onDelete.bind(this);
this.onEdit = this.onEdit.bind(this);
}
onEdit(event, index){
if(this.props.editThis){
this.props.editThis(index);
}
}
render() {
return (
<Fragment>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
<th scope="col">EDIT</th>
<th scope="col">DELETE</th>
</tr>
</thead>
<tbody>
{this.props.employees.map((item, index) => (
<tr key={index}>
<td>{item.name}</td>
<td>{item.age}</td>
<td>{item.email}</td>
<td>
<button
type="button"
onClick={(event) => this.onEdit(event, index)}
className="btn btn-primary btn-sm">EDIT
</button>
</td>
<td>
<button
onClick={(event) => this.props.deleteMe(event, index)}
type="button" className="btn btn-danger btn-sm">DELETE
</button>
</td>
</tr>
))}
</tbody>
</Fragment>
);
}
}
export default Table;
The error occurs only when i add something or click on SAVE buttion or update button. Can anyone help me in this case?
Your problem is with this,
currentEmp: {}
You are setting currentEmp to blank object, and in Form component using this object to set state in componentDidUpdate, in result state in Form component is not getting values.
Also don't mutate state directly.
You can set your currentEmp to empty value object, and your state updation should be,
this.setState({
employees: this.state.employees.map((emp,index) => index === this.state.index ? {name,age,email} : emp),
current: 'SAVE',
currentEmp:{name:'',age:'',email:''}
});
Also in your Form component, in submit function you are doing this,
this.setState({name: '', age: '', email: ''});
which is not needed when you are setting currentEmp:{name:'',age:'',email:''}. Your componentDidUpdate method will take care of this.
Demo
Your problem is in your onSubmit method. You are resetting your currentEmp to {} and using it in your Form component. So, when you reset it affects your Form component and all the values become null there. So, you can skip this step maybe?
this.setState({
employees: emp,
current: "SAVE"
});
Also, I couldn't look so carefully but probably you are mutating your state directly in many places. For example in the update part.
var emp = this.state.employees;
emp[this.state.index].name = name; //use index from state
This is a mutation. Assigning an object to a new one just do this by reference. So, when you change a property in the new one then it changes the original one. Maybe something like that works:
const emp = this.state.employees.map((el, i) => {
const { index } = this.state;
const curEmp = this.state.employees[index];
if (i !== index) return el;
return { ...curEmp, name, age, email };
})
Have you tried to read properties in the submit function?
Like:
submit() {
const { name, age, email } = this.state;
if (this.props.submitMe) {
this.props.submitMe(name, age, email);
}
this.setState({name: '', age: '', email: ''}); // clear form after click on submit
}

React - not refresh page after post with error response

I have application, which fetches data from the server, which is written in nodeJS.
Using componentDidMount i fetch the data. On page is input for name a table with data and every row has checkbox. When I click on button 'send', selected rows are send on backend. On backend I validate unique name. If is not, I return error. But fronted is every time refreshed. And is not possible get error message.
import React, {Component} from 'react';
import axios from 'axios';
import MyNavbar from "./MyNavbar";
class Offer extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleCheckedOrder = this.handleCheckedOrder.bind(this);
this.state = {
offers: [],
name: '',
selectedFoods: [],
selectedBuild: 'Nevybráno',
isOrderChecked: false
};
}
componentDidMount() {
this.getOffer();
}
getOffer() {
const url = '/offer';
axios.get(url).then(response => {
this.setState({offers: response.data})
}).catch(() => 'Cannot load menu');
};
handleNameChange = evt => {
this.setState({name: evt.target.value});
};
handleChecboxChange = offer => {
if (this.state.selectedFoods.includes(offer)) {
this.setState({selectedFoods: this.state.selectedFoods.filter(item => item !== offer)});
} else {
this.setState({selectedFoods: [...this.state.selectedFoods, offer]});
}
};
handleCheckedOrder() {
this.setState({isChecked: !this.state.isChecked});
}
isValid() {
let isEnabledSubmit = this.state.name.length > 0;
let isSelectedFoodAndNotOnlySoap = this.state.selectedFoods.length > 0 && this.state.selectedFoods.some(food => food.index !== 0);
let isSelectedBuild = this.state.selectedBuild !== 'Nevybráno';
return isEnabledSubmit && isSelectedFoodAndNotOnlySoap && isSelectedBuild;
}
handleSubmit() {
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
});
};
render() {
const {offers} = this.state;
const options = ["Nevybráno", "A", "B"];
return (
<div>
<MyNavbar/>
<div className="container">
<form className="form-inline justify-content-center" onSubmit={this.handleSubmit}>
<table className="table">
<tbody>
<tr>
<th> </th>
<th>#</th>
<th>Váha</th>
<th>Menu</th>
<th>Cena</th>
</tr>
{offers.map((offer) => {
return (
<tr key={offer.index}>
<td style={{width: '5%'}}>
<input type="checkbox" className="checkbox"
onChange={this.handleChecboxChange.bind(this, offer)}/>
</td>
<td style={{width: '5%'}}>{offer.index}</td>
<td style={{width: '10%'}}>{offer.weight}g</td>
<td style={{width: '70%'}}>{offer.name}</td>
<td style={{width: '20%'}}>{offer.discount} Kč</td>
</tr>
)
})}
</tbody>
</table>
<label className="sr-only" htmlFor="inlineFormInput">Name</label>
<input type="text" className="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput"
placeholder="Jméno" onChange={this.handleNameChange}/>
<label className="mr-sm-2" htmlFor="inlineFormCustomSelect">Budova</label>
<select className="custom-select mb-2 mr-sm-2 mb-sm-0" id="inlineFormCustomSelect"
onChange={(e) => this.setState({selectedBuild: e.target.value})}>
{options.map(option => {
return <option value={option} key={option}>{option}</option>
})}
</select>
<div className="form-check mb-2 mr-sm-2 mb-sm-0">
<label className="form-check-label">
<input className="form-check-input" type="checkbox"
onChange={this.handleCheckedOrder}/> Objednám
</label>
</div>
<button type="submit" className="btn btn-secondary"
disabled={!this.isValid()}>Odeslat
</button>
</form>
</div>
</div>
);
}
}
export default Offer;
This is because the button submits the form and refreshes the page by default. This can be prevented by using evt.preventDefault();
handleSubmit(evt) {
evt.preventDefault();
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
});
};
In addition to what maartendev's comment, to get the errors and result in component state you can write the handler as:
handleSubmit(evt) {
evt.preventDefault();
axios({
method: 'post',
url: '/order',
headers: {},
data: {
name: this.state.name,
food: this.state.selectedFoods,
order: this.state.isChecked,
build: this.state.selectedBuild
}
}).catch(({ response }) => this.setState({ errors: response.data }));
}
This will give you errors in this.state.errors which can be used in render method.
Try to add it in the form submit function evt.preventDefault();}
handleSubmit=(eve)=>
{
evt.preventDefault();
}
Tell me if it works or not.

Categories

Resources