![JAR search and dependency download from the Maven repository](/logo.png)
org.hyperscala.ui.widgets.visual.ValidatableVisual.scala Maven / Gradle / Ivy
package org.hyperscala.ui.widgets.visual
import org.hyperscala.html._
/**
* @author Matt Hicks
*/
trait ValidatableVisual[T] extends Visual[T] {
type Validation = T => Either[Option[T], String]
property.changing.on {
case newValue => if (validateOnChange) {
validate(newValue)
} else {
Some(newValue)
}
}
private var validations = List.empty[Validation]
def validateOnChange = false
def hasError: Boolean
def errorMessage(message: String): Unit
def validate(): Boolean = {
validate(property())
!hasError
}
def validate(value: T): Option[T] = {
errorMessage(null)
executeValidations(value, validations)
}
private def executeValidations(value: T, validations: List[Validation]): Option[T] = {
if (validations.nonEmpty) {
val v = validations.head
v(value) match {
case Left(option) => option match {
case Some(t) => executeValidations(t, validations.tail)
case None => None
}
case Right(errorMessage) => {
this.errorMessage(errorMessage)
Some(value)
}
}
} else {
Some(value)
}
}
def +=(validation: Validation) = synchronized {
validations = (validation :: validations.reverse).reverse
}
def -=(validation: Validation) = synchronized {
validations = validations.filterNot(v => v == validation)
}
}
object ValidatableVisual {
/**
* Returns true if all ValidatableVisuals within this container pass validation.
*/
def validateAll(container: HTMLTag) = container.byTag[ValidatableVisual[_]].collect {
case vv if (!vv.validate()) => vv
}.isEmpty
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy