how to remove blank space for jspdf pdf in react js - reactjs

I am new to react js and new to creating jspdf pdf. I am creating a pdf for download however I am getting blank space at the top of the pdf like so:
I want to remove this blank space that I am getting in the pdf. My html renders like this:
Here is the function to generate the pdf:
generatePDF = () => {
window.html2canvas = html2canvas;
var doc = new jsPDF("p", "pt", "a4");
doc.html(document.querySelector("#content"), {
callback: function(pdf) {
pdf.save("Coil_Details.pdf");
}
});
};
Here is the function to download data:
getData = async () => {
var ID = this.props.id;
var promise = await this.getAuthorization();
var proxyUrl = "https://cors-anywhere.herokuapp.com/";
console.log("ID:" + ID);
axios({
method: "GET",
url: serverDetails.jwtTokenGenerationURL,
params: {
"jwt-token": jwtService.GetJWT()
}
})
.then(response => {
if (response.statusText != "" && response.statusText != "OK") {
return Promise.reject(response.statusText);
} else {
serverDetails.jwtResponse = response.data;
//return response.data;
}
})
.then(response => {
var url = "api/observation/GetCoilImages";
url += "?jwt=" + serverDetails.jwtResponse;
url += "&ID=" + ID;
axiosAPI
// .get(url)
.get(url)
.then(response => {
if (response.statusText != "" && response.statusText == "OK") {
// window.open(response.data, '_blank');
console.log("Response:" + response.data);
console.log("Response1:" + response.data[0]);
var code = [];
for (var i in response.data) {
code[i] = response.data[i];
console.log("Code:" + code);
}
this.setState({ code });
}
this.setState({
modal: !this.state.modal
});
});
});
};
Here is the html for the same:
return (
<div>
<i
className="fa fa-list-alt"
aria-hidden="true"
// onClick={this.toggle}
onClick={this.getData}
></i>
<Modal
isOpen={this.state.modal}
toggle={this.toggle}
className={this.props.className}
size="lg"
style={{ maxWidth: "700px", width: "100%" }}
>
<ModalHeader
toggle={this.toggle}
cssModule={{ "modal-title": "w-100 text-center" }}
>
Coil Details
</ModalHeader>
<ModalBody>
{/* <Container fluid={true}>
<Card className="card-profile shadow mt--100">
<CardBody> */}
<div id="content">
<div>
<Card className="card-profile shadow">
<center>
{/* <img src={this.props.url} width="100%" height="250px" /> */}
{/* <img src={code} width="100%" height="250px" /> */}
{/* {this.state.code.map(({ src }) => (
<img src={src} key={src} width="40%" height="50px" />
))} */}
{this.state.code.map((imgSrc, index) => (
<img
src={imgSrc}
key={index}
width="100%"
height="250px"
style={{
border: "5px solid #000000",
margin: "3px 3px 3px 3px"
}}
/>
))}
</center>
</Card>
</div>
<hr></hr>
<br></br>
<Row style={{ marginTop: "1rem", marginLeft: "1rem" }}>
<Col lg="3" style={{ marginTop: "1rem" }}>
<FormGroup>
<label>Type</label>
<Input
type="text"
id="typeTextField"
size="sm"
defaultValue={this.props.type}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginTop: "1rem", marginLeft: "3rem" }}>
<FormGroup>
<label>Coil ID</label>
<Input
type="text"
id="coilTextField"
size="sm"
defaultValue={this.props.id}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginTop: "1rem", marginLeft: "3rem" }}>
<FormGroup>
<label>View</label>
<Input
type="text"
id="viewTextField"
size="sm"
defaultValue={this.props.view}
/>
</FormGroup>
</Col>
</Row>
<hr></hr>
<Row style={{ marginLeft: "1rem" }}>
<Col lg="3">
<FormGroup>
<label>Delivery No</label>
<Input
type="text"
id="deliveryTextField"
size="sm"
defaultValue={this.props.delivery}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginLeft: "3rem" }}>
<FormGroup>
<label>Invoice No</label>
<Input
type="text"
id="invoiceTextField"
size="sm"
defaultValue={this.props.invoice}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginLeft: "3rem" }}>
<FormGroup>
<label>Wagon No</label>
<Input
type="text"
id="wagonTextField"
size="sm"
defaultValue={this.props.wagon}
/>
</FormGroup>
</Col>
</Row>
<hr></hr>
<Row style={{ marginLeft: "1rem" }}>
<Col lg="3">
<FormGroup>
<label>Location</label>
<Input
type="text"
id="locationTextField"
size="sm"
defaultValue={this.props.location}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginLeft: "3rem" }}>
<FormGroup>
<label>ICHP</label>
<Input
type="text"
id="ICHPTextField"
size="sm"
defaultValue={this.props.ICHP}
/>
</FormGroup>
</Col>
<Col lg="3" style={{ marginLeft: "3rem" }}>
<FormGroup>
<label>Remarks</label>
<Input
type="textarea"
id="remarksTextField"
size="sm"
defaultValue={this.props.remarks}
/>
</FormGroup>
</Col>
</Row>
<Row>
<Col
lg="5"
style={{ display: "flex", justifyContent: "center" }}
>
<FormGroup>
<label>Date</label>
<Input
type="text"
id="dateTextField"
size="sm"
defaultValue={this.props.date}
/>
</FormGroup>
</Col>
</Row>
</div>
{/* </CardBody>
</Card>
</Container> */}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={this.generatePDF}>
Download
</Button>{" "}
<Button color="secondary" onClick={this.toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
);
}
}
Why am I getting this blank space at the top and how to remove it. Please help

Related

React Use EmailJS for multiple step Form

I have a React multiple step form, first and second steps is to collect user's image, the third step is user's contact information, and I want to send all this by use EmailJS.
Now I set up emailJS correctly so email does get sent(only last step form), but I don't know how to keep first and second steps' content.
Here is part of my current code:
import "./main.css";
import { Stepper, StepLabel, Step } from "#mui/material";
import Step1 from "../Steps/Step1";
import Step2 from "../Steps/Step2";
import Step3 from "../Steps/Step3";
import { multiStepContext } from "../Steps/StepContext";
import { useContext } from "react";
import { QontoConnector, QontoStepIcon } from "./CustomStepper";
export default function Main(){
const {currentStep, finalData} = useContext(multiStepContext);
function showStep(step){
switch(step){
case 1 :
return <Step1 />
case 2 :
return <Step2 />
case 3 :
return <Step3 />
}
}
return(
<div className="center-steeper">
<Stepper style={{width: "90%", marginTop: "20px", marginBottom: "35px"}}
activeStep={currentStep - 1} orientation="horizontal" alternativeLabel connector={<QontoConnector />}>
<Step>
<StepLabel StepIconComponent={QontoStepIcon}></StepLabel>
</Step>
<Step>
<StepLabel StepIconComponent={QontoStepIcon}></StepLabel>
</Step>
<Step>
<StepLabel StepIconComponent={QontoStepIcon}></StepLabel>
</Step>
</Stepper>
<div>
{showStep(currentStep)}
</div>
</div>
)
}
Step 1:
export default function Step1(){
...
return(
<div className="step-container">
...
<Col span={11} className="upload" style={{ marginRight: "25px" }}>
<div className="upload-photo">
<input id="fusk" type="file" onChange={onChange} style={{display:"none"}} name="origin_pic"/>
...
</div>
</Col>
...
<Row style={{ justifyContent: "space-between"}}>
<Col span={1}></Col>
<Col span={1}>
<button className="btn-next" onClick={() => setStep(2)}>Next</button>
</Col>
</Row>
</div>
)
}
Step 2:
export default function Step2(){
...
return(
<div className="step-container">
...
<input id="fusk" type="file" onChange={onChange} style={{display:"none"}} name="focus_pic"/>
...
<TextArea
className="text-input"
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Write down your concern and what you want to achieve."
autoSize={{
minRows: 7,
maxRows: 10,
}}
name="concern"
/>
<Row style={{ justifyContent: "space-between", alignSelf: "flex-start" }}>
<Col span={1}>
<button className="btn-back" onClick={() => setStep(1)}>Back</button>
</Col>
<Col span={1}>
<button className="btn-next" onClick={() => setStep(3)}>Next</button>
</Col>
</Row>
</div>
)
}
Step 3:
export default function Step3(){
const form = useRef();
const onFinish = (values) => {
console.log('Received values of form: ', values);
};
const { setStep } = useContext(multiStepContext);
const sendEmail = (e) => {
e.preventDefault();
emailjs.sendForm('service_fc2puic', 'template_vpee0kb', form.current, '5EET8rJnlaH9MTLWH')
.then((result) => {
console.log(result.text);
}, (error) => {
console.log(error.text);
});
};
return(
<div className="step-container">
<h2 className="step-title">Step 3: Tell us your contact information</h2>
<form
{...formItemLayout}
ref={form}
name="register"
onFinish={onFinish}
scrollToFirstError
>
...
<Input placeholder="First name" name="first_name"/>
...
<Input placeholder="Last name" name="last_name"/>
...
<Input placeholder="Email" name="email"/>
...
<Input placeholder="Email"/>
...
<Input placeholder="Phone number" name="phone_number"/>
...
<Checkbox defaultChecked={false} disabled value="In-office" name="consultation"><h3 className="option-text">In-office</h3></Checkbox>
<br />
<Checkbox defaultChecked={false} value="Receiving customized video through Email" name="consultation"><h3 className="option-text">Receiving customized video through Email</h3></Checkbox>
<br />
<Checkbox defaultChecked={false} disabled value="Facetime" name="consultation"><h3 className="option-text">Facetime</h3></Checkbox>
<br />
<Checkbox defaultChecked={false} disabled value="Whatsapp" name="consultation"><h3 className="option-text">Whatsapp</h3></Checkbox>
...
</form>
<Row style={{ justifyContent: "space-between", alignSelf: "flex-start" }}>
<Col span={1}>
<button className="btn-back" onClick={() => setStep(2)}>Back</button>
</Col>
<Col span={1}>
<button className="btn-next btn-submit" onClick={sendEmail}>Submit</button>
</Col>
</Row>
</div>
)
}

Can anyone help me replace this Segment with a Modal in ReactJS

can anyone help me to replace this Segment with Modal in React JS, here is the code, thanks in advance
return (
<Segment clearing style={{fontWeight: 'bold', fontSize: '20px', backgroundColor: '#f5f7fb'}}> ADD APPOINTMENT
<Form onSubmit={handleSubmit} autoComplete='off'>
<Form.Input placeholder='Customer Name' value={appointment.customerName} name='customerName' onChange={handleInputChange} />
<Form.Input type='date' placeholder='Appointment Date' value={appointment.appointmentDate} name='appointmentDate' onChange={handleInputChange} />
<Form.Input placeholder='Doctor Name' value={appointment.doctorName} name='doctorName' onChange={handleInputChange} />
<Form.Input placeholder='Service' value={appointment.service} name='service' onChange={handleInputChange} />
<Form.Input placeholder='Status' value={appointment.status} name='status' onChange={handleInputChange} />
<Button onClick={submitting} floated='right' positive type='submit' content='Submit' />
<Button onClick={closeForm} floated='right' type='submit' content='Cancel' />
</Form>
</Segment>
)
The below package seems perfect for your needs
https://www.npmjs.com/package/react-modal
below can be your implementation
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';
const customStyles = {
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
transform: 'translate(-50%, -50%)',
},
};
// Make sure to bind modal to your appElement (https://reactcommunity.org/react-modal/accessibility/)
Modal.setAppElement('#root');
function App() {
let subtitle;
const [modalIsOpen, setIsOpen] = React.useState(false);
function openModal() {
setIsOpen(true);
}
function afterOpenModal() {
// references are now sync'd and can be accessed.
subtitle.style.color = '#f00';
}
function closeModal() {
setIsOpen(false);
}
return (
<div>
<button onClick={openModal}>Open Modal</button>
<Modal
isOpen={modalIsOpen}
onAfterOpen={afterOpenModal}
onRequestClose={closeModal}
style={customStyles}
contentLabel="Example Modal"
>
<Segment clearing style={{fontWeight: 'bold', fontSize: '20px', backgroundColor: '#f5f7fb'}}> ADD APPOINTMENT
<Form onSubmit={handleSubmit} autoComplete='off'>
<Form.Input placeholder='Customer Name' value={appointment.customerName} name='customerName' onChange={handleInputChange} />
<Form.Input type='date' placeholder='Appointment Date' value={appointment.appointmentDate} name='appointmentDate' onChange={handleInputChange} />
<Form.Input placeholder='Doctor Name' value={appointment.doctorName} name='doctorName' onChange={handleInputChange} />
<Form.Input placeholder='Service' value={appointment.service} name='service' onChange={handleInputChange} />
<Form.Input placeholder='Status' value={appointment.status} name='status' onChange={handleInputChange} />
<Button onClick={submitting} floated='right' positive type='submit' content='Submit' />
<Button onClick={closeForm} floated='right' type='submit' content='Cancel' />
</Form>
</Segment>
</Modal>
</div>
);
}
ReactDOM.render(<App />, Document.getElementById("root"));

how to hide one div when another div is active in react js

i have two div login and forget password. i want on forget password login block should be hide and when login block needed forget block should be hidden. Now i able to handle forgot password block , but login block i am not able to handle. I want login block hide on click of forgot button. I have written my own code below. Can some one please suggest me how can i do that.
import React, { useEffect, useState } from 'react';
import useForm from 'react-hook-form';
import { Redirect } from 'react-router-dom';
import './loginForm.css';
const { Header, Content, Footer } = Layout;
const LoginForm = () => {
const [forgotPass, setForgotPass] = useState(false);
if (redirect) {
return <Redirect to={routePaths.DASHBOARD} push />;
}
return (
<Layout>
<Header className="header">
<div>
<img src={logo} className="logo" />
<span className="lft">
<MessageOutlined />
</span>
</div>
</Header>
<Content className="content-screen">
<Row>
<Col xs={24} sm={24} md={8} />
<Col xs={24} sm={24} md={8}>
<div id="loginDiv" className="screen">
<Card title="Login to Relocatte" headStyle={{ backgroundColor: '#69c0ff', border: 1 }}>
<form onSubmit={handleSubmit(onSubmit)}>
{/* <h2 style={{textAlign: 'center'}}>Login</h2> */}
<Row>
<Col style={{ padding: 10 }}>
<Input size="large" placeholder="Enter User Email Here..." onChange={(e) => setValue('email', e.target.value)} />
<ErrorTag errors={errors} name="email" />
</Col>
<Col style={{ padding: 10 }}>
<Input type="password" size="large" placeholder="Enter User Password Here..." onChange={(e) => setValue('encryptedPassword', e.target.value)} />
<ErrorTag errors={errors} name="encryptedPassword" />
</Col>
<Col span={7} style={{ padding: 15 }} className="forget">
Sign Up
</Col>
<Col span={7} style={{ padding: 10 }}>
<Input style={{ cursor: 'pointer' }} type="submit" value="Login" className="login-form-button" shape="round" icon="rollback" />
</Col>
<Col span={10} style={{ padding: 15 }} className="forget">
<a href="#" onClick={() => setForgotPass(!forgotPass)}>Forgot Password</a>
{/* <button onClick={() => setForgotPass(!forgotPass)}>Forgot Password</button> */}
</Col>
</Row>
</form>
</Card>
</div>
</Col>
<Col xs={24} sm={24} md={8}>
{/* forgot div goes here */}
{forgotPass
&& (
<div className="screen">
<Card title="Forgot Password" headStyle={{ backgroundColor: '#69c0ff', border: 1 }}>
<form onSubmit={handleSubmit(onSubmit)}>
{/* <h2 style={{textAlign: 'center'}}>Login</h2> */}
<Row>
<Col style={{ padding: 10 }}>
<Input size="large" placeholder="Enter Registered Email Here..." onChange={(e) => setValue('', e.target.value)} />
<ErrorTag errors={errors} name="" />
</Col>
<Col span={12} style={{ padding: 10 }}>
<Input style={{ cursor: 'pointer' }} type="submit" value="Send Reset Link" className="login-form-button" shape="round" icon="rollback" />
</Col>
<Col span={10} style={{ padding: 15 , textAlign: "right"}} className="forget">
<a href="#" onClick={() => setForgotPass(!forgotPass)}>Login</a>
{/* <button onClick={() => setForgotPass(!forgotPass)}>Forgot Password</button> */}
</Col>
</Row>
</form>
</Card>
</div>
)}
</Col>
</Row>
</Content>
<Footer className="footer-back">
<Row>
<Col xs={24} sm={24} md={12} className="foot-child-1">
All Right Reserved© 2020 Relocatte
</Col>
<Col xs={24} sm={24} md={12} className="foot-child-2">
<span>Privacy Policy</span>
<span> | </span>
<span>Term & Conditions</span>
</Col>
</Row>
</Footer>
</Layout>
);
};
export default LoginForm;
Hi Please check this example:
import React, {useEffect, useState} from 'react';
const LoginForm = () => {
const [forgotPass, setForgotPass] = useState(false);
function handleLogin(event) {
}
function handleForgot(event) {
setForgotPass(!forgotPass);
}
function handleReset(event) {
alert('Your password is reset');
setForgotPass(!forgotPass);
}
return (
<div>
{forgotPass ?
(<div>
Username: <input/> <br/>
<button onClick={handleReset}>Reset Password</button>
</div>)
:
(<div>
Username: <input/> <br/>
Password: <input/> <br/>
<button onClick={handleLogin}>Login</button>
<button onClick={handleForgot}>Forgot Password</button>
</div>)
}
</div>
);
};
export default LoginForm;
There are 2 ways of doing it
Using ternary operator
return (<div className="container">
{forgotPass ? <div>Forget password div </div> : <div> Login Div</div>}
</div>)
Using CSS
return (<div className="container">
<div className={forgotPass ? "show" : "hide"}>Forget password div </div>
<div className={!forgotPass ? "show" : "hide"}> Login Div</div>}
</div>)
in your css:
.show { display: 'block' }
.hide { display: 'none' }

Is there a way to force a React component to rerender a child?

I have a React component <ProductPrices>:
render() {
if (this.props.currentProduct.id !== 'new' && !this.props.currentProductPrices) {
this.props.fetchProductPrices(this.props.currentProduct.id);
}
return (
<div>
<div style={{backgroundColor: 'gray', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<h1>Precios</h1>
</div>
<div>
{this.props.currentProductPrices && this.props.currentProductPrices.map((price, index) => {
console.log({detail: price});
return (
<ProductPricesEntry key={price.id} price={price} index={index} />
)
})}
</div>
</div>
)
}
As you can see, <ProductPrices> contains a number of subcomponents <ProductPricesEntry>, which amount is dynamic depending on Redux state variable currentProductPrices:
render() {
console.log({entry: this.props.price});
return (
<div style={{display: 'flex', background: 'white', backgroundColor: 'lightgray', marginTop: '2px', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<div className='col-10'>
<div fullWidth>
<h3>{this.props.price.prices_table.name}</h3>
</div>
<div fullWidth style={{display: 'flex'}}>
{this.props.price.current_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.props.price.current_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.props.price.due_date?
<div style={{textAlign: 'center'}} className='col-4'><strong>{this.props.price.due_date}</strong></div>:
<div style={{textAlign: 'center', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.props.price.next_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.props.price.next_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
</div>
<div fullWidth style={{display: 'flex'}}>
<div style={{textAlign: 'right'}} className='col-4'>Actual</div>
<div style={{textAlign: 'center'}} className='col-4'>Vigencia</div>
<div style={{textAlign: 'right'}} className='col-4'>Próximo</div>
</div>
</div>
<div className='col-1'>
<IconButton color="primary" aria-label={''.concat('update-price-', this.props.price.id)}>
<i className="zmdi zmdi-edit zmdi-hc-fw" onClick={this.handleUpdateClick} />
</IconButton>
<Dialog fullWidth open={this.state.updateDialogOpen} arialabelledby={''.concat('update-price-', this.props.price.id)}>
<DialogTitle id={"".concat("update-price-", this.props.price.id)}>Actualizar Precio</DialogTitle>
<DialogContentText>
<div style={{paddingLeft: '25px'}}><h2>{this.props.currentProductData.name}</h2></div>
<div style={{paddingLeft: '25px'}}><h2>{this.props.price.prices_table.name}</h2></div>
</DialogContentText>
<DialogContent>
<FormControl fullWidth>
<InputLabel htmlFor="newPrice">Precio</InputLabel>
<Input
type="number"
id="newPrice"
name="newPrice"
value={this.state.newPrice}
onChange={this.handleChange}
startAdornment={<InputAdornment position="start">$</InputAdornment>}
/>
</FormControl>
<div fullWidth><TextField fullWidth label="Fecha" type="date" name="newDate" value={this.state.newDate} onChange={this.handleChange} /></div>
</DialogContent>
<DialogActions>
<Button onClick={this.handleDialogAcceptClick} name="accept" color="primary">
Aceptar
</Button>
<Button onClick={this.handleDialogCancelClick} name="cancel" color="secondary">
Cancelar
</Button>
</DialogActions>
</Dialog>
</div>
</div>
)
}
}
I have put console.log() statements right before calling <ProductPricesEntry> from <ProductPrices>, and inside <ProductPricesEntry> when rendering, and I can see that both console.log() statements are reached the first time, but the one inside <ProductPricesEntry> is not reached if this.props.currentProductPrices changes:
This is the value of this.props.currentPrices that is different, and I can see the change on Redux Tools:
The problem is that console.log() statement inside <ProductPricesEntry> is never reached, which means that it does not rerenders, in despite that the Redux state value that changed is sent to the component as a props, and displayed inside.
I guess I am doing something wrong, but I can't find it.
EDIT
This is the reducer that changes the state that must cause the rerendering:
case UPDATE_PRODUCT_PRICE_SUCCESS: {
if (state.currentPricesTable) {
let currentPricesTableProducts = [...state.currentPricesTableProducts];
let updatedProductIndex = currentPricesTableProducts.findIndex(product => product.id === action.payload.productPrice.id)
currentPricesTableProducts[updatedProductIndex]['next_price'] = action.payload.productPrice.next_price;
currentPricesTableProducts[updatedProductIndex]['due_date'] = action.payload.productPrice.start_date;
return {
...state,
currentPricesTableProducts: [...currentPricesTableProducts],
alert: {type: ALERT_SUCCESS, message: "El precio se actualizó existosamente."},
showMessage: true,
}
} else if (state.currentProduct) {
let currentProductPrices = [...state.currentProductPrices];
let updatedProductPriceIndex = currentProductPrices.findIndex(productPrice => productPrice.prices_table_product === action.payload.productPrice.prices_table_product)
currentProductPrices[updatedProductPriceIndex].next_price = action.payload.productPrice.next_price;
currentProductPrices[updatedProductPriceIndex].due_date = action.payload.productPrice.start_date;
return {
...state,
currentProductPrices: [...currentProductPrices],
alert: {type: ALERT_SUCCESS, message: "El precio se actualizó existosamente."},
showMessage: true,
}
} else {
return {
...state
}
}
}
As you can see, I replace the state variable currentProductPrices whit a brand new array.
I added a console.log() just before returning from the reducer, and I can see that the data is right. I can see the change:
I could never make it work as it was, but I found a wait around the problem, and I am sharing it in case it was useful for anyone.
I basically connected <ProductPricesEntry> to Redux store instead of sending the data as props from the parent.
class ProductPricesEntry extends React.Component {
constructor(props) {
super(props);
this.state = {
updateDialogOpen: false,
newPrice: null,
newDate: null,
price: null,
}
this.price = null;
this.handleUpdateClick = this.handleUpdateClick.bind(this);
this.handleDialogAcceptClick = this.handleDialogAcceptClick.bind(this);
this.handleDialogCancelClick = this.handleDialogCancelClick.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleUpdateClick = () => {
this.setState({updateDialogOpen: true});
}
handleDialogAcceptClick = () => {
this.props.updateProductPrice(
this.price.prices_table_product,
this.price.prices_table.id,
this.props.currentProductData.id,
this.state.newPrice, this.state.newDate
);
let price = {...this.state.price};
price.due_date = this.state.newDate;
price.next_price = this.state.newPrice;
this.setState({newPrice: null, newDate: null, updateDialogOpen: false, price: price});
}
handleDialogCancelClick () {
this.setState({newPrice: null, newDate: null, updateDialogOpen: null});
}
handleChange (event) {
this.setState({[event.target.name]: event.target.value})
}
render() {
this.price = this.props.currentProductPrices[this.props.index]
return (
<div key={this.props.index} style={{display: 'flex', background: 'white', backgroundColor: 'lightgray', marginTop: '2px', paddingLeft: '10px', paddingTop: '10px', paddingBottom: '5px'}}>
<div className='col-10'>
<div fullWidth>
<h3>{this.price.prices_table.name}</h3>
</div>
<div fullWidth style={{display: 'flex'}}>
{this.price.current_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.price.current_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.price.due_date?
<div style={{textAlign: 'center'}} className='col-4'><strong>{this.price.due_date}</strong></div>:
<div style={{textAlign: 'center', color: 'orange'}} className='col-4'>Ninguno</div>
}
{this.price.next_price?
<div style={{textAlign: 'right'}} className='col-4'><strong>{currencyFormatter.format(this.price.next_price)}</strong></div>:
<div style={{textAlign: 'right', color: 'orange'}} className='col-4'>Ninguno</div>
}
</div>
<div fullWidth style={{display: 'flex'}}>
<div style={{textAlign: 'right'}} className='col-4'>Actual</div>
<div style={{textAlign: 'center'}} className='col-4'>Vigencia</div>
<div style={{textAlign: 'right'}} className='col-4'>Próximo</div>
</div>
</div>
<div className='col-1'>
<IconButton color="primary" aria-label={''.concat('update-price-', this.price.id)}>
<i className="zmdi zmdi-edit zmdi-hc-fw" onClick={this.handleUpdateClick} />
</IconButton>
<Dialog fullWidth open={this.state.updateDialogOpen} arialabelledby={''.concat('update-price-', this.price.id)}>
<DialogTitle id={"".concat("update-price-", this.price.id)}>Actualizar Precio</DialogTitle>
<DialogContentText>
<div style={{paddingLeft: '25px'}}><h2>{this.props.currentProductData.name}</h2></div>
<div style={{paddingLeft: '25px'}}><h2>{this.price.prices_table.name}</h2></div>
</DialogContentText>
<DialogContent>
<FormControl fullWidth>
<InputLabel htmlFor="newPrice">Precio</InputLabel>
<Input
type="number"
id="newPrice"
name="newPrice"
value={this.state.newPrice}
onChange={this.handleChange}
startAdornment={<InputAdornment position="start">$</InputAdornment>}
/>
</FormControl>
<div fullWidth><TextField fullWidth label="Fecha" type="date" name="newDate" value={this.state.newDate} onChange={this.handleChange} /></div>
</DialogContent>
<DialogActions>
<Button onClick={this.handleDialogAcceptClick} name="accept" color="primary">
Aceptar
</Button>
<Button onClick={this.handleDialogCancelClick} name="cancel" color="secondary">
Cancelar
</Button>
</DialogActions>
</Dialog>
</div>
</div>
)
}
}
const mapStateToProps = ({inventory}) => {
const {
currentProduct,
currentProductData,
currentProductPrices,
} = inventory
return {
currentProduct,
currentProductData,
currentProductPrices,
}
}
export default connect(mapStateToProps, {updateProductPrice}) (ProductPricesEntry);
Now it works as intended.

Reactjs - integrating rich text editor lost scope of state

I am new to reactjs - and I am trying to integrate a rich text editor into a component. The component itself is a bit complex and contains various logic to loop through a json fragment.
I'd like to place the rich text editor inside the component - but when I put the code to invoke it inside -- I loose scope of the this -- it complains on the this.state.
This is the rich text editor markup
<RichTextEditor
value={this.state.value}
onChange={this.onChange}
toolbarConfig={toolbarConfig}
/>
this is the current code
return (
<div>
<MetaSpecific title={lang.metaData.title} description={lang.metaData.description} />
<Intercom appID='bg69flze' custom_launcher_selector='.open_intercom' />
<Spacers />
<RichTextEditor
value={this.state.value}
onChange={this.onChange}
toolbarConfig={toolbarConfig}
/>
<div className='background--white background--white--medium background--white--small'>
{
lang.status[0].items.map(function (item, index) {
return (
<div key={index}>
{
(lang.status[0].dashboard === 'expert')
// after interview section - professional
? <Expert lang={lang} item={item} />
// after interview section - employer
: (lang.status[0].dashboard === 'employer')
? <Employer lang={lang} item={item} />
: null
}
<Row type='flex' justify='center' className='border__transparent--top' style={{maxWidth: '1200px', marginLeft: 'auto', marginRight: 'auto'}}>
<form>
{
(lang.status[0].dashboard === 'employer')
// after interview section - professional
? <EmployerPanel lang={lang} />
: null
}
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h3 style={{paddingBottom: '30px'}}>Shareholder agreement for a UK startup</h3>
<Row>
<Col xs={7} md={7} lg={7}>
<h3 style={{paddingBottom: '30px'}}>Projektfrist</h3>
</Col>
<Col xs={5} md={5} lg={5}>
16 June 2017
</Col>
</Row>
<h3 style={{paddingBottom: '30px'}}>Projektbeschreibung</h3>
<p className='text--font-size-14'>This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description</p>
<p className='text--font-size-14'>This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description</p>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h3 style={{paddingBottom: '30px'}}>Vorschlag zur Provision</h3>
<Row>
<Col xs={7} md={7} lg={7}>
Vergutungsmodell
</Col>
<Col xs={5} md={5} lg={5}>
Fixed rate
</Col>
</Row>
<br />
<Row>
<Col xs={7} md={7} lg={7}>
Fix Vergutung exkl. MwSt. (€)
</Col>
<Col xs={5} md={5} lg={5}>
<Input placeholder='Final Price' style={{border: '1px solid #c5c8cf'}} />
</Col>
</Row>
<Row>
<Col xs={7} md={7} lg={7}>
Ihr angestrebtes Projecktende
</Col>
<Col xs={5} md={5} lg={5}>
<Input placeholder='16/06/2017' style={{border: '1px solid #c5c8cf'}} />
</Col>
</Row>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h2 className='text--font-size-14'>Beschreibung de Angebots</h2>
<h2 className='text--font-size-14'>xx xx xx xx xx xx</h2>
<p className='text--font-size-14'><Input type='textarea' rows={4} /></p>
<p>RICH TEXT</p>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h2 className='text--font-size-14'>Mandatscereinbarung</h2>
<Input type='submit' value='PDF hochladen' style={{width: '200px', color: '#ffffff'}} />
</div>
</Col>
</form>
</Row>
</div>
)
})
}
</div>
</div>
)
but when I try and place the rich text editor in the correct part of the markup it breaks and looses scope on the this.
return (
<div>
<MetaSpecific title={lang.metaData.title} description={lang.metaData.description} />
<Intercom appID='bg69flze' custom_launcher_selector='.open_intercom' />
<Spacers />
<div className='background--white background--white--medium background--white--small'>
{
lang.status[0].items.map(function (item, index) {
return (
<div key={index}>
{
(lang.status[0].dashboard === 'expert')
// after interview section - professional
? <Expert lang={lang} item={item} />
// after interview section - employer
: (lang.status[0].dashboard === 'employer')
? <Employer lang={lang} item={item} />
: null
}
<Row type='flex' justify='center' className='border__transparent--top' style={{maxWidth: '1200px', marginLeft: 'auto', marginRight: 'auto'}}>
<form>
{
(lang.status[0].dashboard === 'employer')
// after interview section - professional
? <EmployerPanel lang={lang} />
: null
}
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h3 style={{paddingBottom: '30px'}}>Shareholder agreement for a UK startup</h3>
<Row>
<Col xs={7} md={7} lg={7}>
<h3 style={{paddingBottom: '30px'}}>Projektfrist</h3>
</Col>
<Col xs={5} md={5} lg={5}>
16 June 2017
</Col>
</Row>
<h3 style={{paddingBottom: '30px'}}>Projektbeschreibung</h3>
<p className='text--font-size-14'>This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description</p>
<p className='text--font-size-14'>This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description. This is the project description</p>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h3 style={{paddingBottom: '30px'}}>Vorschlag zur Provision</h3>
<Row>
<Col xs={7} md={7} lg={7}>
Vergutungsmodell
</Col>
<Col xs={5} md={5} lg={5}>
Fixed rate
</Col>
</Row>
<br />
<Row>
<Col xs={7} md={7} lg={7}>
Fix Vergutung exkl. MwSt. (€)
</Col>
<Col xs={5} md={5} lg={5}>
<Input placeholder='Final Price' style={{border: '1px solid #c5c8cf'}} />
</Col>
</Row>
<Row>
<Col xs={7} md={7} lg={7}>
Ihr angestrebtes Projecktende
</Col>
<Col xs={5} md={5} lg={5}>
<Input placeholder='16/06/2017' style={{border: '1px solid #c5c8cf'}} />
</Col>
</Row>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px 0'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h2 className='text--font-size-14'>Beschreibung de Angebots</h2>
<h2 className='text--font-size-14'>xx xx xx xx xx xx</h2>
<p className='text--font-size-14'><Input type='textarea' rows={4} /></p>
<RichTextEditor
value={this.state.value}
onChange={this.onChange}
toolbarConfig={toolbarConfig}
/>
</div>
</Col>
<Col xs={24} md={24} lg={24} style={{background: '#eff2f4', padding: '50px 65px'}}>
<div className='' style={{background: '#ffffff', padding: '30px'}}>
<h2 className='text--font-size-14'>Mandatscereinbarung</h2>
<Input type='submit' value='PDF hochladen' style={{width: '200px', color: '#ffffff'}} />
</div>
</Col>
</form>
</Row>
</div>
)
})
}
</div>
</div>
)

Resources