Skip to content

Commit

Permalink
feat(validation): enhance error handling and rendering in validation …
Browse files Browse the repository at this point in the history
…components
  • Loading branch information
cheleb committed Nov 29, 2024
1 parent ddb2489 commit f30c392
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 20 deletions.
17 changes: 1 addition & 16 deletions examples/client/src/main/scala/samples/Validation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,10 @@ val validation = {
)
)

val errorBus = ironSampleVar.errorBus

Sample(
"Validation",
div(
ironSampleVar.asForm(errorBus),
div(
child <-- errorBus.watch
.map { errors =>
div(
errors.collect {
case (field, ValidationStatus.Invalid(message, true)) =>
div(
s"$field: $message"
)
}.toSeq
)
}
)
ironSampleVar.asForm
),
div(
child <-- ironSampleVar.signal.map { item =>
Expand Down
28 changes: 27 additions & 1 deletion modules/core/src/main/scala/dev/cheleb/scalamigen/Form.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,24 @@ import java.time.LocalDate
import io.github.iltotore.iron.*

import config.PanelConfig
import com.raquo.airstream.core.Signal

/** Extension method for path: List[Symbol]
*/
extension (path: List[Symbol])
/** Get the key of the path.
*
* This key is used to identify the field in the error bus.
*/
def key: String =
path.map(_.name).mkString(".")

extension (errorBus: EventBus[(String, ValidationEvent)])
def watch = errorBus.events
/** Watch the error bus and return a signal of the errors.
*
* @return
*/
def watch: Signal[Map[String, ValidationStatus]] = errorBus.events
.scanLeft(Map.empty[String, ValidationStatus]) {
case (acc, (field, event)) =>
event match
Expand All @@ -42,6 +53,21 @@ extension (errorBus: EventBus[(String, ValidationEvent)])
}
}

/** Render the errors.
*
* @param f
* @return
*/
def errors(f: (String, String) => HtmlElement) =
errorBus.watch.map { errors =>
div(
errors.collect {
case (field, ValidationStatus.Invalid(message, true)) =>
f(field, message)
}.toSeq
)
}

/** A form for a type A.
*/
trait Form[A] { self =>
Expand Down
15 changes: 12 additions & 3 deletions modules/core/src/main/scala/dev/cheleb/scalamigen/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,18 @@ extension [A](va: Var[A])
Form[A]
): ReactiveHtmlElement[HTMLElement] = {
val errorBus = new EventBus[(String, ValidationEvent)]()
Form
.renderVar(va, () => ())(using wf, errorBus)
.amend(cls := "srf-form")
div(
Form
.renderVar(va, () => ())(using wf, errorBus)
.amend(cls := "srf-form"),
child <-- errorBus
.errors((field, message) =>
div(
s"$field: $message"
)
)
)

}

/** Render a form for the variable.
Expand Down

0 comments on commit f30c392

Please sign in to comment.