1
1
package torstenrudolf .scalajs .react .formbinder
2
2
3
- import japgolly .scalajs .react .{BackendScope , Callback , ReactComponentB , ReactNode }
3
+ import japgolly .scalajs .react .{BackendScope , Callback , CallbackTo , ReactComponentB , ReactNode }
4
4
import japgolly .scalajs .react .vdom .prefix_<^ ._
5
5
6
6
import scala .scalajs .js
@@ -222,17 +222,13 @@ object FormField {
222
222
validator : (O ) => ValidationResult ,
223
223
parentForm : Form [_] with FormAPI [_])
224
224
225
- case class State [O ](currentValidationResult : ValidationResult = ValidationResult . Success ,
225
+ case class State [O ](currentValidationResult : Option [ ValidationResult ] = None ,
226
226
currentRawValue : Option [O ] = None ,
227
- showUnitializedError : Boolean = false ) {
228
- val currentValidatedValue : Option [O ] = if (currentValidationResult.isValid) currentRawValue else None
229
- }
227
+ showUnitializedError : Boolean = false )
230
228
231
229
class Backend [O ]($ : BackendScope [Props [O ], State [O ]]) {
232
- // def update(currentValidatedValue: Option[O], currentValidationResult: ValidationResult) =
233
- // $.setState(State(currentValidatedValue = currentValidatedValue, currentValidationResult = currentValidationResult))
234
230
235
- def validate (showUnitializedError : Boolean = false ): Callback = $.state.zip($.props) >>= { case (state, props) =>
231
+ def validate (showUnitializedError : Boolean = false ): CallbackTo [ ValidationResult ] = $.state.zip($.props) >>= { case (state, props) =>
236
232
val showUnitializedErrorX = showUnitializedError || state.showUnitializedError
237
233
val valueToValidate =
238
234
if (showUnitializedErrorX && state.currentRawValue.isEmpty && props.valueIsString) {
@@ -247,11 +243,11 @@ object FormField {
247
243
case None => ValidationResult .Success
248
244
}
249
245
250
- $.modState(_.copy(currentValidationResult = validationResult, showUnitializedError = showUnitializedErrorX))
246
+ $.modState(_.copy(currentValidationResult = Some ( validationResult) , showUnitializedError = showUnitializedErrorX)) >> CallbackTo (validationResult )
251
247
}
252
248
253
249
private def onChangeCB : Callback =
254
- $.state.zip($.props) >>= { case (state, props) => props.onChangeCB(state. currentValidatedValue) }
250
+ $.state.zip($.props) >>= { case (state, props) => props.onChangeCB(currentValidatedValue) }
255
251
256
252
def updateRawValue (v : Option [O ]): Callback = {
257
253
$.modState(_.copy(currentRawValue = v), cb = validate() >> onChangeCB)
@@ -261,13 +257,20 @@ object FormField {
261
257
262
258
def resetToDefault : Callback = $.modState(_.copy(showUnitializedError = false ), cb = {$.props >>= { props => updateRawValue(props.defaultValue) }})
263
259
264
- def currentValidatedValue : Option [O ] = $.state.runNow().currentValidatedValue
260
+ def currentValidatedValue : Option [O ] = {
261
+ if (currentValidationResult.isValid) $.state.runNow().currentRawValue else None
262
+ }
263
+
264
+ def currentValidationResult : ValidationResult = $.state.runNow().currentValidationResult match {
265
+ case None => validate().runNow()
266
+ case Some (vr) => vr
267
+ }
265
268
266
269
def render (props : Props [O ], state : State [O ]) = < .div(
267
270
props.formFieldDescriptor.descr(
268
271
FormFieldArgs [O ](
269
272
currentValue = state.currentRawValue,
270
- currentValidationResult = state. currentValidationResult,
273
+ currentValidationResult = currentValidationResult,
271
274
onChangeCB = (v : O ) => updateRawValue(Some (v)),
272
275
resetToDefaultCB = resetToDefault,
273
276
clearCB = clear,
@@ -312,7 +315,9 @@ case class FormFieldBinding[O](formFieldDescriptor: FormFieldDescriptor[O],
312
315
313
316
def currentValidatedValue : Option [O ] = formFieldBackend.flatMap(_.currentValidatedValue)
314
317
315
- def validate (showUninitializedError : Boolean ): Try [Callback ] = Try (formFieldBackend.get.validate(showUninitializedError))
318
+ def currentValidationResult : Try [ValidationResult ] = Try (formFieldBackend.get.currentValidationResult)
319
+
320
+ def validate (showUninitializedError : Boolean ): Try [Callback ] = Try (formFieldBackend.get.validate(showUninitializedError).void)
316
321
317
322
def updateValue (v : O ): Try [Callback ] = Try (formFieldBackend.get.updateRawValue(Some (v)))
318
323
@@ -347,6 +352,11 @@ trait FormAPI[T] extends Form[T] {
347
352
private var _validatedFormData : Option [T ] = None
348
353
private var _formGlobalValidationResult : Option [ValidationResult ] = None
349
354
355
+ private def formGlobalValidationResult : ValidationResult = _formGlobalValidationResult match {
356
+ case Some (vr) => vr
357
+ case None => throw FormUninitialized
358
+ }
359
+
350
360
protected def globalValidator (data : T ): ValidationResult
351
361
352
362
protected def currentUnvalidated : scala.util.Try [T ]
@@ -379,14 +389,22 @@ trait FormAPI[T] extends Form[T] {
379
389
override def fullValidate : Callback = Callback {validate(showUninitializedError = true )}
380
390
381
391
def onChangeCB : Callback = {
382
- Callback (validate(showUninitializedError = false )) >> forceGlobalValidationMessageUpdate.getOrElse(Callback .empty)
392
+ Callback (validate(showUninitializedError = false )) >>
393
+ forceGlobalValidationMessageUpdate.getOrElse(Callback .empty) >>
394
+ formLayout.onChange(validatedData = _validatedFormData)
383
395
}
384
396
385
397
override def validatedFormData : Option [T ] = {
386
398
validate(showUninitializedError = true )
387
399
_validatedFormData
388
400
}
389
401
402
+ private def allFieldValidationResults : List [ValidationResult ] = allFormFieldBindings.map(
403
+ _.currentValidationResult match {
404
+ case Success (vr) => vr
405
+ case _ => throw FormUninitialized
406
+ })
407
+
390
408
protected def allFormFieldBindings : List [FormFieldBinding [_]]
391
409
392
410
override def field [A ](fd : torstenrudolf.scalajs.react.formbinder.FormFieldDescriptor [A ]): ReactNode =
0 commit comments