feat(15): submitting form data on step back
This commit is contained in:
parent
5f260455cb
commit
076dc76ca4
|
@ -39,9 +39,9 @@
|
||||||
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
||||||
id="form-step"
|
id="form-step"
|
||||||
th:fragment="formFragment(formData)"
|
th:fragment="formFragment(formData)"
|
||||||
hx-post="/submit-step/1"
|
hx-post="/submit-step/1/2"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
action="/submit-step/1"
|
action="/submit-step/1/2"
|
||||||
method="post"
|
method="post"
|
||||||
>
|
>
|
||||||
<summary
|
<summary
|
||||||
|
|
|
@ -39,9 +39,9 @@
|
||||||
<form
|
<form
|
||||||
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
||||||
id="form-step"
|
id="form-step"
|
||||||
hx-post="/submit-step/2"
|
hx-post="/submit-step/2/3"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
action="/submit-step/2"
|
action="/submit-step/2/3"
|
||||||
method="post"
|
method="post"
|
||||||
th:fragment="formFragment(formData)"
|
th:fragment="formFragment(formData)"
|
||||||
>
|
>
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
name="plan-type"
|
name="plan-type"
|
||||||
value="Arcade"
|
value="Arcade"
|
||||||
class="hidden peer"
|
class="hidden peer"
|
||||||
th:checked="${formData.step2.planType.toString()} == 'Acrade'"
|
th:checked="${formData.step2.planType.toString()} == 'Arcade'"
|
||||||
checked
|
checked
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
@ -187,9 +187,9 @@
|
||||||
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
hx-get="/get-form/1"
|
hx-post="/submit-step/2/1"
|
||||||
hx-target="#form-step"
|
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#form-step"
|
||||||
href="step1.html"
|
href="step1.html"
|
||||||
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
||||||
>Go Back</a
|
>Go Back</a
|
||||||
|
|
|
@ -39,9 +39,9 @@
|
||||||
<form
|
<form
|
||||||
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
||||||
id="form-step"
|
id="form-step"
|
||||||
hx-post="/submit-step/3"
|
hx-post="/submit-step/3/4"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
action="/submit-step/3"
|
action="/submit-step/3/4"
|
||||||
method="post"
|
method="post"
|
||||||
th:fragment="formFragment(formData)"
|
th:fragment="formFragment(formData)"
|
||||||
>
|
>
|
||||||
|
@ -191,9 +191,9 @@
|
||||||
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
hx-get="/get-form/2"
|
hx-post="/submit-step/3/2"
|
||||||
hx-target="#form-step"
|
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#form-step"
|
||||||
href="step2.html"
|
href="step2.html"
|
||||||
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
||||||
>Go Back</a
|
>Go Back</a
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
<form
|
<form
|
||||||
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
class="flex flex-col items-center w-screen h-screen md:grid md:items-start md:p-5 md:bg-white md:rounded-2xl md:grid-cols-[auto_1fr] md:w-desktop-form md:h-desktop-form md:drop-shadow-2xl"
|
||||||
id="form-step"
|
id="form-step"
|
||||||
hx-post="/submit-step/4"
|
hx-post="/submit-step/4/5"
|
||||||
action="/submit-step/4"
|
action="/submit-step/4/5"
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
method="post"
|
method="post"
|
||||||
th:fragment="formFragment(formData)"
|
th:fragment="formFragment(formData)"
|
||||||
|
@ -134,9 +134,9 @@
|
||||||
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
class="flex flex-row items-center py-4 w-full bg-white md:items-end md:h-full"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
hx-get="/get-form/3"
|
hx-post="/submit-step/4/3"
|
||||||
hx-target="#form-step"
|
|
||||||
hx-swap="outerHTML"
|
hx-swap="outerHTML"
|
||||||
|
hx-target="#form-step"
|
||||||
href="step3.html"
|
href="step3.html"
|
||||||
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
class="ml-6 text-sm font-semibold md:pb-3 md:ml-20 md:text-base text-cool-gray"
|
||||||
>Go Back</a
|
>Go Back</a
|
||||||
|
|
|
@ -15,34 +15,37 @@ object Models {
|
||||||
final case class Answers(
|
final case class Answers(
|
||||||
sessionId: String = "id1",
|
sessionId: String = "id1",
|
||||||
currentStep: Int = 1,
|
currentStep: Int = 1,
|
||||||
step1: StepAnswers.Step1 = StepAnswers.Step1("Test Name", "some@email.com", "+9876", true),
|
step1: StepAnswers.Step1 =
|
||||||
step2: StepAnswers.Step2 = StepAnswers.Step2(PlanType.Advanced, true, true),
|
StepAnswers.Step1("Test Name", "some@email.com", "+9876", true),
|
||||||
step3: StepAnswers.Step3 = StepAnswers.Step3(Set(Addons.LargerStorage), true),
|
step2: StepAnswers.Step2 =
|
||||||
|
StepAnswers.Step2(PlanType.Advanced, true, true),
|
||||||
|
step3: StepAnswers.Step3 =
|
||||||
|
StepAnswers.Step3(Set(Addons.LargerStorage), true),
|
||||||
step4: StepAnswers.Step4 = StepAnswers.Step4()
|
step4: StepAnswers.Step4 = StepAnswers.Step4()
|
||||||
) {
|
) {
|
||||||
// this is not enforced by compiler, sad, maintain by hand in html template files
|
// this is not enforced by compiler, sad, maintain by hand in html template files
|
||||||
def fragmentName: String = s"step${currentStep}"
|
def fragmentName: String = s"step${currentStep}"
|
||||||
def updateStep(stepNum: Int, rawData: String): Answers = {
|
def updateStep(stepNum: Int, rawData: String, nextStep: Int): Answers = {
|
||||||
stepNum match {
|
stepNum match {
|
||||||
case 1 =>
|
case 1 =>
|
||||||
this.copy(
|
this.copy(
|
||||||
step1 = this.step1.fromFormData(rawData),
|
step1 = this.step1.fromFormData(rawData),
|
||||||
currentStep = stepNum + 1
|
currentStep = nextStep
|
||||||
)
|
)
|
||||||
case 2 =>
|
case 2 =>
|
||||||
this.copy(
|
this.copy(
|
||||||
step2 = this.step2.fromFormData(rawData),
|
step2 = this.step2.fromFormData(rawData),
|
||||||
currentStep = stepNum + 1
|
currentStep = nextStep
|
||||||
)
|
)
|
||||||
case 3 =>
|
case 3 =>
|
||||||
this.copy(
|
this.copy(
|
||||||
step3 = this.step3.fromFormData(rawData),
|
step3 = this.step3.fromFormData(rawData),
|
||||||
currentStep = stepNum + 1
|
currentStep = nextStep
|
||||||
)
|
)
|
||||||
case 4 =>
|
case 4 =>
|
||||||
this.copy(
|
this.copy(
|
||||||
currentStep = stepNum + 1,
|
step4 = this.step4,
|
||||||
step4 = this.step4
|
currentStep = nextStep
|
||||||
)
|
)
|
||||||
case _ => this
|
case _ => this
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import cask.endpoints.ParamReader
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import scala.jdk.CollectionConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
import multistepform.Models.Answers
|
import multistepform.Models.Answers
|
||||||
|
import scala.annotation.internal.requiresCapability
|
||||||
|
import java.net.URLDecoder
|
||||||
|
|
||||||
case class Routes()(implicit cc: castor.Context, log: cask.Logger)
|
case class Routes()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
extends cask.Routes {
|
extends cask.Routes {
|
||||||
|
@ -85,54 +87,11 @@ case class Routes()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@cask.get("/get-form/:stepNum")
|
@cask.post("/submit-step/:stepNum/:nextStep")
|
||||||
def getFormByStep(stepNum: Int, sessionId: cask.Cookie) = {
|
|
||||||
val id = sessionId.value
|
|
||||||
val answersData = Sessions.sessionReplies.get(id)
|
|
||||||
println(s"returning to step $stepNum with data $answersData")
|
|
||||||
answersData match {
|
|
||||||
case Some(state) => {
|
|
||||||
val stepData = stepNum match {
|
|
||||||
case 1 => state.step1
|
|
||||||
case 2 => state.step2
|
|
||||||
case 3 => state.step3
|
|
||||||
case 4 => state.step4
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stepData.submitted) {
|
|
||||||
cask.Response(
|
|
||||||
s"Your previous answer for step $stepNum not found, please reload the page"
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
val context = new Context()
|
|
||||||
val updatedState = state.copy(currentStep = stepNum)
|
|
||||||
Sessions.sessionReplies.update(id, updatedState)
|
|
||||||
context.setVariable(formDataContextVarName, updatedState)
|
|
||||||
val formFragment = templateEngine.process(
|
|
||||||
updatedState.fragmentName,
|
|
||||||
Set("formFragment").asJava,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
cask.Response(
|
|
||||||
formFragment,
|
|
||||||
headers = Seq("Content-Type" -> "text/html;charset=UTF-8")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case None =>
|
|
||||||
cask.Response(
|
|
||||||
"Your previous answers not found, please reload the page",
|
|
||||||
404
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// i guess let's make step a hidden input?
|
|
||||||
@cask.post("/submit-step/:stepNum")
|
|
||||||
def submitStep(
|
def submitStep(
|
||||||
sessionId: cask.Cookie,
|
sessionId: cask.Cookie,
|
||||||
stepNum: Int,
|
stepNum: Int,
|
||||||
|
nextStep: Int,
|
||||||
request: cask.Request
|
request: cask.Request
|
||||||
) = {
|
) = {
|
||||||
val id = sessionId.value
|
val id = sessionId.value
|
||||||
|
@ -140,7 +99,9 @@ case class Routes()(implicit cc: castor.Context, log: cask.Logger)
|
||||||
|
|
||||||
val userAnswers = Sessions.sessionReplies.getOrElse(id, Answers(id))
|
val userAnswers = Sessions.sessionReplies.getOrElse(id, Answers(id))
|
||||||
|
|
||||||
val updatedAnswers = userAnswers.updateStep(stepNum, request.text())
|
val submittedData = URLDecoder.decode(request.text() , "UTF-8")
|
||||||
|
|
||||||
|
val updatedAnswers = userAnswers.updateStep(stepNum, submittedData, nextStep)
|
||||||
|
|
||||||
Sessions.sessionReplies.update(id, updatedAnswers)
|
Sessions.sessionReplies.update(id, updatedAnswers)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue