Warning
This document is for an old release of Galaxy. You can alternatively view this page in the latest release if it exists or view the top of the latest release's documentation.
Source code for galaxy.forms.forms
"""
FormDefinition and field factories
"""
# TODO: A FormDefinitionField is closely linked to a form_builder result.
# Can this functionality be further abstracted and merged with form_builder?
from galaxy.model import (
FormDefinition,
FormDefinitionCurrent,
)
from galaxy.util import string_as_bool
FORM_TYPES = {f_type.lower(): f_descript for f_type, f_descript in FormDefinition.types.__members__.items()}
[docs]class FormDefinitionFactory:
[docs] def __init__(self, form_types, field_type_factories):
self.form_types = form_types
self.field_type_factories = field_type_factories
[docs] def new(self, form_type, name, description=None, fields=None, layout=None, form_definition_current=None):
"""
Return new FormDefinition.
"""
assert (
form_type in self.form_types
), f"Invalid FormDefinition type ( {form_type} not in {self.form_types.keys()} )"
assert name, "FormDefinition requires a name"
if description is None:
description = ""
if layout is None:
layout = []
if fields is None:
fields = []
# Create new FormDefinitionCurrent
if form_definition_current is None:
form_definition_current = FormDefinitionCurrent()
rval = FormDefinition(
name=name,
desc=description,
form_type=self.form_types[form_type],
form_definition_current=form_definition_current,
layout=layout,
fields=fields,
)
form_definition_current.latest_form = rval
return rval
[docs] def from_elem(self, elem, form_definition_current=None):
"""
Return FormDefinition created from an xml element.
"""
name = elem.get("name", None)
description = elem.get("description", None)
form_type = elem.get("type", None)
# load layout
layout = []
if layouts_elem := elem.find("layout"):
for layout_elem in layouts_elem.findall("grid"):
layout_name = layout_elem.get("name", None)
assert layout_name and layout_name not in layout, "Layout grid element requires a unique name."
layout.append(layout_name)
# load fields
fields = []
if (fields_elem := elem.find("fields")) is not None:
for field_elem in fields_elem.findall("field"):
field_type = field_elem.get("type")
assert field_type in self.field_type_factories, f"Invalid form field type ( {field_type} )."
fields.append(self.field_type_factories[field_type].from_elem(field_elem, layout))
# create and return new form
return self.new(
form_type,
name,
description=description,
fields=fields,
layout=layout,
form_definition_current=form_definition_current,
)
[docs]class FormDefinitionFieldFactory:
type: str
def __get_stored_field_type(self, **kwds):
raise Exception("not implemented")
[docs] def new(self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None):
"""
Return new FormDefinition field.
"""
rval = {}
assert name, "Must provide a name"
rval["name"] = name
if not label:
rval["label"] = name
else:
rval["label"] = label
if required:
rval["required"] = "required"
else:
rval["required"] = "optional"
if helptext is None:
helptext = ""
rval["helptext"] = helptext
if default is None:
default = ""
rval["default"] = default
rval["visible"] = visible
# if layout is None: #is this needed?
# layout = ''
rval["layout"] = layout
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition created from an xml element.
"""
name = elem.get("name")
label = elem.get("label")
required = string_as_bool(elem.get("required", "false"))
default = elem.get("value")
helptext = elem.get("helptext")
visible = string_as_bool(elem.get("visible", "true"))
field_layout = elem.get("layout", None)
if field_layout:
assert layout and field_layout in layout, f"Invalid layout specified: {field_layout} not in {layout}"
field_layout = str(
layout.index(field_layout)
) # existing behavior: integer indexes are stored as strings. why?
return self.new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=field_layout,
)
[docs]class FormDefinitionTextFieldFactory(FormDefinitionFieldFactory):
type = "text"
def __get_stored_field_type(self, area):
if area:
return "TextArea"
else:
return "TextField"
[docs] def new(
self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None, area=False
):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type(area)
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type(string_as_bool(elem.get("area", "false")))
return rval
[docs]class FormDefinitionPasswordFieldFactory(FormDefinitionFieldFactory):
type = "password"
def __get_stored_field_type(self):
return "PasswordField"
[docs] def new(
self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None, area=False
):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type()
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type()
return rval
[docs]class FormDefinitionAddressFieldFactory(FormDefinitionFieldFactory):
type = "address"
def __get_stored_field_type(self):
return "AddressField"
[docs] def new(self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type()
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type()
return rval
[docs]class FormDefinitionWorkflowFieldFactory(FormDefinitionFieldFactory):
type = "workflow"
def __get_stored_field_type(self):
return "WorkflowField"
[docs] def new(self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type()
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type()
return rval
[docs]class FormDefinitionWorkflowMappingFieldFactory(FormDefinitionFieldFactory):
type = "workflowmapping"
def __get_stored_field_type(self):
return "WorkflowMappingField"
[docs] def new(self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type()
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type()
return rval
[docs]class FormDefinitionHistoryFieldFactory(FormDefinitionFieldFactory):
type = "history"
def __get_stored_field_type(self):
return "HistoryField"
[docs] def new(self, name=None, label=None, required=False, helptext=None, default=None, visible=True, layout=None):
"""
Return new FormDefinition field.
"""
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type()
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type()
return rval
[docs]class FormDefinitionSelectFieldFactory(FormDefinitionFieldFactory):
type = "select"
def __get_stored_field_type(self, checkboxes):
if checkboxes:
return "CheckboxField"
else:
return "SelectField"
[docs] def new(
self,
name=None,
label=None,
required=False,
helptext=None,
default=None,
visible=True,
layout=None,
options=None,
checkboxes=False,
):
"""
Return new FormDefinition field.
"""
options = options or []
rval = super().new(
name=name,
label=label,
required=required,
helptext=helptext,
default=default,
visible=visible,
layout=layout,
)
rval["type"] = self.__get_stored_field_type(checkboxes)
if options is None:
options = []
rval["selectlist"] = options
return rval
[docs] def from_elem(self, elem, layout=None):
"""
Return FormDefinition field created from an xml element.
"""
rval = super().from_elem(elem, layout=layout)
rval["type"] = self.__get_stored_field_type(string_as_bool(elem.get("checkboxes", "false")))
# load select options
rval["selectlist"] = []
for select_option in elem.findall("option"):
value = select_option.get("value", None)
assert value is not None, 'Must provide a "value" for a select option'
rval["selectlist"].append(value)
return rval
field_type_factories = {
field.type: field()
for field in (
FormDefinitionTextFieldFactory,
FormDefinitionPasswordFieldFactory,
FormDefinitionAddressFieldFactory,
FormDefinitionSelectFieldFactory,
FormDefinitionWorkflowFieldFactory,
FormDefinitionWorkflowMappingFieldFactory,
FormDefinitionHistoryFieldFactory,
)
}
form_factory = FormDefinitionFactory(FORM_TYPES, field_type_factories)