Responsive Mortgage Calculator built with Vue3, TailwindCSS and TS
Design comparison
Solution retrospective
This was an interesting challenge overall. I'm most proud of how I was able to get the input with the extra text into a reuseable component where the developer can specify which side they want the text to be at(left/right). I would definitely use a more cleaner code approach next time.
What challenges did you encounter, and how did you overcome them?I was trying to get the form validations without using any extra state or Javascript code, but It seemed to be harder so I might just change to javascript instead for the validations. Also had a small issue with the enhanced inputs and validations.
What specific areas of your project would you like help with?I would like help with doing the validation manually as using HTML+CSS for the validation was a bit more challenging than expected. Also cleaning up the code and making it more accessible.
Community feedback
- @AtatraPosted 4 months ago
Well done, looks clean! :)
Seems like I'm not the only one who tried to factorize the inputs into a single one. Though your code is cleaner than mine. Your CSS solution for hidding/showing the error is interesting.
-
But maybe you could hide the error messages before the user submits the form? It would make the user experience a bit better I think. But you would need to add some javascript.
-
I'm not acquainted with VueJS so it's probably not true (though it doesn't seem so different from NextJS). It looks like you could do it with
@submit
keyword in your<form>
if you correctly named your inputs (see Using Custom Validation . Actually, I did something quite similar here Line 103. My code is ugly, but the idea is the same I suppose. So in your@sumbit
, before calling calculateMortage(), or inside, you could check if the infos are empty string/null. Then update yourformErrors
accordingly. Finally, you will have to extract this array just like you did in MortgageResults. Well, I don't know if there's a simpler solution, or one that only uses HTML+CSS.
(I'm still trying to wrap my head around how you managed to change the radio button's color? It looks so good!!)
Happy coding! :)
0@dylan-dot-cPosted 4 months ago@Atatra hey! Thanks for the review. I see we both used TailwindCSS for the styling, i did the hide/show part with selectors in css and how i did the input. So basically if the input field is invalid, make the p.error element visible
input[type='radio']:invalid { & ~ .error { display: block; margin: 0; } }
But my main objective was to try and depend on html and CSS for my validation instead of using JS, didn't turn out how I wanted it so I might have to use JS instead. I guess I was trying to not complicate things by using js, I see it most places where people do something complex in js that could be done with proper html/css.
Like even for the multi-step form, thats how I did the validation using zustand and custom validators and keeping my errors state in an array/object. ANd as you can see I was planning to do the same for vue but I just have an used formErrors state lol.
<label for="interest" class="border p-4 pl-16 mb-12 relative" :class="{ 'border-lime bg-lime bg-opacity-10': data.formInfo.type == 'interest' }"> <input type="radio" name="type" value="interest" id="interest" class="" v-model="data.formInfo.type" required /> <span class="radio"><span class="radio--circle"></span></span> Interest <p class="error hidden text-red absolute top-16 left-0">This field is required</p> </label>
That is the html that I used so I just wrapped the whole info with a label and for the css(non-tailwind part)
input[type='radio']:checked ~ .radio { border-color: hsl(61, 70%, 52%); & .radio--circle { display: inherit; background-color: hsl(61, 70%, 52%); width: 10px; height: 10px; border-radius: 50%; } } .radio { display: grid; place-items: center; position: absolute; left: 5px; width: 20px; height: 20px; border-radius: 50%; border: 1px solid rgb(138, 138, 148); }
And I also added a little opacity of the lime color for the bg of the label.
So thats what I did, also I realized you used a custom radio but you would also have to hide the default one, either with opacity or display none. And due to that it wont look too perfect.
PS: I was a react guy(might still be) but react makes me write some nasty looking code so yh... trying out vue and its cool so far. Only issue I have is dealing with some global state, like I know in react how when state changes the component re-renders and same for any components that use the state, so in react the state is very reactive but not so easily reactive with vue(refs / reactive).
1@AtatraPosted 4 months ago@dylan-dot-c Thanks so much for the thorough answer, it makes everything a lot clearer! I'll keep in mind your solution when I'll have to deal with radios next time.
I know absolutely nothing about Vue so it's interesting to hear the differences between the two. Me too, I tend to write nasty code in React - though I'm still a beginner anyway. My last real project (a multistep form builder and previewer) was so badly written that it made me want to cry haha. I don't know if it will get better, but I'll might consider trying out Vuejs too then.
0@dylan-dot-cPosted 3 months ago@Atatra Just updated the validation, had to do it manually, not sure if its exact but take a look if you have the time
0 -
Please log in to post a comment
Log in with GitHubJoin our Discord community
Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!
Join our Discord