This library provides a module that checks the contents of components, and displays errors if the contents are invalid. It can also disable components such as submit buttons if the form is invalid.
There’s a validation
module with a Validator
class that performs the validation:
self.validator = validation.Validator()
Here’s how you set up validation for a text field:
self.validator.require_text_field(self.my_text_field, self.label_to_display_if_invalid)
and for a check box:
self.validator.require_checked(self.my_check_box, self.label_to_display_if_invalid)
You can set up validation for any component by using the general-purpose require
method.
As well as the component itself, it takes:
- a list of events that trigger validation
- a function that returns
True
if the component is valid,False
otherwise - the label to display if the field is invalid.
self.validator.require(
self.my_component,
['change', 'lost_focus'],
lambda component: return component.text != '',
self.label_to_display_if_invalid,
)
If you want to disable your submit button when the form is invalid:
self.validator.enable_when_valid(self.submit_button)
This sets the enabled
property on the component it’s given, so you can use it for any component with an enabled
property.
To display the error labels for all invalid fields:
self.validator.show_all_errors()
The Form Validation library is completely free to use, so click on the clone link and use it in your app!
You can use it from another app by using the App Dependencies dialog.
When you clone the library, you will also get an example app that shows you how to include it and make use of it.
How it works
The validation.Validator
class holds data about the validation config in three attributes:
def __init__(self):
self._validity = {}
self._actions = []
self._component_checks = []
self._validity
maps components to a boolean representing whether that component is valid.
self._actions
is a list of functions to call that depend on the whole form’s validity. Each function is passed a boolean that’s
False
if the form is invalid. This is used by the enable_when_valid
method to disable buttons, but you could put other functions in this list.
self._component_checks
is a list of functions that get called in order when the form is validated.
The require
method populates this list with the validation function that you pass into it (named predicate
), wrapped in a function that
updates the _validity
list, displays the error label if necessary, and runs the whole-form checking method (_check
):
The require
method also sets up event handlers on the component based on the list that was passed into it.
def require(self, component, event_list, predicate, error_lbl=None, show_errors_immediately=False):
# When `require` is called, we define a function that wraps `predicate` with some actions to take.
def check_this_component(**e):
result = predicate(component)
self._validity[component] = result
if error_lbl is not None:
error_lbl.visible = not result
self._check()
# Then register event handlers for the component
for e in event_list:
component.set_event_handler(e, check_this_component)
# And add the component check to the Validator's list
self._component_checks.append(check_this_component)
# Not shown: a bit of code at the end for checking the form as a whole.
require_text_field
and require_checked
are convenience functions that wrap the require
method.
show_all_errors
checks the entire form - in practice, this just means iterating over self._component_checks
and running
each of the functions that were created by require
.
There’s also a method for checking the entire form - self.is_valid
. This calculates the form’s validity based on
the contents of self._validity
, so the check functions must be run first if you want the result to be up-to-date.
self._check
runs self.is_valid
to check if the form is valid, then runs all of self._actions
, the actions
to be carried out based on the form’s validity.