Does anyone have any tips for overriding when it displays NAN and Infinity when just one value is input? I've been trying for longer than I'd like to admit to solve it on my own, but nothing seems to be working. I think it may have something to do with the calculator trying to calculate while not all the input fields have values, but I can't seem to figure out a solution.
Ozmar Mendoza
@ozzy1136All comments
- @kileybelangaSubmitted over 1 year ago@ozzy1136Posted over 1 year ago
You're getting that error due to dividing by 0 for the total number of people. So:
- Instead of using
<input type="text"/>
, I recommend using<input type="number"/>
for the bill amount, number of people, and custom tip percentage. For the bill amount you could addvalue="0" step="0.01" min="0"
attributes, for number of people you can addvalue="1" min="1"
attributes, and for custom tip percentage you can addplaceholder="Custom" min="0"
attributes. With a text input, there is the chance that a user inputs letters or other characters that are invalid when you calculate the tip and total per person. - You should combine
calculateBill
andcalculateTip
into one function, because you are calculating the same variables in both functions. For example:function handleInputChange(e) { e.preventDefault(); // No need to cast value to a number type since you're using number inputs now const bill = billInput.value; const people = numberOfPeopleDiv.value; let tip; if (id == "tipButtonOne") { tip = tipButtonDivOne.value; } else if (id == "tipButtonTwo"){ tip = tipButtonDivTwo.value; } else if (id == "tipButtonThree"){ tip = tipButtonDivThree.value; } else if (id == "tipButtonFour"){ tip = tipButtonDivFour.value; } else if (id == "tipButtonFive"){ tip = tipButtonDivFive.value; } else { tip = customTipInputDiv.value; } const tipPercentage = tip / 100; const tipAmount = bill * tipPercentage; // Be careful using innerHTML, you can find plenty of articles for why perPersonTipDiv.innerText = `$${(tipAmount / people).toFixed(2)}`; perPersonTotalDiv.innerText = `$${((tipAmount + bill) / people).toFixed(2)}`; };
- Instead of
onkeyup
, you can useonchange="handleInputChange"
when working with updating input elements.
That should get you to a good spot. There are some other things you could do like creating a variable that saves the last clicked tip percentage, so you can remove the if...else statements and just get the value of that variable.
0 - Instead of using
- @great1gretaSubmitted about 2 years ago
- i tried to introduce if-else statement so the page would not load if the rating is not selected:
submitButton.addEventListener("click", () => {
if (evaluation) {
receiptContainer.classList.remove("hidden");
mainContainer.style.display = "none";
} else {
receiptContainer.classList.add("hidden");
} });
but it didint work and i couldnt come up with another way to do it. i looked up other peoples solutions for inspiration, but they all looked so complicated and unreasonably long.
- apparently, i suck at responsiveness. this is a second project that i fail to adjust it to a mobile device.
@ozzy1136Posted about 2 years agoGreat job with this one!
Strictly related to the question you asked, I think it would be easier to use radio buttons instead of regular buttons. This way, you can check if a value was submitted for the rating. This solution uses the FormData API, which has great browser support.
A simple example:
// index.html ... <form> <label>1 <input type="radio" name="rating" value="one" /> </label> // More radio buttons with labels ... <input type="submit" value="Submit" /> </form> ... // app.js const formEl = document.querySelector("form"); formEl.addEventListener("submit", (e) => { e.preventDefault(); new FormData(e.target); } formEl.addEventListener("formdata", (e) => { // e.formData is a JavaScript iterator object, so you have to loop over it // data will be in the form of [name, value] // You could also do for (const [name, value] of e.formData) {...} for (const data of e.formData) { if (data[0] === "rating") { // There was a rating button selected ... } } // There was not a rating button selected ... }
Check the MDN Web Docs for more information about FormData. Using radio buttons with labels also takes more effort to make the buttons look how you need to, so I would suggest you look for guides that go over this.
I imagine you could loop over the radio buttons on submit and test for a
checked
value instead.Marked as helpful1 - @hkmarcootSubmitted about 2 years ago
I found difficult to position the error icon & the submit button relative to form input.
I am a bit unsure how to make email validation in real time since it is now checking only when user click on the submit button. Also, after user input the correct email and submit it, the validation stops and not responses to new wrong email.
@ozzy1136Posted about 2 years agoYou have laid things out pretty well, nice job!
I would recommend you look into the
<picture/>
element to handle the image. You can use this element with child<source/>
elements that use media queries to serve the image based on the viewport size. Check out the MDN Web Docs for a reference.For the e-mail input, you are using the
<label/>
element incorrectly. This element is used to describe the input it references and usually doesn't contain images; in your case, it could be<label>Submit</label>
, since the submit button doesn't have any visible text. Additionally, the browser already displays an error if the input isn't formatted correctly as an e-mail address. If you want to implement your own validation, check out the MDN Web Docs for a detailed guide.Lastly, read through the Accessibility and HTML reports for your solution here on Frontend Mentor, I've found them very helpful for making sure I have the basics correct.
Marked as helpful0 - @adetoye-devSubmitted about 2 years ago
Any tips on improving this project is welcomed :)
@ozzy1136Posted about 2 years agoIt looks pretty good, well done!
On my first look at your project, the first thing you need to do is remove the
width
property on the cards. Currently, you havewidth: 23rem
, but this makes the cards break out of the grid container. If you want each card to be a certain width and you are using CSS grid, you can setgrid-template-columns: repeat(auto-fit, minmax(23rem, 1fr))
on the grid container. Check out the MDN Web Docs for more information.Also, I would put the search container inside
<main/>
, since it is related to the cards and would make it an essential part of the document. Check out the MDN Web Docs for more information about HTML sectioning elements.Marked as helpful1 - @Chiwetalu345Submitted about 2 years ago
please would you highlight what section of my code is subpar according to industry standards?
@ozzy1136Posted about 2 years agoYour code looks great!
One change I would make is to place the <img/> inside the <article/>, because the image is related to the other content inside the <article/>.
The only other change I would make is to move all the CSS styles that affect the card from the <section/> to the <article/> element (e.g. width, background-color, padding, border-radius). This will make it easier to reuse the code if you wanted to add another card on the page.
Marked as helpful0 - @ThomasMumladzeSubmitted about 2 years ago
application has only one bug when cardholder name filed is fill after confirm the form program continue work... what ever filed work perfect and resposnive works only 930px
@ozzy1136Posted about 2 years agoTake a look at CSS media queries: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries. You can update styles based on how large the viewport width is. For your project, you can use a media query to make the divs stack vertically on small viewports and then lay horizontally on large viewports.
.wrapper { flex-direction: column; } @media screen and (min-width: 930px) { .wrapper { flex-direction: row; } }
Also, make sure to place all the main content of the page inside <main></main> elements. For your project, you can change
<div class="wrapper">
into<main class="wrapper">
or you can place the div inside a <main> element. Take a look at this reference for HTML sectioning elements: https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning.0 - @Justlana13thSubmitted about 2 years ago
the hardest part is creating the responsive navbar. it took me like 3 hours to finish this section and im not really sure with the Creations sections, in the mobile design, the image looks bad. can anyone tell me the best practices for this section? thank you.
@ozzy1136Posted about 2 years agoI haven't done this challenge, but if you only get the desktop-size images, then you can use the object-fit and object-position CSS properties on the <img/> element in order to resize the photo.
If you also get the mobile-size images, then you can use the <picture/> element with media queries in order to tell the browser which image to use at which viewport size. More info at the MDN web docs: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture.
Edit: You should move the divs with class "main" and "creations" into <main></main> elements for better semantics and accessibility. Read more about sectioning elements on the MDN web docs: https://developer.mozilla.org/en-US/docs/Web/HTML/Element#content_sectioning.
0 - @guedesycSubmitted about 2 years ago
I'm still not training responsiveness.
@ozzy1136Posted about 2 years agoTake a look at the reference for the @media rule and you will be able to adjust styles based on how large the viewport width is: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries. So, you could write:
main { flex-direction: column; } @media screen and (min-width: 650px) { main { flex-direction: row; } }
This way by default the card will be laid out vertically, but once the viewport gets too big it will place the items horizontally. Also, it is usually better to begin with the mobile design and build on top of that.
0 - @yolanda1089Submitted about 2 years ago
What are the standard breakpoints? I only added 2 breakpoints, and I think the hero image is a bit big when I switch flex-direction. Any thoughts?
@ozzy1136Posted about 2 years agoYour finished project looks good! For the hero image, setting a max-width in CSS will work just fine. As for the breakpoints, you should only use media queries when you absolutely need to (i.e. when the page styles break). Using responsive units (e.g. vw, vh) and the CSS math functions min(), max(), and clamp() can help to cut down on the need for breakpoints.
0 - @ssembatya-dennisSubmitted about 2 years ago
Hi everyone 👋🏽, Am very glad to have completed my second JS project but I faced a hard time implementing the UI design and the approach I took for using Positioning made it tricky to make my solution very responsive and I have noticed icons are not rendered well in Firefox on small mobile media queries so I humbly request for ideas on how to improve my solution and any feedback on my solution more especially highlighting weak areas in my code will greatly be appreciated.
@ozzy1136Posted about 2 years agoYour finished project looks pretty good! However, there are a couple things you should fix.
First, you should put the main content of the page between <main></main> elements. At the moment, you have all of your content inside a <header/> elements, but this is bad for semantics and accessibility. Usually, only headings and, if it is the page header, site navigation links. Take a look at this <header> reference for other examples of what type of content should go between <header/> elements: https://developer.mozilla.org/en-US/docs/web/html/element/header.
Second, consider using CSS grid for laying out the content on the page. Using absolute positioning is difficult to maintain for page responsiveness and grid is perfect for that. Check out this reference for CSS grid: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout.
Lastly, I would remove the <div/> that wraps the email input and icons, because these items are not really related. This is just a personal preference.
Marked as helpful1