Given a react form with multiple radio buttons and a text input that is visible only when the other option radio button is selected, I currently have the submit button disabled until a radio button is selected. However, if the other option is selected, the submit button will still work even if there is no text in the input field associated with it. How can I check the length of the input box if and only if the other option is selected?
class CancelSurvey extends React.Component {
constructor (props) {
super(props)
this.state = {
reasons: [],
reason: {},
otherReasonText: undefined,
submitting: false
}
this.processData = this.processData.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.setReason = this.setReason.bind(this)
this.setOtherReasonText = this.setOtherReasonText.bind(this)
this.otherReason = {
reason_id: 70,
client_reason: 'other'
}
}
componentDidMount () {
this.fetchSurvey()
}
/**
* Fetch reasons
*/
fetchSurvey (cb) {
superagent
.get('/api/user/survey')
.then(this.processData)
}
processData (data) {
this.setState({ reasons: data.body })
}
async handleSubmit (e) {
e.preventDefault()
await this.setState({ submitting: true })
const { reason, otherReasonText } = this.state
superagent
.post('/api/user/survey')
.send({
optionId: reason.reason_id,
optionText: reason.client_reason,
otherReasonText
})
.then(async (data) => {
await this.setState({ submitting: false })
if (data.body.success) {
this.props.setStep(OFFER)
}
})
}
setOtherReasonText (e) {
this.setState({ otherReasonText: e.target.value })
}
setReason (reason) {
this.setState({ reason })
}
/**
* render
*/
render (props) {
const content = this.props.config.contentStrings
const reasons = this.state.reasons.map((reason, i) => {
return (
<div
className='form-row'
key={i}>
<input type='radio'
id={reason.reason_id}
value={reason.client_reason}
name='reason'
checked={this.state.reason.reason_id === reason.reason_id}
onChange={() => this.setReason(reason)} />
<label htmlFor={reason.reason_id}>{reason.client_reason}</label>
</div>
)
})
return (
<div className='cancel-survey'>
<form className='cancel-survey-form'>
{ reasons }
<div className='form-row'>
<input
type='radio'
id='other-option'
name='reason'
onChange={() => this.setReason(this.otherReason)} />
<label htmlFor='other-option'>
Other reason
</label>
</div>
{ this.state.reason.reason_id === 70 &&
<div>
<input
className='valid'
type='text'
id='other-option'
name='other-text'
placeholder="placeholder"
onChange={this.setOtherReasonText} />
</div>
}
<div className='button-row'>
<button
disabled={!this.state.reason.client_reason}
className={btnClassList}
onClick={this.handleSubmit}>
<span>Submit</span>
</button>
</div>
</form>
</div>
)
}
}
export default CancelSurvey
disabled={
!this.state.reason.client_reason
||
(this.state.reason.client_reason === 'other' && !this.state.otherReasonText)
}
If you want to make sure otherReasonText is not just empty spaces, use otherReasonText: '' as initial state then check !this.state.otherReasonText.trim().
Do some conditional logic before like:
const reasonId = this.state.reason.reason_id;
const otherReasonText = this.state.otherReasonText;
const clientReason = this.state.reason.client_reason;
const shouldDisableButton = !clientReason || (reasonId === 70 && otherReasonText.length === 0)
...
<div className='button-row'>
<button
disabled={shouldDisableButton}
className={btnClassList}
onClick={this.handleSubmit}>
<span>Submit</span>
</button>
</div>
Related
I have passed my user ID into my 'OrderMessages' component but in my function says undefined. When my user submits a messages using the form in the handleFormSubmit function I need the UserID and the datetime of the message. I have managed to get the date and time but when trying to console log to get the UserID I keep getting an error. I have tried this.props.... and this.state but both say undefined, can you please help. In my constructor I have tested using const UserId = props.location.state.UserID; and in debug I can see this has correctly got the UserID so im not sure how to get it into my hadleFormSubmit function.
import React from "react";
import Moment from "moment";
import { Form, Button } from "react-bootstrap";
class OrderMessages extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: false,
checkboxes: [],
selectedId: [],
formLableSelected: "",
formSelectedSubject: "",
formSelectedSubjectId: "",
formNewSubject: "",
formChainID: "",
formMessageBody: "",
userId: '',
};
const UserId = props.location.state.UserID;
}
componentDidMount() {
this.setState({ isLoading: true });
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url =
"myURL" +
this.props.location.state.orderNumber;
fetch(proxyurl + url)
.then((res) => res.json())
.then((data) => this.setState({ data: data, isLoading: false }));
}
handleClick = (id) => {
if (this.state.selectedId !== id) {
this.setState({ selectedId: id });
} else {
this.setState({ selectedId: null });
}
};
setformSubjectID(messageSubject) {
if (messageSubject.subject === this.state.formSelectedSubject) {
this.setState({ formSelectedSubjectId: messageSubject.messageSubjectId });
}
}
handleChangeSubject = (event) => {
this.setState({ formSelectedSubject: event.target.value });
this.state.data.message_Subjects.map((ms) => this.setformSubjectID(ms));
};
handleFormSubmit(e) {
e.preventDefault();
// get current time
let submit_time = Moment().format("ddd DD MMM YYYY HH:mm:ss");
console.log("messageDatetime", submit_time);
// get user id THIS IS WHAT DOESN’T WORK
console.log("messageSentFrom", this.state.userId);
console.log("messageSentFrom", this.props.location.state.UserID);
}
render() {
const { data, isLoading } = this.state;
if (isLoading) {
return <p>Loading ...</p>;
}
if (data.length === 0) {
return <p> no data found</p>;
}
console.log("mess: ", data);
return (
<div>
<div className="sendMessageContent">
<Form className="sendMessageForm" onSubmit={this.handleFormSubmit}>
<Form.Group className="formRadio">
<Form.Check
className="formRadiob"
type="radio"
label="New chat"
value="new"
name="neworexisitng"
id="New Message"
onChange={this.onFormMessageChanged}
defaultChecked
/>
<Form.Check
className="formRadiob"
type="radio"
label="Reply to exisiting chat"
value="reply"
name="neworexisitng"
id="exisiting Message"
onChange={this.onFormMessageChanged}
/>
</Form.Group>
{this.returnCorrectFormFields(data)}
<Form.Group>
<Form.Label>Message Body</Form.Label>
<Form.Control as="textarea" rows={3} />
</Form.Group>
<Button variant="primary" type="submit">
Send Message
</Button>
</Form>
</div>
</div>
);
}
returnCorrectFormFields(data) {
if (this.state.formLableSelected === "new") {
return this.newMessageSubject(data);
} else {
return this.choseMessageSubject(data);
}
}
choseMessageSubject(data) {
return (
<Form.Group>
<Form.Label>Select the message subject</Form.Label>
<Form.Control as="select" onChange={this.handleChangeSubject}>
<option value="0">Choose...</option>
{data.message_Subjects.map((ms) => (
<option value={ms.subject}>{ms.subject}</option>
))}
</Form.Control>
</Form.Group>
);
}
newMessageSubject(data) {
return (
<Form.Group>
<Form.Label>Enter Message Subject</Form.Label>
<Form.Control type="text" placeholder="Enter message subject" />
</Form.Group>
);
}
onFormMessageChanged = (event) => {
this.setState({
formLableSelected: event.target.value,
});
};
getAllMessageInChain(messageChain) {
return (
<div className="messageHistory">
<div className="messageHistoryHeader">
<div className="innerMS-history-body">Message</div>
<div className="innerMS">Date and Time</div>
<div className="innerMS">Message sent by</div>
</div>
{messageChain.map((ms) => (
<div className="messageHistoryBody">
<div className="innerMS-history-body">{ms.messageBody}</div>
<div className="innerMS">
{Moment(ms.dateTime).format("ddd DD MMM YYYY hh:mm:ss")}
</div>
<div className="innerMS">{ms.sentFromId}</div>
</div>
))}
</div>
);
}
getLatestMessageDateTime(messageChain) {
const lastmessage = messageChain.length - 1;
Moment.locale("en");
var dt = messageChain[lastmessage].dateTime;
return Moment(dt).format("ddd DD MMM YYYY hh:mm:ss");
}
}
export default OrderMessages;
The scope of this isn't the component in the function you're using.
Either change handleFormSubmit to this to bind this automatically.
handleFormSubmit = (e) => {
// .. your code
}
or bind this manually in the constructor
constructor() {
// ..other code
this.handleFormSubmit = this.handleFormSubmit.bind(this)
}
Good day so I have a question about firebase and perhaps my code as well I wrote some code in JSX and React linked to Firebase and the Button that I'm using to delete is not working properly.
I'm using Parent Child props to pass the function into the page that is needed to be deleted but there is no functionality. I need help thanks!
this is the parent where the function is located :
import React from 'react';
import fire from '../config/firebase';
import Modal from 'react-modal';
// import "firebase/database";
// import 'firebase/auth';
import NotesCard from './note-card';
Modal.setAppElement('#root');
export default class Notes extends React.Component {
_isMounted = false;
constructor(props) {
super(props);
this.state = {
notes: [],
showModal: false,
loggedin: false
};
this.handleOpenModal = this.handleOpenModal.bind(this);
this.handleCloseModal = this.handleCloseModal.bind(this);
this.handleAddNote = this.handleAddNote.bind(this);
this.handleRemoveNote = this.handleRemoveNote.bind(this);
}
componentDidMount() {
this._isMounted = true;
fire.auth().onAuthStateChanged((user) => {
if(user){
// call firebase from import fire
// grab userData and push it to the dataArray
fire.database().ref(`users/${user.uid}/notes`).on('value', (res) => {
const userData = res.val()
const dataArray = []
for(let objKey in userData) {
userData[objKey].key = objKey
dataArray.push(userData[objKey])
}
// set in the state
if(this._isMounted){
this.setState({
notes: dataArray,
loggedin: true
})
}
});
}else {
this.setState({loggedin: false})
}
});
};
componentWillUnmount() {
this._isMounted = false;
}
handleAddNote (e) {
e.preventDefault()
const note = {
title: this.noteTitle.value,
text: this.noteText.value
}
// reference where we can push it
const userId = fire.auth().currentUser.uid;
const dbRef = fire.database().ref(`users/${userId}/notes`);
dbRef.push(note)
this.noteTitle.value = ''
this.noteText.value = ''
this.handleCloseModal()
}
handleRemoveNote(key) {
const userId = fire.auth().currentUser.uid;
const dbRef = fire.database().ref(`users/${userId}/notes/${key}`);
dbRef.remove();
}
handleOpenModal (e) {
e.preventDefault();
this.setState({
showModal: true
});
}
handleCloseModal () {
this.setState({
showModal: false
});
}
render() {
return (
<div>
<button onClick={this.handleOpenModal}>create Note</button>
<section className='notes'>
{
this.state.notes.map((note, indx) => {
return (
<NotesCard
note={note}
key={`note-${indx}`}
handleRemoveNote={this.handleRemoveNote}
/>
)
}).reverse()
}
</section>
<Modal
isOpen={this.state.showModal}
onRequestClose={this.handleCloseModal}
shouldCloseOnOverlayClick={false}
style={
{
overlay: {
backgroundColor: '#9494b8'
},
content: {
color: '#669999'
}
}
}
>
<form onSubmit={this.handleAddNote}>
<h3>Add New Note</h3>
<label htmlFor='note-title'>Title:</label>
<input type='text' name='note-title' ref={ref => this.noteTitle = ref} />
<label htmlFor='note-text'>Note</label>
<textarea name='note-text' ref={ref => this.noteText = ref} placeholder='type notes here...' />
<input type='submit' onClick={this.handleAddNote} />
<button onClick={this.handleCloseModal}>close</button>
</form>
</Modal>
</div>
)
}
}
and this is where the function is being called :
import React from 'react';
import fire from '../config/firebase';
export default class NotesCard extends React.Component {
constructor(props) {
super(props);
this.state = {
editing: false,
note: {}
}
this.handleEditNote = this.handleEditNote.bind(this);
this.handleSaveNote = this.handleSaveNote.bind(this);
}
handleEditNote() {
this.setState({
editing: true
})
}
handleSaveNote(e) {
e.preventDefault()
const userId = fire.auth().currentUser.uid;
const dbRef = fire.database().ref(`users/${userId}/notes/${this.props.note.key}`);
dbRef.update({
title: this.noteTitle.value,
text: this.noteText.value
})
this.setState({
editing: false
})
}
render() {
let editingTemp = (
<span>
<h4>{this.props.note.title}</h4>
<p>{this.props.note.text}</p>
</span>
)
if(this.state.editing) {
editingTemp = (
<form onSubmit={this.handleSaveNote}>
<div>
<input
type='text'
defaultValue={this.props.note.title}
name='title'
ref={ref => this.noteTitle = ref}
/>
</div>
<div>
<input
type='text'
defaultValue={this.props.note.text}
name='text'
ref ={ref => this.noteText = ref}
/>
</div>
<input type='submit' value='done editing' />
</form>
)
}
return (
<div>
<button onClick={this.handleEditNote}>edit</button>
<button onClick={this.props.handleRemoveNote(this.state.note.key)}>delete</button>
{editingTemp}
</div>
)
}
}
Thank you in advance for taking a look at this code.
Second iteration answer
Working sandbox
Problem
looking at https://codesandbox.io/s/trusting-knuth-2og8e?file=/src/components/note-card.js:1621-1708
I see that you have this line
<button onClick={()=> this.props.handleRemoveNote(this.state.note.key)}>delete
Yet your state.note declared as an empty map in the constructor:
this.state = {
editing: false,
note: {}
}
But never assigned a value using this.setState in the component
Solution
Change it to:
<button onClick={()=> this.props.handleRemoveNote(**this.props.note.key**)}>delete</button>
First iteration answer
NotesCard's buttons is firing the onClick callback on render instead on click event.
This is because you have executed the function instead of passing a callback to the onClick handler
Change
<button onClick={this.props.handleRemoveNote(this.state.note.key)}>delete</button>
To
<button onClick={()=> this.props.handleRemoveNote(this.state.note.key)}>delete</button>
I created a simple image uploader component that is rendered in a new-image-form that extends a form. but when handling a change(an image upload), the state is updated with an empty opbject (and not with the file object). I tried to debug it but anything goes right until this.setState. Can anyone helps?
NewImagesForm :
class NewImagesForm extends Form {
state = {
data: {
_id: 0,
name: "",
file: null,
},
errors: {},
apiEndpoint: "",
};
render() {
return (
<div className="new-menu-item-form">
<form onSubmit={this.handleSubmit}>
{this.renderInput("name", "Name")}
{this.renderUploadFile("file", "Upload")}
{this.renderButton("Add")}
</form>
</div>
);
}
Form
class Form extends Component {
state = { data: {}, errors: {} };
handleFileUpload = (e) => {
const data = { ...this.state.data };
data[e.currentTarget.name] = e.target.files[0];
this.setState({ data });
};
renderUploadFile(name, label) {
const { data } = this.state;
return (
<UploadImage
name={name}
label={label}
value={data[name]}
onChange={this.handleFileUpload}
></UploadImage>
);
}
}
export default Form;
File Upload Component
const UploadImage = ({ name, label, error, onChange }) => {
return (
<div className="input-group">
<div className="custom-file">
<input
type="file"
onChange={onChange}
className="custom-file-input"
id={name}
name={name}
></input>
{label && (
<label className="custom-file-label" htmlFor={name}>
{label}
</label>
)}
</div>
<div className="input-group-append">
<button className="btn btn-outline-secondary" type="button">
Button
</button>
</div>
</div>
);
};
export default UploadImage;
First of all, react does not recommend the use of extends, because of the combination of extends.
In the Form component, the setState() trigger the render() , but there is no render(). setState does not allow renderUploadFile to be re-executed.
It would be a good idea to use the UploadImage component in the NewImagesForm component. Don't let NewImagesForm extends Form.
But the exactly same way works for me with custom input text and custom select boxes, see the differences:
handleChange = (e) => {
const data = { ...this.state.data };
data[e.currentTarget.name] = e.currentTarget.value;
this.setState({ data });
};
handleFileUpload = (e) => {
const data = { ...this.state.data };
data[e.currentTarget.name] = e.target.files[0];
this.setState({ data });
};
The Reactjs code below works excellently by posting and retrieving Users newStatus from a form input to and from an API.
Now I want to add two additional form form inputs (newTitle and newEvent) as per code below
<input className="input-status" name="newTitle"
value={this.state.newTitle}
onChange={e => this.handleNewStatusChange(e)}
placeholder="your Title"
/>
<input className="input-status" name="newEvent"
value={this.state.newEvent}
onChange={e => this.handleNewStatusChange(e)}
placeholder="Your Event Centre Name"
/>
I have also implemented newEvent and newTitle variables in code where possible. My issue is that if type in the first form inputs (eg newStatus) it gets replicated or inserted in all other remaining two forms inputs as can be seen in the screenshot below.
And I believe that's why only the newStatus get posted and retrieved.
I have commented out all newEvent and newTitle variables in code so readers can see where I am wrong.
Here is the code profile.jsx:
import React, { Component } from 'react';
import {
isSignInPending,
loadUserData,
Person,
getFile,
putFile,
lookupProfile
} from 'blockstack';
import Status from './Status.jsx';
const avatarFallbackImage = 'https://mysite/onename/avatar-placeholder.png';
const statusFileName = 'statuses.json'
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = {
person: {
name() {
return 'Anonymous';
},
avatarUrl() {
return avatarFallbackImage;
},
},
username: "",
newStatus: "",
//newTitle: "",
// newEvent: "",
statuses: [],
statusIndex: 0,
isLoading: false
};
this.handleDelete = this.handleDelete.bind(this);
this.isLocal = this.isLocal.bind(this);
}
componentDidMount() {
this.fetchData()
}
handleNewStatusChange(event) {
this.setState({
newStatus: event.target.value,
//newTitle: event.target.value,
//newEvent: event.target.value
})
}
handleNewStatusSubmit(event) {
this.saveNewStatus(
this.state.newStatus,
//this.state.newTitle,
//this.state.newEvent
)
this.setState({
newStatus: "",
//newTitle: "",
//newEvent: "",
})
}
handleDelete(id) {
const statuses = this.state.statuses.filter((status) => status.id !== id)
const options = { encrypt: false }
putFile(statusFileName, JSON.stringify(statuses), options)
.then(() => {
this.setState({
statuses
})
})
}
saveNewStatus(statusText) {
let statuses = this.state.statuses
let status = {
id: this.state.statusIndex++,
text: statusText.trim(),
//textTitle: statusText.trim(),
//textEvent: statusText.trim(),
created_at: Date.now()
}
statuses.unshift(status)
const options = { encrypt: false }
putFile(statusFileName, JSON.stringify(statuses), options)
.then(() => {
this.setState({
statuses: statuses
})
})
}
fetchData() {
if (this.isLocal()) {
this.setState({ isLoading: true })
const options = { decrypt: false, zoneFileLookupURL: 'https://myapi/v1/names/' }
getFile(statusFileName, options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
person: new Person(loadUserData().profile),
username: loadUserData().username,
statusIndex: statuses.length,
statuses: statuses,
})
})
.finally(() => {
this.setState({ isLoading: false })
})
} else {
const username = this.props.match.params.username
this.setState({ isLoading: true })
lookupProfile(username)
.then((profile) => {
this.setState({
person: new Person(profile),
username: username
})
})
.catch((error) => {
console.log('could not resolve profile')
})
const options = { username: username, decrypt: false, zoneFileLookupURL: 'https://myapi/v1/names/'}
getFile(statusFileName, options)
.then((file) => {
var statuses = JSON.parse(file || '[]')
this.setState({
statusIndex: statuses.length,
statuses: statuses
})
})
.catch((error) => {
console.log('could not fetch statuses')
})
.finally(() => {
this.setState({ isLoading: false })
})
}
}
isLocal() {
return this.props.match.params.username ? false : true
}
render() {
const { handleSignOut } = this.props;
const { person } = this.state;
const { username } = this.state;
return (
!isSignInPending() && person ?
<div className="container">
<div className="row">
<div className="col-md-offset-3 col-md-6">
<div className="col-md-12">
<div className="avatar-section">
<img
src={ person.avatarUrl() ? person.avatarUrl() : avatarFallbackImage }
className="img-rounded avatar"
id="avatar-image"
/>
<div className="username">
<h1>
<span id="heading-name">{ person.name() ? person.name()
: 'no name found' }</span>
</h1>
<span>{username}</span>
{this.isLocal() &&
<span>
|
<a onClick={ handleSignOut.bind(this) }>(Logout)</a>
</span>
}
</div>
</div>
</div>
{this.isLocal() &&
<div className="new-status">
<div className="col-md-12">
<textarea className="input-status" name="newStatus"
value={this.state.newStatus}
onChange={e => this.handleNewStatusChange(e)}
placeholder="What's on your mind?"
/>
<input className="input-status" name="newTitle"
value={this.state.newTitle}
onChange={e => this.handleNewStatusChange(e)}
placeholder="your Title"
/>
<input className="input-status" name="newEvent"
value={this.state.newEvent}
onChange={e => this.handleNewStatusChange(e)}
placeholder="Your Event Centre Name"
/>
</div>
<div className="col-md-12 text-right">
<button
className="btn btn-primary btn-lg"
onClick={e => this.handleNewStatusSubmit(e)}
>
Submit
</button>
</div>
</div>
}
<div className="col-md-12 statuses">
{this.state.isLoading && <span>Loading...</span>}
{
this.state.statuses.map((status) => (
<Status
key={status.id}
status={status}
handleDelete={this.handleDelete}
isLocal={this.isLocal}
/>
))
}
</div>
</div>
</div>
</div> : null
);
}
}
Here is just sample part for for status.jsx showing how I successfully return the status:
//some coding...
return (
<div className="status">
<div className="status-text">
{status.text}
/*
{status.textTitle} {status.textEvent}
*/
</div>
</div>
)
You can use the name attribute of the input field to your advantage.
And update your change handler function:
handleNewStatusChange(event) {
this.setState({
[event.target.name]: event.target.value,
})
}
more info on { [key]: value }
I cant seem to figure this out.
I have a form that is validated by formik.
When i click the search button, I make an api call to get a list of addresses.
When i click on one of those addresses, I want to populate the inputs with the data from the clicked address.
I can do all of the above except for the last part. I have tried using document.getElementById.innerHTML, setting it in state and having the input controlled by that state object, but i cant seem to get it to populate with any data.
import React, { Component } from 'react';
import { Formik, Form, Field } from 'formik';
import Axios from 'axios';
class CharityAgreement extends Component {
constructor(props) {
super(props);
this.state = {
response: [],
visible: true,
address: ''
}
}
postcodeChange = (e) => {
console.log(e.target.value);
this.setState({ 'postcode': e.target.value })
}
searchPostcode = () => {
this.setState({ 'visible': true });
if (this.state.postcode.length > 0) {
Axios.get('post code api lookup here')
.then(response => {
this.setState({ 'response': response.data });
console.log('response data:', response.data);
})
} else {
}
}
addressClick = (e) => {
console.log('CLICKED ADDRESS:', e.target.innerHTML);
this.setState({ 'visible': false });
}
render() {
const result = this.state.response.map((item) => {
if (this.state.visible === true) {
return (
<p key={item.Id} onClick={this.addressClick} className='lookup-data'>{item.address1Field} {item.address2Field} {item.townField} {item.countyField}</p>
)
} else {
}
})
return (
<div className='body-wrapper'>
<main id='mainContent' className='container'>
<div className='page-content-wrapper'>
<div className='raised-bordered-wrapper'>
<div className='raised-bordered quiz form'>
<Formik
initialValues={{
address_1:'',
}}
validate={(values) => {
const errors = {};
if (!values.address_1) errors.address_1 = 'Required';
return errors;
}}
onSubmit={this.handleSubmit}
render={({
touched,
errors,
values,
handleChange,
handleBlur,
handleSubmit
}) => (
<Form>
<div className='form-row'>
<span className='form-cell-wrapper'>
<label>Postcode Lookup</label>
<Field
name='postcode-lookup'
type='text'
onChange={this.postcodeChange}
/>
<button className='btn' onClick={this.searchPostcode}>Search</button>
</span>
</div>
{result}
<div className='form-row'>
<h5>License Code and Area</h5>
<span className='form-cell-wrapper'>
<label>Address Line 1</label>
<Field
name='address_1'
value={values.address_1}
onChange={handleChange}
id='address'
type='text'
style={{
borderColor:
errors.address_1 && touched.address_1 && "tomato"
}}
/>
</span>
</div>
</Form>
)}
/>
</div>
</div>
</div>
</main>
</div>
)
}
}
export default CharityAgreement;