|
| 1 | +//> using scala "3.3.1" |
| 2 | +//> using dep ba.sake::sharaf:0.0.22 |
| 3 | + |
| 4 | +import io.undertow.Undertow |
| 5 | +import ba.sake.sharaf.*, routing.* |
| 6 | +import ba.sake.formson.FormDataRW |
| 7 | + |
| 8 | +object views { |
| 9 | + import scalatags.Text.all.* |
| 10 | + import ba.sake.hepek.html.HtmlPage |
| 11 | + import ba.sake.hepek.htmx.* |
| 12 | + |
| 13 | + class IndexView(formData: ContactForm) extends HtmlPage with HtmxDependencies: |
| 14 | + override def bodyContent = div( |
| 15 | + h3("Signup Form"), |
| 16 | + contactForm(formData) |
| 17 | + ) |
| 18 | + |
| 19 | + override def stylesInline = List(""" |
| 20 | + .error-message { |
| 21 | + color:red; |
| 22 | + } |
| 23 | + .error input { |
| 24 | + box-shadow: 0 0 3px #CC0000; |
| 25 | + } |
| 26 | + .valid input { |
| 27 | + box-shadow: 0 0 3px #36cc00; |
| 28 | + } |
| 29 | + """) |
| 30 | + |
| 31 | + def contactForm(formData: ContactForm) = form(hx.post := "/contact", hx.swap := "outerHTML")( |
| 32 | + emailField(formData.email, false), |
| 33 | + div(label("First Name")(input(name := "firstName", value := formData.firstName))), |
| 34 | + div(label("Last Name")(input(name := "lastName", value := formData.lastName))), |
| 35 | + button("Submit") |
| 36 | + ) |
| 37 | + |
| 38 | + def emailField(fieldValue: String, isError: Boolean) = |
| 39 | + div(hx.target := "this", hx.swap := "outerHTML", Option.when(isError)(cls := "error"))( |
| 40 | + label("Email Address")( |
| 41 | + input(name := "email", value := fieldValue, hx.post := "/contact/email", hx.indicator := "#ind"), |
| 42 | + img(id := "ind", src := "/img/bars.svg", cls := "htmx-indicator") |
| 43 | + ), |
| 44 | + Option.when(isError)(div(cls := "error-message")("That email is already taken. Please enter another email.")) |
| 45 | + ) |
| 46 | + |
| 47 | +} |
| 48 | + |
| 49 | +case class ContactForm(email: String, firstName: String, lastName: String) derives FormDataRW |
| 50 | + |
| 51 | +val routes = Routes: |
| 52 | + case GET() -> Path() => |
| 53 | + val formData = ContactForm("", "", "") |
| 54 | + Response.withBody(views.IndexView(formData)) |
| 55 | + case POST() -> Path("contact", "email") => |
| 56 | + val formData = Request.current.bodyForm[ContactForm] |
| 57 | + val isValid = formData.email == "[email protected]" |
| 58 | + Response.withBody(views.emailField(formData.email, !isValid)) |
| 59 | + case POST() -> Path("contact") => |
| 60 | + val formData = Request.current.bodyForm[ContactForm] |
| 61 | + Response.withBody(views.contactForm(formData)) |
| 62 | + |
| 63 | +Undertow.builder |
| 64 | + .addHttpListener(8181, "localhost") |
| 65 | + .setHandler(SharafHandler(routes)) |
| 66 | + .build |
| 67 | + .start() |
| 68 | + |
| 69 | +println(s"Server started at http://localhost:8181") |
0 commit comments