-
-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(curriculum): add React forms lab (#637)
* add prototype * improve prototype
- Loading branch information
Showing
3 changed files
with
267 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
|
||
<head> | ||
<meta charset="UTF-8" /> | ||
<title>Event RSVP</title> | ||
<link rel="stylesheet" href="styles.css" /> | ||
<script src="https://unpkg.com/react@18/umd/react.development.js"></script> | ||
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> | ||
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | ||
</head> | ||
|
||
<body> | ||
<div id="root"></div> | ||
<script type="text/babel"> | ||
function EventRSVPForm() { | ||
const [formData, setFormData] = React.useState({ | ||
name: '', | ||
email: '', | ||
attendees: '', | ||
dietaryPreferences: '', | ||
bringingOthers: false, | ||
}); | ||
|
||
const [submitted, setSubmitted] = React.useState(false); | ||
|
||
function handleChange(event) { | ||
const { name, value, type, checked } = event.target; | ||
setFormData({ | ||
...formData, | ||
[name]: type === 'checkbox' ? checked : value, | ||
}); | ||
} | ||
|
||
function handleSubmit(event) { | ||
event.preventDefault(); | ||
setSubmitted(true); | ||
} | ||
|
||
return ( | ||
<div className="form-container"> | ||
<h2>Event RSVP Form</h2> | ||
<form onSubmit={handleSubmit}> | ||
<div className="form-group"> | ||
<label>Name:</label> | ||
<input | ||
type="text" | ||
name="name" | ||
value={formData.name} | ||
onChange={handleChange} | ||
placeholder="Your Name" | ||
required | ||
/> | ||
</div> | ||
<div className="form-group"> | ||
<label>Email:</label> | ||
<input | ||
type="email" | ||
name="email" | ||
value={formData.email} | ||
onChange={handleChange} | ||
placeholder="Your Email" | ||
required | ||
/> | ||
</div> | ||
<div className="form-group"> | ||
<label>Number of Attendees:</label> | ||
<input | ||
type="number" | ||
name="attendees" | ||
value={formData.attendees || ''} | ||
onChange={handleChange} | ||
min="1" | ||
placeholder="Number of Attendees" | ||
required | ||
/> | ||
</div> | ||
<div className="form-group"> | ||
<label>Dietary Preferences:</label> | ||
<input | ||
type="text" | ||
name="dietaryPreferences" | ||
value={formData.dietaryPreferences} | ||
onChange={handleChange} | ||
placeholder="Dietary Preferences (Optional)" | ||
/> | ||
</div> | ||
<div className="form-group"> | ||
<label> | ||
Bringing additional guests? | ||
</label> | ||
<input | ||
type="checkbox" | ||
name="bringingOthers" | ||
checked={formData.bringingOthers} | ||
onChange={handleChange} | ||
/> | ||
</div> | ||
<button type="submit">Submit RSVP</button> | ||
</form> | ||
{submitted && ( | ||
<div className="submitted-message"> | ||
<h3>RSVP Submitted!</h3> | ||
<p><strong>Name:</strong> {formData.name}</p> | ||
<p><strong>Email:</strong> {formData.email}</p> | ||
<p><strong>Number of Attendees:</strong> {formData.attendees}</p> | ||
<p><strong>Dietary Preferences:</strong> {formData.dietaryPreferences || 'None'}</p> | ||
<p><strong>Bringing Others:</strong> {formData.bringingOthers ? 'Yes' : 'No'}</p> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
|
||
const container = document.getElementById('root'); | ||
const root = ReactDOM.createRoot(container); | ||
root.render(<EventRSVPForm />); | ||
</script> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
body { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100vh; | ||
margin: 0; | ||
font-family: 'Helvetica Neue', Arial, sans-serif; | ||
background-color: #e0e0e0; | ||
} | ||
|
||
.form-container { | ||
background-color: #ffffff; | ||
padding: 40px; | ||
border-radius: 12px; | ||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); | ||
width: 100%; | ||
max-width: 450px; | ||
text-align: center; | ||
} | ||
|
||
h2 { | ||
margin-bottom: 20px; | ||
font-size: 28px; | ||
color: #333; | ||
font-weight: bold; | ||
} | ||
|
||
form { | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.form-group { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
margin-bottom: 20px; | ||
} | ||
|
||
.form-group label { | ||
flex: 1; | ||
text-align: left; | ||
margin-right: 15px; | ||
font-size: 15px; | ||
color: #555; | ||
} | ||
|
||
.form-group input[type="text"], | ||
.form-group input[type="email"], | ||
.form-group input[type="number"] { | ||
flex: 2; | ||
padding: 10px 12px; | ||
border: 1px solid #ccc; | ||
border-radius: 8px; | ||
width: 100%; | ||
font-size: 15px; | ||
transition: border-color 0.3s ease; | ||
} | ||
|
||
.form-group input:focus { | ||
border-color: #4caf4f4f; | ||
} | ||
|
||
.form-group input[type="checkbox"] { | ||
margin-left: 10px; | ||
} | ||
|
||
button { | ||
background-color: #5957e4; | ||
color: white; | ||
border: none; | ||
padding: 12px 25px; | ||
border-radius: 8px; | ||
cursor: pointer; | ||
font-size: 16px; | ||
font-weight: bold; | ||
margin-top: 15px; | ||
transition: background-color 0.3s ease; | ||
} | ||
|
||
button:hover { | ||
background-color: #413fb3; | ||
} | ||
|
||
.submitted-message { | ||
margin-top: 30px; | ||
text-align: left; | ||
} | ||
|
||
.submitted-message h3 { | ||
color: #5957e4; | ||
margin-bottom: 10px; | ||
font-size: 22px; | ||
} | ||
|
||
@media (max-width: 500px) { | ||
.form-container { | ||
width: 90%; | ||
padding: 20px; | ||
} | ||
|
||
.form-group { | ||
flex-direction: column; | ||
align-items: flex-start; | ||
} | ||
|
||
.form-group label { | ||
text-align: left; | ||
margin-bottom: 5px; | ||
} | ||
|
||
.form-group input[type="text"], | ||
.form-group input[type="email"], | ||
.form-group input[type="number"] { | ||
width: 100%; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
You should create a form with fields for name, email, number of attendees, dietary preferences, and an option to indicate if you are bringing additional guests. | ||
|
||
You should have a text input field where you would enter your name (mandatory). | ||
|
||
You should have an email input field where you would enter your email address (mandatory). The form should validate the format to ensure it is a proper email. | ||
|
||
You should have a number input field where you would enter the number of attendees in the form (mandatory), and the number should not be less than one. | ||
|
||
You should have a text input field where you would enter your dietary preferences, and this information should be optional. | ||
|
||
You should be able to check or uncheck a checkbox to indicate whether you are bringing additional guests. | ||
|
||
You should have a `"Submit RSVP"` button and be able to submit the form by clicking it and the form should prevent the page from reloading upon submission. | ||
|
||
You should see a confirmation message `"RSVP Submitted!"` displayed just below the form after submitting, followed by the details you provided (name, email, number of attendees, dietary preferences, and whether you are bringing additional guests). | ||
Here is a sample message you should see after submitting the form: | ||
|
||
``` | ||
RSVP Submitted! | ||
Name: John Doe | ||
Email: [email protected] | ||
Number of attendees: 2 | ||
Dietary preferences: None | ||
Bringing additional guests: Yes | ||
``` | ||
|
||
You should not be able to submit the form if the required fields (name, email, and number of attendees) are not filled out, ensuring proper validation. | ||
|
||
You should see the default message "None" if no dietary preferences are entered after submitting the form. |