Doing real-time calculations in a form in react js components - javascript

I'm a new user to React and I'm having trouble with my app.. Basically I want to do some calculation when the user input some values it dynamically outputs the amount. The calculation should add the packaging amt with transport amt and subtract the discount amt, the result is then added to the product of kgs with price per kg to show the total amt. . If anyone can help me with this it would be very much appreciated. My code is included below `
import React from "react";
import APIHandler from "../utils/APIHandler";
import { Link } from "react-router-dom";
import AutoCompleteCustomer from "../components/AutoCompleteCustomer";
class HomeComponent extends React.Component {
constructor(props) {
super(props);
this.formSubmit = this.formSubmit.bind(this);
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
farmerlist: [],
customersDetails: [{
phone: "",
name: "",
}],
dataLoaded: false,
value: ""
};
async formSubmit(event) {
event.preventDefault();
this.setState({ btnMessage: 1 });
var apiHandler = new APIHandler();
var response = await apiHandler.saveOrdersData(
event.target.phone.value,
event.target.id.value,
event.target.town.value,
event.target.region.value,
event.target.kgs.value,
event.target.packaging.value,
event.target.discount.value,
event.target.transport.value,
event.target.comment.value,
event.target.farmer_id.value,
event.target.price.value,
event.target.amount.value,
);
console.log(response);
this.setState({ btnMessage: 0 });
this.setState({ errorRes: response.data.error });
this.setState({ errorMessage: response.data.message });
this.setState({ sendData: true });
}
//This Method Work When Our Page is Ready
componentDidMount() {
this.LoadFarmer();
}
async LoadFarmer() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerOnly();
this.setState({ farmerlist: farmerdata.data });
}
showDataInInputs = (index, item) => {
console.log(index);
console.log(item);
this.setState.customersDetails[index].phone = item.phone;
this.setState.customersDetails[index].id = item.id;
}
viewRequestDetails = (request_id) => {
console.log(request_id);
console.log(this.props);
this.props.history.push("/ordersDetails/" + request_id);
};
qtyChangeUpdate = (event) => {
var value = event.target.value;
this.state.total =
((parseInt(this.state.packaging) +
parseInt(this.state.transport) -
parseInt(this.state.discount)) +
(parseInt(this.state.kgs) * parseInt(this.state.price))) * value;
this.state.amount = value;
this.setState({});
};
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>MANAGE ORDERS & CUSTOMERS</h2>
</div>
<div className="row clearfix">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>Add Order</h2>
<ul className="header-dropdown m-r--5">
<Link to="/addcustomer" className="toggled waves-effect waves-block">
<button className="btn btn-primary m-r-15 waves-effect">
Add Customer
</button>
</Link>
</ul>
</div>
<div className="body">
<form onSubmit={this.formSubmit}>
{this.state.customersDetails.map((item, index) => (
<div className="row" key={index}>
<div className="col-lg-6">
<label htmlFor="email_address">
Phone No.{" "}
</label>
<div className="form-group">
<div className="form-line">
<AutoCompleteCustomer
itemPostion={index}
showDataInInputs={this.showDataInInputs}
/>
</div>
</div>
</div>
<div className="col-lg-6">
<label htmlFor="email_address">Customer Name</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="id"
name="id"
className="form-control"
placeholder="Enter Customer Name"
defaultValue={item.id}
data-index={index}
/>
</div>
</div>
</div>
</div>
))}
<div className="row">
<div className="col-lg-4">
<label htmlFor="email_address">Town</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="town"
name="town"
className="form-control"
placeholder="Enter Customer Town"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Region</label>
<div className="form-group">
<div className="form-line">
<select id="region" name="region" className="form-control show-tick">
<option value="1">Nairobi</option>
<option value="2">Nyanza</option>
<option value="3">Central</option>
<option value="4">Coast</option>
<option value="5">Eastern</option>
<option value="6">North Eastern</option>
<option value="7">Western</option>
<option value="8">Rift Valley</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Kgs : </label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="kgs"
name="kgs"
className="form-control"
placeholder="Enter Quantity."
defaultValue={this.state.kgs}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Packaging</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="packaging"
name="packaging"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.packaging}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Discount.</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="discount"
name="discount"
className="form-control"
placeholder="Enter Discount."
defaultValue={this.state.discount}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Transport</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="transport"
name="transport"
className="form-control"
placeholder="Enter Transport."
defaultValue={this.state.transport}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Comment</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="comment"
name="comment"
className="form-control"
placeholder="Enter Comment"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Farmer Name</label>
<div className="form-group">
<select className="form-control show-tick"
id="farmer_id"
name="farmer_id"
>
{this.state.farmerlist.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Price per Kg</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="price"
name="price"
className="form-control"
placeholder="Enter Price"
defaultValue={this.state.price}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Amount</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="amount"
name="amount"
className="form-control"
placeholder="Enter Amount"
value={this.state.amount}
onChange={this.qtyChangeUpdate}
/>
</div>
</div>
</div>
</div>
<br />
<button
type="submit"
className="btn btn-success m-t-15 waves-effect "
disabled={this.state.btnMessage === 0 ? false : true}
>
{this.state.btnMessage === 0
? "Add Order"
: "Adding Order Please Wait.."}
</button>
<br />
{this.state.errorRes === false &&
this.state.sendData === true ? (
<div className="alert alert-success">
<strong>Success!</strong> {this.state.errorMessage}.
</div>
) : (
""
)}
{this.state.errorRes === true &&
this.state.sendData === true ? (
<div className="alert alert-danger">
<strong>Failed!</strong>
{this.state.errorMessage}.
</div>
) : (
""
)}
</form>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default HomeComponent;

I managed to get this working by using setState an binding event to the form
import React from "react";
import APIHandler from "../utils/APIHandler";
import { Link } from "react-router-dom";
import AutoCompleteCustomer from "../components/AutoCompleteCustomer";
class HomeComponent extends React.Component {
constructor(props) {
super(props);
this.formSubmit = this.formSubmit.bind(this);
this.updateKgs = this.updateKgs.bind(this);
this.updatePackaging = this.updatePackaging.bind(this);
this.updateDiscount = this.updateDiscount.bind(this);
this.updateTransport = this.updateTransport.bind(this);
this.updatePrice = this.updatePrice.bind(this);
this.formRef = React.createRef();
}
state = {
errorRes: false,
errorMessage: "",
btnMessage: 0,
sendData: false,
farmerlist: [],
kgs: "",
price: "",
packaging: "",
discount: "",
transport: "",
amount: "",
customersDetails: [
{
id: 0,
phone: "",
name: "",
customer_id: "",
},
],
dataLoaded: false,
};
async formSubmit(event) {
event.preventDefault();
this.setState({ btnMessage: 1 });
var apiHandler = new APIHandler();
var response = await apiHandler.saveOrdersData(
event.target.phone.value,
event.target.name.value,
event.target.customer_id.value,
event.target.town.value,
event.target.region.value,
event.target.kgs.value,
event.target.packaging.value,
event.target.discount.value,
event.target.transport.value,
event.target.comment.value,
event.target.farmer_id.value,
event.target.rice_type.value,
event.target.price.value,
event.target.amount.value,
);
console.log(response);
this.setState({ btnMessage: 0 });
this.setState({ errorRes: response.data.error });
this.setState({ errorMessage: response.data.message });
this.setState({ sendData: true });
this.formRef.current.reset();
}
//This Method Work When Our Page is Ready
componentDidMount() {
this.LoadFarmer();
}
async LoadFarmer() {
var apihandler = new APIHandler();
var farmerdata = await apihandler.fetchFarmerOnly();
this.setState({ farmerlist: farmerdata.data });
}
showDataInInputs = (index, item) => {
console.log(index);
console.log(item);
this.state.customersDetails[index].id = item.id;
this.state.customersDetails[index].phone = item.phone;
this.state.customersDetails[index].name = item.name;
this.state.customersDetails[index].customer_id = item.id;
this.setState({})
}
updateKgs = (event) => {
this.setState({
kgs: event.target.value
});
}
updatePackaging = (event) => {
this.setState({
packaging: event.target.value
});
console.log(this.state.packaging)
}
updateDiscount = (event) => {
this.setState({
discount: event.target.value
});
}
updateTransport = (event) => {
this.setState({
transport: event.target.value
});
}
updatePrice = (event) => {
this.setState({
price: event.target.value
});
}
updateAmount = () => {
this.setState({
amount: (Number(this.state.kgs) * Number(this.state.price)) + Number(this.state.packaging) + Number(this.state.transport) - Number(this.state.discount)
});
}
render() {
return (
<section className="content">
<div className="container-fluid">
<div className="block-header">
<h2>ADD ORDERS & CUSTOMERS</h2>
</div>
<div className="row clearfix">
<div className="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div className="card">
<div className="header">
<h2>Add Order</h2>
<ul className="header-dropdown m-r--5">
<Link to={"/addcustomer"} className="toggled waves-effect waves-block">
<button className="btn btn-primary m-r-15 waves-effect">
Add Customer
</button>
</Link>
</ul>
</div>
<div className="body">
<form onSubmit={this.formSubmit} ref={this.formRef}>
{this.state.customersDetails.map((item, index) => (
<div className="row" key={index}>
<div className="col-lg-6">
<label htmlFor="email_address">
Phone No.{" "}
</label>
<div className="form-group">
<div className="form-line">
<AutoCompleteCustomer
itemPostion={index}
showDataInInputs={this.showDataInInputs}
/>
</div>
</div>
</div>
<div className="col-lg-5">
<label htmlFor="email_address">Customer Name</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="name"
name="name"
className="form-control"
placeholder="Enter Customer Name"
defaultValue={item.name}
/>
</div>
</div>
</div>
<div className="col-sm-1">
<label htmlFor="email_address">No</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="customer_id"
name="customer_id"
className="form-control"
placeholder=""
value={item.customer_id}
/>
</div>
</div>
</div>
</div>
))}
<div className="row">
<div className="col-lg-4">
<label htmlFor="email_address">Town</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="town"
name="town"
className="form-control"
placeholder="Enter Customer Town"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Region</label>
<div className="form-group">
<div className="form-line">
<select id="region" name="region" className="form-control show-tick">
<option value="1">NAIROBI</option>
<option value="2">NYANZA</option>
<option value="3">CENTRAL</option>
<option value="4">COAST</option>
<option value="5">EASTERN</option>
<option value="6">NORTH EASTERN</option>
<option value="7">WESTERN</option>
<option value="8">RIFT VALLEY</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Kgs : </label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="kgs"
name="kgs"
className="form-control"
placeholder="Enter Quantity."
defaultValue={this.state.kgs}
onChange={this.updateKgs}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Packaging</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="packaging"
name="packaging"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.packaging}
onChange={this.updatePackaging}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Discount.</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="discount"
name="discount"
className="form-control"
placeholder="Enter Discount."
defaultValue={this.state.discount}
onChange={this.updateDiscount}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Transport</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="transport"
name="transport"
className="form-control"
placeholder="Enter Transport."
defaultValue={this.state.transport}
onChange={this.updateTransport}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Comment</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="comment"
name="comment"
className="form-control"
placeholder="Enter Comment"
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Farmer Name</label>
<div className="form-group">
<select className="form-control show-tick"
id="farmer_id"
name="farmer_id"
>
{this.state.farmerlist.map((item) => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Rice Type</label>
<div className="form-group">
<div className="form-line">
<select id="rice_type" name="rice_type" className="form-control show-tick">
<option value="1">Pishori</option>
<option value="2">Komboka</option>
</select>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Price per Kg</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="price"
name="price"
className="form-control"
placeholder="Enter Price"
defaultValue={this.state.price}
onChange={this.updatePrice}
/>
</div>
</div>
</div>
<div className="col-lg-4">
<label htmlFor="email_address">Amount</label>
<div className="form-group">
<div className="form-line">
<input
type="text"
id="amount"
name="amount"
className="form-control"
placeholder="Enter Amount"
defaultValue={this.state.amount}
onClick={this.updateAmount}
/>
</div>
</div>
</div>
</div>
<br />
<button
type="submit"
className="btn btn-success m-t-15 waves-effect "
disabled={this.state.btnMessage === 0 ? false : true}
>
{this.state.btnMessage === 0
? "Add Order"
: "Adding Order Please Wait.."}
</button>
<br />
{this.state.errorRes === false &&
this.state.sendData === true ? (
<div className="alert alert-success">
<strong>Success!</strong> {this.state.errorMessage}.
<Link to="/orders" className="btn btn-info">View Orders</Link>
</div>
) : (
""
)}
{this.state.errorRes === true &&
this.state.sendData === true ? (
<div className="alert alert-danger">
<strong>Failed!</strong>
{this.state.errorMessage}.
</div>
) : (
""
)}
</form>
</div>
</div>
</div>
</div>
</div>
</section>
);
}
}
export default HomeComponent;
Hope this helpful to anyone facing a similar problem..

Related

how to read function outside useEffect in react | not working onclick button

I wrote the Code and it has a separate script file, but when I click on the button next or before, the nextPrev does not work , I have put all the JS codes into the useEffect and I don't know if this method is correct or not
i can't read function inside in useEffect and show me this error:
‍‍‍‍‍‍Line 174:57: 'nextPrev' is not defined no-undef
const AddTest = () => {
useEffect(()=>{
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
},[])
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input type="text" className="form-control" id="validationCustom01" placeholder="First name" required />
</div>
<div className="col-md-6 mb-3">
<input type="text" className="form-control" id="validationCustom02" placeholder="Last name" required />
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input type="text" className="form-control" id="validationCustom01" placeholder="First name" required />
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">درصد افیلیت</label>
<p className="text-muted">درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده شود را تعیین کنید.</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline1" name="customRadioInline1" className="custom-control-input" />
<label className="custom-control-label" for="customRadioInline1">5 درصد</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input type="radio" id="customRadioInline2" name="customRadioInline1" className="custom-control-input" />
<label className="custom-control-label" for="customRadioInline2">10 درصد</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input type="email" placeholder="Email Address" oninput="this.className = ''" name="email" />
</div>
<div className="mb-3">
<input type="password" placeholder="Password" oninput="this.className = ''" name="password" />
</div>
<div className="mb-3">
<input type="password" placeholder="Confirm Password" oninput="this.className = ''" name="password" />
</div>
</div>
<div className="step">
<p className="text-center mb-4">Your presence on the social network</p>
<div className="mb-3">
<input type="text" placeholder="Linked In" oninput="this.className = ''" name="linkedin" />
</div>
<div className="mb-3">
<input type="text" placeholder="Twitter" oninput="this.className = ''" name="twitter" />
</div>
<div className="mb-3">
<input type="text" placeholder="Facebook" oninput="this.className = ''" name="facebook" />
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input type="text" placeholder="Full name" oninput="this.className = ''" name="fullname" />
</div>
<div className="mb-3">
<input type="text" placeholder="Mobile" oninput="this.className = ''" name="mobile" />
</div>
<div className="mb-3">
<input type="text" placeholder="Address" oninput="this.className = ''" name="address" />
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onClick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onClick="nextPrev(1)">Next</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
Respectfully, your code is quite confusing to read. If you are using React, then use React! Someone else provided you with a Code Sandbox, but here is yet another.
Pay attention at how, with React, you have no need to use document.getElementById, etc. If you need a reference to a DOMElement, then use useRef (e.g. <div ref={ ref } ... />, accessible via ref.current).
import { useState } from "react";
import classnames from "classnames";
const DEFAULT_FORM_DATA = {
firstName: "",
lastName: "",
companyName: "",
notes: "",
radioValue: 0, // ????
email: "",
password: "",
passwordConfirm: "",
fullname: "",
address: "",
mobile: "",
linkedin: "",
twitter: "",
facebook: ""
};
const AddTest = () => {
// Current tab is set to be the first tab (0)
const [currentTab, setCurrentTab] = useState(0);
const [formData, setFormData] = useState(DEFAULT_FORM_DATA);
const [formValid, setFormValid] = useState({});
const handleInputChange = (e) => {
const key = e.target.name;
const value = e.target.value;
const valid = value !== "";
setFormValid((formValid) => ({ ...formValid, [key]: valid }));
setFormData((formData) => ({ ...formData, [key]: value }));
};
const handlePreviousTab = () =>
setCurrentTab((currentTab) => Math.max(currentTab - 1, 0));
const handleNextTab = () =>
setCurrentTab((currentTab) => Math.min(currentTab + 1, 3));
const handleSubmit = () => {
console.log("TODO : submit formData = ", formData);
};
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span
className={classnames("stepIndicator", {
active: currentTab === 0
})}
>
تنظیمات
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 1
})}
>
سوالات
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 2
})}
>
تفسیر
</span>
<span
className={classnames("stepIndicator", {
active: currentTab === 3
})}
>
پیش نمایش
</span>
</div>
<div
className="step"
style={{ display: currentTab === 0 ? "" : "none" }}
>
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.firstName === false
})}
name="firstName"
placeholder="First name"
required
value={formData.firstName}
onChange={handleInputChange}
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.lastName === false
})}
name="lastName"
placeholder="Last name"
required
value={formData.lastName}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea
className="form-control"
name="notes"
value={formData.notes}
onChange={handleInputChange}
></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className={classnames("form-control", {
invalid: formValid.firstName === false
})}
id="companyName"
name="companyName"
placeholder="Company name"
required
value={formData.companyName}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-group">
<label
htmlFor="companyName"
className="font-weight-bold text-right"
>
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="radioValue5"
name="radioValue"
className="custom-control-input"
value={5}
checked={formData.radioValue === "5"}
onChange={handleInputChange}
/>
<label className="custom-control-label" htmlFor="radioValue5">
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="radioValue10"
name="radioValue"
className="custom-control-input"
value={10}
checked={formData.radioValue === "10"}
onChange={handleInputChange}
/>
<label
className="custom-control-label"
htmlFor="radioValue10"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 1 ? "" : "none" }}
>
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
onInput={(e) => (e.target.className = "")}
name="email"
value={formData.email}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
onInput={(e) => (e.target.className = "")}
name="password"
value={formData.password}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
onInput={(e) => (e.target.className = "")}
name="passwordConfirm"
value={formData.passwordConfirm}
onChange={handleInputChange}
/>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 2 ? "" : "none" }}
>
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
onInput={(e) => (e.target.className = "")}
name="linkedin"
value={formData.linkedin}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
onInput={(e) => (e.target.className = "")}
name="twitter"
value={formData.twitter}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
onInput={(e) => (e.target.className = "")}
name="facebook"
value={formData.facebook}
onChange={handleInputChange}
/>
</div>
</div>
<div
className="step"
style={{ display: currentTab === 3 ? "" : "none" }}
>
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
onInput={(e) => (e.target.className = "")}
name="fullname"
value={formData.fullname}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
onInput={(e) => (e.target.className = "")}
name="mobile"
value={formData.mobile}
onChange={handleInputChange}
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
onInput={(e) => (e.target.className = "")}
name="address"
value={formData.address}
onChange={handleInputChange}
/>
</div>
</div>
<div className="form-footer d-flex">
<button
type="button"
id="prevBtn"
onClick={handlePreviousTab}
style={{ display: currentTab > 0 ? "" : "none" }}
>
Previous
</button>
<button
type="button"
id="nextBtn"
onClick={currentTab === 3 ? handleSubmit : handleNextTab}
>
{currentTab === 3 ? "Submit" : "Next"}
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
Consider watching or reading some tutorials on using React, and then try to adopt best practices when using the framework. This will not only make your code easier to read for others, it will help you actually use the framework how it is intended.
Note
The "next" button may become a submit button if you want to submit the form through the browser instead of manually handling it. If this is the intention, you could change the button with
<button
type={ currentTab === 3 ? "submit", : "button" }
id="nextBtn"
onClick={currentTab === 3 ? null : handleNextTab}
>
{currentTab === 3 ? "Submit" : "Next"}
</button>
Try this, I set currentTab as a state so I think you don't need to worry about useEffect:
import { useState } from "react";
const AddTest = () => {
const [currentTab, setCurrentTab] = useState(0);
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == x.length - 1) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n);
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
setCurrentTab(currentTab + n);
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x,
y,
i,
valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className +=
" finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i,
x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
useEffect(() => {
showTab(currentTab); // Display the current tab
}, []);
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom02"
placeholder="Last name"
required
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline1"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline1"
>
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline2"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline2"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
oninput="this.className = ''"
name="email"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
oninput="this.className = ''"
name="password"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
oninput="this.className = ''"
name="password"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
oninput="this.className = ''"
name="linkedin"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
oninput="this.className = ''"
name="twitter"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
oninput="this.className = ''"
name="facebook"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
oninput="this.className = ''"
name="fullname"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
oninput="this.className = ''"
name="mobile"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
oninput="this.className = ''"
name="address"
/>
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onclick={() => nextPrev(-1)}>
Previous
</button>
<button type="button" id="nextBtn" onclick={() => nextPrev(1)}>
Next
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
const AddTest = () => {
const [currentTab, setCurrentTab] = React.useState(0);
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i,
x = document.getElementsByClassName("stepIndicator");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("step");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == x.length - 1) {
document.getElementById("nextBtn").innerHTML = "Submit";
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n);
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("step");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
setCurrentTab((curTab) => curTab + n);
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("signUpForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x,
y,
i,
valid = true;
x = document.getElementsByClassName("step");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("stepIndicator")[currentTab].className +=
" finish";
}
return valid; // return the valid status
}
useEffect(() => {
showTab(currentTab); // Display the current tab
}, []);
return (
<>
<div className="row">
<p>njjj</p>
<form id="signUpForm" className="md-12" action="#!">
<div className="form-header d-flex mb-4">
<span className="stepIndicator">تنظیمات</span>
<span className="stepIndicator">سوالات</span>
<span className="stepIndicator">تفسیر</span>
<span className="stepIndicator">پیش نمایش</span>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="form-row">
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
<div className="col-md-6 mb-3">
<input
type="text"
className="form-control"
id="validationCustom02"
placeholder="Last name"
required
/>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<textarea className="form-control"></textarea>
</div>
</div>
<div className="form-row">
<div className="col-md-12 mb-3">
<input
type="text"
className="form-control"
id="validationCustom01"
placeholder="First name"
required
/>
</div>
</div>
<div className="form-group">
<label for="company_name" className="font-weight-bold text-right">
درصد افیلیت
</label>
<p className="text-muted">
درصدی از هزینه تست که میخواهید به پزشک یا نمایندگان اختصاص داده
شود را تعیین کنید.
</p>
<div className="form-row">
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline1"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline1"
>
5 درصد
</label>
</div>
<div className="custom-control custom-radio custom-control-inline">
<input
type="radio"
id="customRadioInline2"
name="customRadioInline1"
className="custom-control-input"
/>
<label
className="custom-control-label"
for="customRadioInline2"
>
10 درصد
</label>
</div>
</div>
</div>
</div>
<div className="step">
<p className="text-center mb-4">Create your account</p>
<div className="mb-3">
<input
type="email"
placeholder="Email Address"
oninput="this.className = ''"
name="email"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Password"
oninput="this.className = ''"
name="password"
/>
</div>
<div className="mb-3">
<input
type="password"
placeholder="Confirm Password"
oninput="this.className = ''"
name="password"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">
Your presence on the social network
</p>
<div className="mb-3">
<input
type="text"
placeholder="Linked In"
oninput="this.className = ''"
name="linkedin"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Twitter"
oninput="this.className = ''"
name="twitter"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Facebook"
oninput="this.className = ''"
name="facebook"
/>
</div>
</div>
<div className="step">
<p className="text-center mb-4">We will never sell it</p>
<div className="mb-3">
<input
type="text"
placeholder="Full name"
oninput="this.className = ''"
name="fullname"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Mobile"
oninput="this.className = ''"
name="mobile"
/>
</div>
<div className="mb-3">
<input
type="text"
placeholder="Address"
oninput="this.className = ''"
name="address"
/>
</div>
</div>
<div className="form-footer d-flex">
<button type="button" id="prevBtn" onClick={() => nextPrev(-1)}>
Previous
</button>
<button type="button" id="nextBtn" onClick={() => nextPrev(1)}>
Next
</button>
</div>
</form>
</div>
</>
);
};
export default AddTest;
I created this CodeSandBox to guide you in the react way. I only added handling the next and prev steps. https://codesandbox.io/s/keen-feather-cr801y?file=/src/App.js
It's better to read about form handling:
https://www.w3schools.com/react/react_forms.asp
https://ibaslogic.com/simple-guide-to-react-form/
Or you can use a package like formik to help.

React needs to be handled some if conditions

I have an issue with the if statement. The problem is I need to create a condition if the array has 2 object needs to be true if has 1 object it should be false. the objects are strings please check the code.
const { program } = useContext(ProgramContext);
const { authMethods } = program;
let loginComponent;
let claimComponent;
let insertRow;
let insertEnd;
if (authMethods) {
if (authMethods.indexOf('login') !== -1) {
loginComponent = (
<div className="col-md-6 d-flex">
<div className="card flex-grow-1 mb-md-0">
<div className="card-body">
<h3 className="card-title">Login</h3>
<form>
<div className="form-group">
<label htmlFor="login-id">User ID</label>
<input
id="login-id"
className="form-control"
placeholder="Please enter user ID"
/>
</div>
<div className="form-group">
<label htmlFor="login-password">Password</label>
<input
id="login-password"
type="password"
className="form-control"
placeholder="Password"
/>
<small className="form-text text-muted">
<ErrModal />
</small>
</div>
<div className="form-group">
<div className="form-check">
<span className="form-check-input input-check">
<span className="input-check__body">
<input
id="login-remember"
type="checkbox"
className="input-check__input"
/>
<span className="input-check__box" />
<Check9x7Svg className="input-check__icon" />
</span>
</span>
<label className="form-check-label" htmlFor="login-remember">
Remember Me
</label>
</div>
</div>
<button type="submit" className="btn btn-primary mt-2 mt-md-3 mt-lg-4">
Login
</button>
</form>
</div>
</div>
</div>
);
}
if (authMethods.indexOf('claim') !== -1) {
claimComponent = (
<div className="col-md-6 d-flex mt-4 mt-md-0">
<div className="card flex-grow-1 mb-0">
<div className="card-body">
<h3 className="card-title">Claim</h3>
<form>
<div className="form-group">
<label htmlFor="claim-code">Enter Claim Code</label>
<input
id="register-email"
type="text"
className="form-control"
placeholder="Claim Code"
/>
</div>
<button type="submit" className="btn btn-primary" style={{ marginTop: '186px' }}>
Claim
</button>
</form>
</div>
</div>
</div>
);
}
}
console.log(loginComponent);
console.log(claimComponent);
const rowComponent = (
<div className="container">
{insertRow}
{loginComponent}
{claimComponent}
{insertEnd}
</div>
);
Basically I want to add row class if there are 2 items in the array otherwise I don't need a row.
thank you
Your question is not clear so I'll chalk out a similar example:
import React from 'react'
const Component = () => {
const arr = ["foo", "bar"];
const rowClass = arr.length === 2 ? "row" : "";
return (
<div className={rowClass}>
This is an example
</div>
)
}
export default Component

Manage array from get request using useEffect and useState hooks in React

I need help in managing some values from a GET request that returns me an array of values from reading a file inside the server.
When loading the functional component I want send the request so I'm using useState and useEffect in my code like the following:
import { useHttpClient } from '../shared/hooks/http-hook';
...
const Settings = () => {
const { isLoading, error, sendRequest, clearError } = useHttpClient();
const [loadedSettings, setLoadedSettings] = useState([]);
useEffect(() => {
const fetchSettings = async () => {
try {
const responseData = await sendRequest(
'http://localhost/api/settings'
);
setLoadedSettings(responseData)
} catch (err) { }
};
fetchSettings();
}, []);
I need to do this to fill some inputs of my form with the values from the array I get from the request:
return (
<React.Fragment>
<ErrorModal error={error} onClear={clearError} />
{isLoading && <LoadingSpinner asOverlay />}
<form className="settings-form" onSubmit={settingsSubmitHandler}>
<div className="container">
<div className="row">
<div className="col">
<div className="form-group row">
<div className="col-sm-12">
<p>Database Connection:</p>
</div>
</div>
<div className="form-group row">
<div className="col-sm-12">
<Input
element="input"
id="hostname"
type="text"
title="HOSTNAME"
placeholder="HOST NAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
</div>
</div>
<div className="form-group row">
<div className="col-sm-12">
<Input
element="input"
id="username"
type="text"
title="USERNAME"
placeholder="USERNAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
</div>
</div>
<div className="form-group row">
<div className="col-sm-12">
<Input
element="input"
id="password"
type="password"
title="PASSWORD"
placeholder="PASSWORD"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
</div>
</div>
...
If I console log:
loadedSettings.map(elem => {
console.log(elem)
}
It returns me all values from text file as expected.
How can I put every value in each input box?
Thanks
you can try to render the form input elements inside the map function
please let me know if this worked fine with you
return (
..
loadedSettings.map(elem=>(
<Input
element="input"
value={elem}
id="hostname"
type="text"
title="HOSTNAME"
placeholder="HOST NAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
))
)
I think, you can just replace this section
<div className="col-sm-12">
<Input
element="input"
id="hostname"
type="text"
title="HOSTNAME"
placeholder="HOST NAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
/>
</div>;
with
{loadedSettings && loadedSettings.map((setting) => (
<div className="col-sm-12">
<Input
element="input"
id="hostname"
type="text"
title="HOSTNAME"
placeholder="HOST NAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
value={setting}
/>
</div>
)}
I solved with this {!isLoading && loadedSettings && ( and transformed array into an object so I can add in my input elements initialValue={loadedSettings.MYHOST} ecc..
{
"MYHOST": "value1",
"MYUSER": "value2",
....
....
}
Here the jsx code
return (
<React.Fragment>
<ErrorModal error={error} onClear={clearError} />
{isLoading && <LoadingSpinner asOverlay />}
{!isLoading && loadedSettings && (
<form className="settings-form" onSubmit={settingsSubmitHandler}>
<div className="container">
<div className="row">
<div className="col">
<div className="form-group row">
<div className="col-sm-12">
<p>Database Connection:</p>
</div>
</div>
<div className="form-group row">
<div className="col-sm-12">
<Input
element="input"
id="hostname"
type="text"
title="HOSTNAME"
placeholder="HOST NAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
initialValue={loadedSettings.MYHOST}
initialValid={true}
/>
</div>
</div>
<div className="form-group row">
<div className="col-sm-12">
<Input
element="input"
id="username"
type="text"
title="USERNAME"
placeholder="USERNAME"
validators={[VALIDATOR_REQUIRE()]}
errorText="Required."
onInput={inputHandler}
initialValue={loadedSettings.MYUSER}
initialValid={true}
/>
</div>
</div>
...
...

Using the react-select to create the markup using bootstrap 4

I am new to the react-redux. Here I am trying to achieve the following markup
So from Here what I achieved using the following code is ,
<div className="row">
<div className="col-md-12">
<form className="form-inline">
<div className="form-group col-md-4">
<lable>Select Technolgoy </lable>
<Select
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
</div>
<div className="form-group col-md-4">
<lable>Select Component </lable>
<Select
value={selectedOption}
onChange={this.handleChange}
options={options}
/>
</div>
<div className="form-group col-md-4">
<lable>Select Job </lable>
<button className="btn btn-primary">
Add
</button>
<button className="btn btn-primary">
Remove
</button>
</div>
</form>
</div>
</div>
So, here I am using the react-select.
What is it that I am doing wrong ? can anyone help me with this? Thanks
You need to update the style of your selects like the following lines:
const styles = {
container: base => ({
...base,
flex: 1
})
};
function App() {
return (
<div className="row">
<div className="col-12">
<form className="form-inline">
<div className="form-group col-4">
<lable>Select Technolgoy </lable>
<Select styles={styles} options={options} />
</div>
<div className="form-group col-4">
<lable>Select Component </lable>
<Select styles={styles} options={options} />
</div>
<div className="form-group col-4 row">
<lable className="col-4">Select Job </lable>
<button className="btn btn-primary col-4">Add</button>
<button className="btn btn-primary col-4">Remove</button>
</div>
</form>
</div>
</div>
);
}
Here a live example.

Error while updating the content

Why am i getting an error while trying for updating the content? I am getting the edited value in componentDidMount function. There is no problem while posting the content but when i try for updating the content using reactjs and django tastypie api , i get an error as
"{"error_message": "The format indicated 'application/x-www-form-urlencoded' had no available deserialization method.
my code
export default class RoomDetail extends Component{
constructor(props){
super(props);
this.state = { rooms:[], isEditing:false };
this.onEditClick = this.onEditClick.bind(this);
this.onCancelClick = this.onCancelClick.bind(this);
this.onSaveClick = this.onSaveClick.bind(this);
}
onEditClick(event){
event.preventDefault();
this.setState({ isEditing: true });
}
onCancelClick(){
this.setState({ isEditing: false });
}
onSaveClick(event){
event.preventDefault();
console.log('edited property type is', this.refs.property.value);
const newUser = [
{
listingName: this.refs.editlistingName.value,
summary: this.refs.editSummary.value,
ownerName: this.refs.editOwnerName.value,
email: this.refs.editEmail.value,
phoneNumber:this.refs.editphoneNumber.value,
room:this.refs.rooms.value,
city:this.refs.editCity.value,
place:this.refs.editPlace.value,
property:this.refs.property.value,
price:this.refs.editPrice.value,
}
];
this.updateRoomToServer(...newUser);
}
updateRoomToServer(newUser){
console.log('newuser from updateRoomToServer', newUser);
this.componentDidMount(newUser);
}
componentDidMount(newUser){
console.log('component updated with new user are', newUser);
$.ajax({
url:'/api/v1/rental/'+this.props.data.slug+'/',
type:'put',
dataType:'json',
data:newUser,
success: (data) => {
console.log('data',data);
},
error: (xhr, status, err) => {
console.error(xhr, status, err.toString());
}
});
}
componentWillMount(){
console.log('componentDidMount');
console.log(this.props.data.slug);
this.loadRoomFromServer();
}
loadRoomFromServer(){
$.ajax({
url:'/api/v1/rental/'+this.props.data.slug,
dataType:'json',
success: (data) => {
console.log('data',data);
this.setState({rooms: data});
},
error: (xhr, status, err) => {
console.error(xhr, status, err.toString());
}
});
}
renderRoomDetailSection(){
let imageFile;
let firstImage;
if(this.state.rooms.gallery){
firstImage = this.state.rooms.gallery[0].image;
console.log('firstImage', firstImage);
imageFile = this.state.rooms.gallery.map((image) => {
return(
<div className="col-md-3">
<img src={image.image} key={image.id} className="img-fluid img-rounded" />
</div>
);
});
}
if (this.state.isEditing ){
return(
<div className="container">
<div className="row">
<div className="col-md-6 col-md-offset-3">
<form onSubmit = { this.onSaveClick } >
<fieldset className="form-group">
<label htmlFor="listingName">listing Name</label>
<input type="text" className="form-control" id="listingName" defaultValue = {this.state.rooms.listingName} placeholder="name of your listing" ref="editlistingName" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="summary">summary</label>
<input type="text" className="form-control" id="summary" defaultValue = {this.state.rooms.summary} placeholder="enter summary" ref="editSummary" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="ownerName">owner Name</label>
<input type="text" className="form-control" id="ownerName" defaultValue = {this.state.rooms.ownerName} placeholder="name of owner" ref="editOwnerName" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="email">Email</label>
<input type="text" className="form-control" id="email" defaultValue = {this.state.rooms.email} placeholder="enter email" ref="editEmail" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="contact">phoneNumber</label>
<input type="text" className="form-control" id="phoneNumber" defaultValue = {this.state.rooms.phoneNumber} placeholder="enter phoneNumber" ref="editphoneNumber" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="contact">Property Type</label>
<select className="form-control" defaultValue={this.state.rooms.property} name="Property Type" ref="property">
<option value="appartment">Appartment</option>
<option value="house">House</option>
<option value="shop">Shop</option>
</select>
</fieldset>
<fieldset className="form-group">
<label htmlFor="contact">Room</label>
<select className = "form-control" defaultValue={this.state.rooms.room} name="Rooms" ref="rooms">
<option value="1">1 room</option>
<option value="2">2 rooms</option>
<option value="3">3 rooms</option>
<option value="4">4 rooms</option>
<option value="5">5+ rooms</option>
</select>
</fieldset>
<fieldset className="form-group">
<label htmlFor="price">Price</label>
<input type="text" className="form-control" id="price" defaultValue = {this.state.rooms.price} placeholder="enter price" ref="editPrice" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="city">City</label>
<input type="text" className="form-control" id="city" defaultValue = {this.state.rooms.city} placeholder="enter city" ref="editCity" />
</fieldset>
<fieldset className="form-group">
<label htmlFor="place">Price</label>
<input type="text" className="form-control" id="place" defaultValue = {this.state.rooms.place} placeholder="enter place" ref="editPlace" />
</fieldset>
</form>
</div>
</div>
</div>
)
}
return(
<div className="detailListing">
<div className="container-fluid">
<div className="row">
<div className="col-sm-12">
<div className="lanscapeImage">
<img src={firstImage} className="img-fluid" height="400px" />
</div>
</div>
</div>
</div>
<div className="container descriptionContainer">
<div className="row">
<div className = "aboutListing line">
<div className="col-md-10 listingNameSummary">
<h3>About your listing {this.state.rooms.listingName}</h3>
<p>{this.state.rooms.summary}</p>
</div>
</div>
<div className="rentInformation line">
<div className="col-md-3">
<h3>Rent Information</h3>
</div>
<div className="col-md-9">
<p>Property Type: {this.state.rooms.property}</p>
<p>Number of rooms/spaces: {this.state.rooms.room} room</p>
<p>Price of rooms/spaces: {this.state.rooms.price} Rs/Month </p>
<p>Water Facilities: {this.state.rooms.water} </p>
<p>Amenities: {this.state.rooms.amenities} </p>
<hr />
</div>
</div>
<div className="location line">
<div className="col-md-3">
<h3>Location</h3>
</div>
<div className="col-md-9">
<p>City: {this.state.rooms.city}</p>
<p>Place: {this.state.rooms.place} </p>
<hr />
</div>
</div>
<div className="gallery line">
<div className="col-md-3">
<h3>Gallery</h3>
</div>
<div className="col-md-9">
{imageFile}
</div>
</div>
</div>
</div>
</div>
)
}
renderUserAction(){
if ( this.state.isEditing ){
return(
<div className = "buttons">
<button className="btn btn-warning text-xs-left" onClick = { this.onSaveClick } >Save</button>
<button className="btn btn-danger text-xs-right" onClick = { this.onCancelClick } >Cancel</button>
</div>
);
}
return(
<div className = "buttons">
<button className="btn btn-warning" onClick = { this.onEditClick }>Edit</button>
</div>
);
}
render() {
return (
<div className = "newRoomDetail" >
{ this.renderRoomDetailSection() }
{ this.renderUserAction() }
</div>
);
}
}
api.py
class RentalResource(MultipartResource,ModelResource):
gallery = fields.ToManyField('rentals.api.api.GalleryResource', 'gallery', related_name='rental',full=True)
class Meta:
queryset = Rental.objects.all()
resource_name = 'rental'
detail_uri_name = 'slug'
allowed_methods = ['get', 'post', 'put']
fields = ['listingName','slug','property','city','place','ownerName','room','water','amenities','price','summary','phoneNumber','email']
filtering = { "property" : ALL , "city":ALL, "place":('exact', 'startswith',), "room":ALL,"price":ALL,"listingName":ALL,"slug":ALL}
authorization = DjangoAuthorization()
You should try changing your AJAX call this way:
$.ajax({
url:'/api/v1/rental/'+this.props.data.slug+'/',
type:'put',
contentType: "application/json",
data:JSON.stringify(newUser),
success: (data) => {
console.log('data',data);
},
error: (xhr, status, err) => {
console.error(xhr, status, err.toString());
}
});
Your backend might be able to deserialize the data this way, as application/x-www-form-urlencoded does not seem to work.

Categories

Resources