theraPy/forms/SearchForm.py
2024-10-12 21:39:20 +02:00

88 lines
3.7 KiB
Python

from wtforms import Form, StringField, validators
from wtforms.fields.choices import SelectMultipleField, RadioField
from wtforms.fields.numeric import IntegerField
from wtforms.fields.simple import BooleanField
from wtforms.widgets.core import CheckboxInput, ListWidget, Input
def validate_therapy_types(form, field):
"""
Validate form input for given therapy types (mapping in input field)
:param form: required by calling method
:param field: data field for validation (therapy types)
:return:
"""
# Given choices by the data source
valid_choices = {"A", "S", "T", "V"}
# All of them in arbitrary sets are allowed
if not all(choice in valid_choices for choice in field.data):
raise validators.ValidationError("Invalid value in therapy types selection.")
def validate_therapy_phone_times(form, field):
"""
Validate number of weeks for therapy phone times search.
:param form: required by calling method
:param field: data field for validation (therapy phone times in weeks)
:return:
"""
# Weeks from 1 to 4
valid_choices = {1, 2, 3, 4}
# Check for given data at all -> at least 1 week necessary
if not field.data:
raise validators.ValidationError("Please select at least one option.")
# All of them in arbitrary sets are allowed
if not all(choice in valid_choices for choice in field.data):
raise validators.ValidationError("Invalid value in therapy phone types selection.")
class RangeInput(Input):
"""
Define a range as input type to use HTML element form-range
"""
input_type = "range"
class SearchForm(Form):
"""
Search Form to search with several parameters and constraints for doctors/therapists with phone times
"""
# Match location as string or plz with arbitrary length
location = StringField("Standort/PLZ", validators=[validators.InputRequired(), validators.Length(min=2, max=50),
validators.Regexp("^[a-zA-ZäöüßÄÖÜẞ0-9]+$")])
# Define a distance as range input to limit the search area
therapy_distance = IntegerField(
"Distanz",
widget=RangeInput(),
default=25,
validators=[validators.InputRequired(), validators.NumberRange(min=0, max=50)]
)
# Define several therapy types (all of them possible to search for)
therapy_type = SelectMultipleField("Therapieverfahren", choices=[
("A", "Analytische Psychotherapie"),
("S", "Systemische Therapie"),
("T", "Tiefenpsychologisch fundierte Psychotherapie"),
("V", "Verhaltenstherapie")], option_widget=CheckboxInput(), widget=ListWidget(prefix_label=False),
validators=[validate_therapy_types])
# Distinction between adults/children & youth as radio button
therapy_age_range = RadioField("Altersgruppe", choices=[
("E", "Erwachsene"),
("K", "Kinder und Jugendliche")], validators=[validators.InputRequired(), validators.any_of(["E", "K"])])
# Distinction between available therapy types
therapy_setting = RadioField("Therapiesetting", choices=[
("E", "Einzeltherapie"),
("G", "Gruppentherapie")], validators=[validators.InputRequired(), validators.any_of(["E", "G"])])
# TODO: find a better name for label
# Choose for how many weeks to show phone times
amount_of_weeks = IntegerField(
# Rest of the label rendered by the frontend (even though not perfect solution)
"Telefonzeiten für die ",
widget=RangeInput(),
default=1,
validators=[validators.InputRequired(), validators.NumberRange(min=1, max=4)]
)
privacy_agreement = BooleanField("Datenschutz", validators=[validators.InputRequired()])