Views
6 months ago

tornadofx-guide

11. Editing Models and

11. Editing Models and Validation While you will probably never do this in a real application, it is possible to set up a ValidationContext and apply validators to it manually. The following example is actually taken from the internal tests of the framework. It illustrates the concept, but is not a practical pattern in an application. // Create a validation context val context = ValidationContext() // Create a TextField we can attach validation to val input = TextField() // Define a validator that accepts input longer than 5 chars val validator = context.addValidator(input, input.textProperty()) { if (it!!.length < 5) error("Too short") else null } // Simulate user input input.text = "abc" // Validation should fail assertFalse(validator.validate()) // Extract the validation result val result = validator.result // The severity should be error assertTrue(result is ValidationMessage && result.severity == ValidationSeverity.Error) // Confirm valid input passes validation input.text = "longvalue" assertTrue(validator.validate()) assertNull(validator.result) Take special note of the last parameter to the addValidator call. This is the actual validation logic. The function is passed the current input for the property it validates and must return null if there are no messages, or an instance of ValidationMessage if something is noteworthy about the input. A message with severity Error will cause the validation to fail. As you can see, you don't need to instantiate a ValidationMessage yourself, simply use one of the functions error , warning , success or info instead. Validation with ViewModel 170

11. Editing Models and Validation Every ViewModel contains a ValidationContext , so you don't need to instantiate one yourself. The Validation framework integrates with the type safe builders as well, and even provides some built in validators, like the required validator. Going back to our person editor, we can make the input fields required with this simple change: field("Name") { } textfield(model.name).required() That's all there is to it. The required validator optionally takes a message that will be presented to the user if the validation fails. The default text is "This field is required". Instead of using the built in required validator we can express the same thing manually: field("Name") { textfield(model.name).validator { if (it.isNullOrBlank()) error("The name field is required") else null } } If you want to further customize the textfield, you might want to add another set of curly braces: field("Name") { textfield(model.name) { // Manipulate the text field here validator { if (it.isNullOrBlank()) error("The name field is required") else null } } } Binding buttons to validation state You might want to only enable certain buttons in your forms when the input is valid. The model.valid property can be used for this purpose. Since the default validation trigger is OnChange , the valid state would only be accurate when you first try to commit the model. However, if you want 171

GUIDE
GUIDE
GUIDE
GUIDE
Guide
GUIDE
Guide
GUIDE
Guide
GUIDE
GUIDE
GUIDE
Guide
Guide
GUIDE
GUIDE