This is a solution to the Conference ticket generator challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.
Users should be able to:
- Complete the form with their details
- Receive form validation messages if:
- Any field is missed
- The email address is not formatted correctly
- The avatar upload is too big or the wrong image format
- Complete the form only using their keyboard
- Have inputs, form field hints, and error messages announced on their screen reader
- See the generated conference ticket when they successfully submit the form
- View the optimal layout for the interface depending on their device's screen size
- See hover and focus states for all interactive elements on the page
| Form page | Form page(Img) |
|---|---|
![]() |
![]() |
| Ticket page |
|---|
![]() |
- Solution URL: GitHub solution site
- Live Site URL: GitHub live site
I roughly finished the HTML and CSS of both pages, before starting with the JS part of this project. After I was done with the JS on each page, I polished the CSS a bit and made my JS code more readable by adding comments and the likes.
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- Vanilla JS
<!-- I learnt about the file input and its attributes -->
<input type="file" accept=".png, .jpeg">
<!-- I learnt how to use a label in the place of its input tag -->
<input type="file" name="change-button" id="change-button" accept=".png, .jpg, .jpeg">
<label for="change-button">Change image</label>/* Hiding the input button and styling the label */
#change-button {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.output-imgArea, .complete-buttons-wrapper > button, #change-button + label {
color: white;
background-color: hsla(252, 6%, 83%, 0.24);
padding: 0.4rem 0.4rem;
border: solid 1px var(--grey2);
border-radius: 10px;
}
.complete-buttons-wrapper {
display: none;
}
.complete-buttons-wrapper > button:hover, #change-button:hover + label {
color: var(--grey1);
text-decoration: underline;
}// I learnt how to use the FileReader interface.
function imgHandler(file){
if(file.length === 0){
alert("No files selected.");
return;
};
if (!file.type.startsWith("image/")) {
alert("Only image files are allowed.");
return;
};
if (!file.name.endsWith(".png") && !file.name.endsWith(".jpg") ) {
alert("Only JPG or PNG image files are allowed.");
return;
};
if(file.size > 500 * 1024){
imgErrorMsg.style.display = 'flex';
imgReqMsg.style.display = 'none';
clearTimeout(imgTimeOut)
imgTimeOut = setTimeout(() => {
imgErrorMsg.style.display = 'none';
imgReqMsg.style.display = 'flex';
}, 5000);
return;
}
const reader = new FileReader();
reader.onload = (e) => {
imgOutput.src = e.target.result;
};
reader.onerror = (err) => {
console.error(`Error reading file: ${err}`)
alert("An error occured while reading the file.")
};
reader.readAsDataURL(file);
stepsText.style.display = 'none'
buttonsWrapper.classList.add('show')
fileInput.style.pointerEvents = 'none';
}- Improve my CSS skills
- A better understanding of JS
- MDN FileReader interface - Explains the FileReader interface.
- Cloduinary FileReader Tutorial - Helped me implement the drop feature.
- Website - InfamousTheif
- Frontend Mentor - @InfamousTheif


