I am trying to have a button enabled in a modal when text is entered in an input field. But my form is built in another class and is used in a parent class. How can I pass an onChange
method my form component.
Here is my parent component:
import React from 'react';
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle
} from '@material-ui/core';
import CompanyFinancialModalForm from '../CompanyFinancialModalForm/CompanyFinancialModalForm';
interface CompanyFinancialModalState {
addEnabled: boolean;
}
interface CompanyFinancialModalProps {
open: boolean;
onClose: () => void;
}
export class CompanyFinancialModal extends React.Component<
CompanyFinancialModalProps,
CompanyFinancialModalState
> {
constructor(props: CompanyFinancialModalProps) {
super(props);
this.state = {
addEnabled: false
};
}
private enableButton = () => {
this.setState({ addEnabled: true});
}
public render() {
const { open, onClose } = this.props;
const { addEnabled } = this.state;
return (
<>
<Dialog
open={open}
onClose={onClose}
className="company-financial-modal"
>
<DialogTitle id="company-financial-modal-title">
{'Company and Financial Data'}
</DialogTitle>
<DialogContent>
<CompanyFinancialModalForm onChange={this.enableButton}/>
</DialogContent>
<DialogActions>
<Button
id="company-financial-modal-add"
disabled={!addEnabled}
onClick={onClose}
color="primary"
>
Add
</Button>
<Button
id="company-financial-modal-cancel"
onClick={onClose}
color="secondary"
autoFocus={true}
>
Cancel
</Button>
</DialogActions>
</Dialog>
</>
);
}
}
export default CompanyFinancialModal;
Here is my class that my form is in:
import React from 'react';
import axios from 'axios';
import { Form, Field } from 'react-final-form';
import { TextField, Select } from 'final-form-material-ui';
import {
Paper,
Grid,
MenuItem,
} from '@material-ui/core';
export interface IValues {
company_name: string;
critical_technology: [];
}
export interface IFormState {
[key: string]: any;
values: IValues[];
submitSuccess: boolean;
}
export default class CompanyFinancialModalForm extends React.Component<{}, IFormState> {
constructor(props: {}) {
super(props);
this.state = {
company_name: '',
critical_technology: [],
values: [],
submitSuccess: false
};
}
private processFormSubmission = (e: React.FormEvent<HTMLFormElement>): void => {
e.preventDefault();
this.setState({ loading: true });
const formData = {
company_name: this.state.company_name,
critical_technology: this.state.critical_technology
};
this.setState({
submitSuccess: true,
values: [...this.state.values, formData],
loading: false
});
axios.post(`http://localhost:8081/companies`, formData);
}
private onChange = (e: React.FormEvent<HTMLInputElement>) => {
const { name, value } = e.target;
// other form-related logic
this.props.onChange({ name, value }, e);
}
public render() {
const { submitSuccess, loading } = this.state;
const { onChange } = this.props;
return (
<div>
<Form
onSubmit={this.processFormSubmission}
// validate={this.validateForm}
render={({ handleSubmit,/* reset, submitting, pristine, values*/ }) => (
<form onSubmit={handleSubmit} noValidate>
<Paper style={{ padding: 16 }}>
<Grid container alignItems="flex-start" spacing={2}>
<Grid item xs={6}>
<Field
fullWidth
required
name="companyName"
component={TextField}
type="text"
label="Company Name"
onChange={onChange}
/>
</Grid>
<Grid item xs={12}>
<Field
name="critical_technology"
label="Critical Technology"
component={Select as any}
>
<MenuItem value="hypersonics">Hypersonics</MenuItem>
<MenuItem value="directed_energy">Directed Energy</MenuItem>
<MenuItem value="command_control_and_communications">Command, Control and Communications </MenuItem>
<MenuItem value="space_offense_and_defense">Space Offense and Defense</MenuItem>
<MenuItem value="cybersecurity">Cybersecurity</MenuItem>
<MenuItem value="artificial_intelligence_machine_learning">Artificial Intelligence/Machine Learning</MenuItem>
<MenuItem value="missile_defense">Missile Defense</MenuItem>
<MenuItem value="quantum_science_and_computing">Quantum Science and Computing </MenuItem>
<MenuItem value="microelectronics">Microelectronics</MenuItem>
<MenuItem value="autonomy">Autonomy</MenuItem>
</Field>
</Grid>
</Grid>
</Paper>
</form>
)}
/>
</div>
);
}
}
I want to pass a prop to <CompanyFinancialModalForm />
that enables the add button when the Textfield
has text typed into it.
2
Answers
For future reference, it will be more beneficial if you only include the relevant code, because it takes more time to find when scrolling through irrelevant code, anyways:
I’m not 100% clear on what you’re looking for, but I’ll try to answer what I think I understand. You can add an onChange method on your parent component, and pass that as a prop to the form, and the form can call that function every time it runs it’s own onChange method. Below is a simplified version:
is this what you’re looking for?
You can simply pass a child a reference to a function that exists in the parent and then use the parent’s function to validate and enable the button.
Codesandbox Demo
Simplified Code: