Learning-HTMX/15-multi-step-form
efim fe8b54346a docs: adding license to deployable projects 2023-07-22 06:04:42 +00:00
..
design init(15): adding exercise resources 2023-07-09 15:05:07 +00:00
project init(15): adding tailwind, yay 2023-07-08 18:41:46 +00:00
src docs: adding license to deployable projects 2023-07-22 06:04:42 +00:00
.envrc feat(15): nix installation & image 2023-07-16 06:45:04 +00:00
.gitignore init(15): sbt project with mainargs 2023-07-08 17:06:32 +00:00
.project init(15): sbt project with mainargs 2023-07-08 17:06:32 +00:00
.scalafmt.conf init(15): server returns dummy index from template 2023-07-08 18:27:21 +00:00
README.org doc(15): link and more gratitute 2023-07-16 15:54:57 +00:00
build.sbt feat(15): phone validation htmx inline 2023-07-16 15:07:46 +00:00
default.nix fix(15): sbt-derivation need new hach for new deps 2023-07-16 15:41:53 +00:00
screenshot-desktop.png docs(15): lessons learned 2023-07-16 15:34:33 +00:00
screenshot-mobile.png docs(15): lessons learned 2023-07-16 15:34:33 +00:00
style-guide.md init(15): adding exercise resources 2023-07-09 15:05:07 +00:00
tailwind.config.js feat(15): initial styling footer-controls section 2023-07-09 18:04:43 +00:00

README.org

Frontend Mentor - Multi-step form solution

This is a solution to the Multi-step form challenge on Frontend Mentor. Frontend Mentor challenges help you improve your coding skills by building realistic projects.

Overview

The challenge

Users should be able to:

  • Complete each step of the sequence
  • Go back to a previous step to update their selections
  • See a summary of their selections on the final step and confirm their order
  • 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
  • Receive form validation messages if:

    • A field has been missed
    • The email address is not formatted correctly
    • A step is submitted, but no selection has been made

Screenshot

/efim/Learning-HTMX/media/commit/51e3629fa5b66c846672abe7eb8a80823094f97d/15-multi-step-form/screenshot-desktop.png /efim/Learning-HTMX/media/commit/51e3629fa5b66c846672abe7eb8a80823094f97d/15-multi-step-form/screenshot-mobile.png

My process

Built with

  • Semantic HTML5 markup well, i tried, but yeah
  • TailwinCSS
  • Mobile-first workflow
  • Server-side rendering, in Scala and Cask
  • htmx
  • Thymeleaf html templates

What I learned

hx-get and hx-post
How i show correct form stage for each user on same URL

on 'index.html' i use "initial loading" element

      <section hx-get="/get-form" hx-trigger="load" hx-swap="outerHTML">
        <!-- here be immediate hx-get for the form. to subscitute the body -->
        <img class="w-14 text-green-500 fill-current" src="../public/images/tail-spin.svg" alt="loading..." />
      </section>

This element will do single GET request to server to /get-form And user already has cookie with sessionId set from visiting the root enpoint, which returned 'index.html'

So request to /get-form already includes 'sessionId' cookie, and server can find \ initialize Answers data for this particular session, and 'currentStep' is part of the Answers

so reloading 'index.html' would trigger /get-form, which would render correct step.

hx-post

This will make POST request. If we do GET request from <input> only current input value is included, as query para. POST request from <input> or from <form> would include all filelds of the form.

So form submittion on "Next" and "Back" done via htmx POST requests, which parse and save passed attributes, but also server selects required next form step, renders it and returns for the 'hx-swap="outerHTML"'

hx-post on <input> allows for 'inline validation' (see useful resources) this allows for validating field value - in isolation or together with all other form field values.

Learned format in which browser sends POST attributes to the server

Request payload as text: name=e&email=emails%40la.la&phone=%2B7%20(911)%2084-35644%20ext%20155

I chose this exercise also because i wanted more experience in working with forms. Single form would still be much nicer, even with htmx, but yeah. Current exercise felt like full-fledged application.

Styling of the checkbox and radiobuttons as big selectable areas

This was first time I attempted something like this. Insight was to use <label> as overall container for the input and other data - descriptions and icons.

Because user clicking on label automatically translates into toggling of the input, no js needed.

Either hide (for radio button part on step 2) or keep (for checkboxes on step 3) the input, and put descriptions and icons as next element.

So that peer- styling can be used.

htmx inline validation of the phone number field

Almost exactly as in example. Separate rest endpoint for the input field, which returns new rendered state.

hx-post is triggered on input field default trigger = "changed", and i guess only on focus leaving field. So this seems quite efficient.

This way validation can be done with very heavy libraries and access to DB and such. Over single field, or over all of them at once. Seems unusual, but cool

Continued development

I want to learn more about Thymeleaf - how to use files for efficient fragment storage. Currently it feels that i have separate files, and it's nice, but some files have several fragments, and maybe need more documentation or markings.

Look for other templating solutions for java \ scala, maybe there are others with 'fragment' functionality

Would be nice to refactor the code, to have smaller and more directed files.

I am also getting better at doing flex \ grid layouts without specific paddings\margins on the lements, but feel that i'm still abusing that, and that future tinkering with layouts could be painful due to free space being constructed from manual paddings\margings

For htmx - would be nice to learn transition animations, and try to use it in a bigger exercise already.

Useful resources

Acknowledgments