vibecode some validation logic
This commit is contained in:
parent
b856d31fcc
commit
263a609084
2 changed files with 101 additions and 4 deletions
|
|
@ -5,6 +5,7 @@ import org.scalajs.dom.HTMLTableRowElement
|
||||||
import com.raquo.laminar.api.L.*
|
import com.raquo.laminar.api.L.*
|
||||||
import com.raquo.laminar.api.features.unitArrows
|
import com.raquo.laminar.api.features.unitArrows
|
||||||
import rdts.base.Uid
|
import rdts.base.Uid
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
class EntryComponent(
|
class EntryComponent(
|
||||||
entry: Entry,
|
entry: Entry,
|
||||||
|
|
@ -15,10 +16,60 @@ class EntryComponent(
|
||||||
def render: ReactiveHtmlElement[HTMLTableRowElement] = {
|
def render: ReactiveHtmlElement[HTMLTableRowElement] = {
|
||||||
if editMode then
|
if editMode then
|
||||||
val driverInput = input(cls := "input", value := entry.driver.payload)
|
val driverInput = input(cls := "input", value := entry.driver.payload)
|
||||||
|
|
||||||
val startKmInput =
|
val startKmInput =
|
||||||
input(cls := "input", value := entry.startKm.payload.toString())
|
input(
|
||||||
|
`type` := "number",
|
||||||
|
value := entry.startKm.payload.toString()
|
||||||
|
)
|
||||||
val endKmInput =
|
val endKmInput =
|
||||||
input(cls := "input", value := entry.endKm.payload.toString())
|
input(
|
||||||
|
`type` := "number",
|
||||||
|
value := entry.endKm.payload.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
// Validation signals
|
||||||
|
val startKmValue = startKmInput
|
||||||
|
.events(onInput)
|
||||||
|
.mapTo(startKmInput.ref.value)
|
||||||
|
.startWith(entry.startKm.payload.toString())
|
||||||
|
val endKmValue = endKmInput
|
||||||
|
.events(onInput)
|
||||||
|
.mapTo(endKmInput.ref.value)
|
||||||
|
.startWith(entry.endKm.payload.toString())
|
||||||
|
|
||||||
|
val startKmValid =
|
||||||
|
startKmValue.map(value => Try(value.toDouble).isSuccess)
|
||||||
|
val endKmValid = endKmValue.map(value => Try(value.toDouble).isSuccess)
|
||||||
|
|
||||||
|
val rangeValid = startKmValue.combineWithFn(endKmValue) { (start, end) =>
|
||||||
|
Try(start.toDouble).toOption.zip(Try(end.toDouble).toOption) match {
|
||||||
|
case Some((startVal, endVal)) => endVal > startVal
|
||||||
|
case None => true // Don't show range error if values are invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val startKmError = startKmValid.combineWithFn(rangeValid) {
|
||||||
|
(valid, range) =>
|
||||||
|
!valid || !range
|
||||||
|
}
|
||||||
|
|
||||||
|
val endKmError = endKmValid.combineWithFn(rangeValid) { (valid, range) =>
|
||||||
|
!valid || !range
|
||||||
|
}
|
||||||
|
|
||||||
|
startKmInput.amend(
|
||||||
|
cls <-- startKmError.map(error =>
|
||||||
|
if error then "input is-danger" else "input"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
endKmInput.amend(
|
||||||
|
cls <-- endKmError.map(error =>
|
||||||
|
if error then "input is-danger" else "input"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val animalInput = input(cls := "input", value := entry.animal.payload)
|
val animalInput = input(cls := "input", value := entry.animal.payload)
|
||||||
val costWearInput =
|
val costWearInput =
|
||||||
input(cls := "input", value := entry.costWear.toString())
|
input(cls := "input", value := entry.costWear.toString())
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,60 @@ import fahrtenbuch.model.Entry
|
||||||
import rdts.base.Uid
|
import rdts.base.Uid
|
||||||
import rdts.datatypes.LastWriterWins
|
import rdts.datatypes.LastWriterWins
|
||||||
import scala.scalajs.js.Date
|
import scala.scalajs.js.Date
|
||||||
|
import scala.util.Try
|
||||||
|
|
||||||
class NewEntryInput(showNewEntryField: Var[Boolean]):
|
class NewEntryInput(showNewEntryField: Var[Boolean]):
|
||||||
val newEntryDriver = input(cls := "input")
|
val newEntryDriver = input(cls := "input")
|
||||||
val newEntryStartKm = input(cls := "input")
|
val newEntryStartKm = input(`type` := "number")
|
||||||
val newEntryEndKm = input(cls := "input")
|
val newEntryEndKm = input(`type` := "number")
|
||||||
val newEntryAnimal = input(cls := "input")
|
val newEntryAnimal = input(cls := "input")
|
||||||
val newEntryPaid = input(`type` := "checkbox")
|
val newEntryPaid = input(`type` := "checkbox")
|
||||||
|
|
||||||
|
// Validation signals
|
||||||
|
val startKmValue = newEntryStartKm
|
||||||
|
.events(onInput)
|
||||||
|
.mapTo(newEntryStartKm.ref.value)
|
||||||
|
.startWith("")
|
||||||
|
val endKmValue = newEntryEndKm
|
||||||
|
.events(onInput)
|
||||||
|
.mapTo(newEntryEndKm.ref.value)
|
||||||
|
.startWith("")
|
||||||
|
|
||||||
|
val startKmValid =
|
||||||
|
startKmValue.map(value => value.isEmpty || Try(value.toDouble).isSuccess)
|
||||||
|
val endKmValid =
|
||||||
|
endKmValue.map(value => value.isEmpty || Try(value.toDouble).isSuccess)
|
||||||
|
|
||||||
|
val rangeValid = startKmValue.combineWithFn(endKmValue) { (start, end) =>
|
||||||
|
if (start.isEmpty || end.isEmpty) true
|
||||||
|
else {
|
||||||
|
Try(start.toDouble).toOption.zip(Try(end.toDouble).toOption) match {
|
||||||
|
case Some((startVal, endVal)) => endVal > startVal
|
||||||
|
case None => true // Don't show range error if values are invalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val startKmError = startKmValid.combineWithFn(rangeValid) { (valid, range) =>
|
||||||
|
!valid || !range
|
||||||
|
}
|
||||||
|
|
||||||
|
val endKmError = endKmValid.combineWithFn(rangeValid) { (valid, range) =>
|
||||||
|
!valid || !range
|
||||||
|
}
|
||||||
|
|
||||||
|
newEntryStartKm.amend(
|
||||||
|
cls <-- startKmError.map(error =>
|
||||||
|
if error then "input is-danger" else "input"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
newEntryEndKm.amend(
|
||||||
|
cls <-- endKmError.map(error =>
|
||||||
|
if error then "input is-danger" else "input"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def render =
|
def render =
|
||||||
tr(
|
tr(
|
||||||
td(),
|
td(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue