Class MultistepFormsService
The service maintains intermediate values in the HTTP session, applies field,
anti-spam, and file validation, invokes optional form processors, and persists the
completed form through SaveFormService.
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionMultistepFormsService(SaveFormService saveFormService, FormsRepository formsRepository, FormItemsRepository formItemsRepository, FormStepsRepository formStepsRepository, FormSettingsRepository formSettingsRepository) -
Method Summary
Modifier and TypeMethodDescriptionfinal voidclearStepDrafts(String formName, jakarta.servlet.http.HttpServletRequest request) Removes all drafts for the completed or definitively terminated form instance.static final voidclearUnsupportedItemValues(FormItemEntity entity, jakarta.servlet.http.HttpServletRequest request) Clears values that are not available for the selected form item type.static voidclearValidationFieldsCache(String formName, Integer domainId) Evicts a form's validation definitions locally and requests domain-wide eviction on the cluster.final List<LabelValue>getAutocompleteOptions(Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request) Backward-compatible variant for callers that do not provide the form instance name.final List<LabelValue>getAutocompleteOptions(String formName, Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request) Return matching configured options for an autocomplete form item.final List<LabelValue>getAvailableConditionFields(String formName, Long stepId, Prop prop) Build available source fields for condition builder up to the current step.getChartStatInfo(jakarta.servlet.http.HttpServletRequest request) Extract chart statistics parameters from request.final Pair<org.json.JSONObject,org.json.JSONObject> getDraftStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) Returns unconfirmed step values and metadata for completed temporary uploads.static final StringgetFieldName(FormItemEntity stepItem, Prop prop) Resolve human-readable field name for validation and UI messages.static final List<LabelValue>getFieldTabVisibility(jakarta.servlet.http.HttpServletRequest request) Provide tab visibility configuration per field type.static final Pair<List<LabelValue>,List<LabelValue>> getFieldTypes(jakarta.servlet.http.HttpServletRequest request) Provide supported form field types as label/value pairs.static final List<LabelValue>getFiledTypeVisibility(jakarta.servlet.http.HttpServletRequest request) Provide visibility configuration per field type (which technical fields are hidden).intgetFormCounter(String formName, jakarta.servlet.http.HttpServletRequest request) Retrieve the form instance counter for the current request.final intResolves the settings identifier of a form in the current domain.static intgetFormIdStatic(String formName) Resolves a form settings identifier through the registered service bean.static List<FormItemEntity>getFormItemsForValidation(String formName) Returns independent validation-field copies for the form in the current domain.static final StringgetFormName(jakarta.servlet.http.HttpServletRequest request) Reads theformNameparameter from the request.static final StringgetFormName(Map<String, String> params) Reads theformNamevalue from a parameter map.final List<LabelValue>getFormStepsOptions(String formName, Prop prop) Build human-readable options for steps of a form suitable for selection inputs.static final StringgetNewSessionKey(String formName, String csrf) Build a new session key for the given form and CSRF token.static final FormStepEntitygetNextStep(String formName, FormStepEntity currentStep, FormStepsRepository repo) Get the next step following the provided step within a form sequence.static final FormStepEntitygetPreviousStep(String formName, FormStepEntity currentStep, FormStepsRepository repo) Get the step preceding the provided step within a form sequence.static final List<LabelValue>getRegExOptions(RegExpRepository regExpRepository, jakarta.servlet.http.HttpServletRequest request) Provide available regular expression validations as label/value pairs for UI.Return technical field types used only for row/column layout in the form editor.final Pair<org.json.JSONObject,org.json.JSONObject> getSavedStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) Load values previously saved for a step and prepare metadata for temporary uploads.getSavedTempFilePreview(String formName, String fileKey, jakarta.servlet.http.HttpServletRequest request) Resolves a previewable temporary image owned by the current form session.static final StringgetSessionKey(String formName, jakarta.servlet.http.HttpServletRequest request) Build the session key used to store per-form, per-request step data.final StringgetValidItemFormId(FormItemEntity entity) Generates a validitemFormIdfor a form item within a form.static final booleanisFieldtypeIterable(String fieldType, jakarta.servlet.http.HttpServletRequest request) static final booleanisFileUploadField(String fieldType) Determine whether a form field stores an asynchronously uploaded attachment.final List<LabelValue>prepareConditionFieldOptions(List<FormItemEntity> fields, String formName, Prop prop) Build condition field options from arbitrary field collection.static voidrefresh(long domainId) Handles cluster refresh requests using the same monitor as validation-field loading.final voidsaveFormStep(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request, org.json.JSONObject response) Validate and persist a single step of a multistep form into session, and optionally finalize the form submission.final voidsaveStepDraft(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) Stores a complete draft of the current step without field validation or submission side effects.final voidupdateFormPattern(String formName) Updates or creates the pattern entity for a form by concatenating its validation item identifiers in order.static final StringBuilderupdateFormValues(String formName, jakarta.servlet.http.HttpServletRequest request, StringBuilder formHtml) Replaces form value placeholders with values stored for the current session.static final StringBuilderupdateFormValues(Map<String, String> formData, StringBuilder formHtml) Replaces placeholders using prepared values without reading the submission session.voidupdateStepsPositions(String formName) Recompute current and max positions for all steps in a form.voidupdateStepsPositions(RowReorderDto rowReorderDto) Refresh step positions after row reorder operation payload.validateField(String formName, Long stepId, String fieldId, jakarta.servlet.http.HttpServletRequest request) Validates one field without saving values or invoking step processors and statistics.final booleanvalidateFormInfo(String formName, Long currentStepId, jakarta.servlet.http.HttpServletRequest request) Validate whether provided form and step represent an allowed step for current session.
-
Field Details
-
SESSION_PREFIX
- See Also:
-
MULTIUPLOAD_PREFIX
- See Also:
-
FILE_INPUT_FIELD_TYPE
- See Also:
-
VISIBILITY_TAB
- See Also:
-
REQUIREMENT_TAB
- See Also:
-
STATISTICS_TAB
- See Also:
-
-
Constructor Details
-
MultistepFormsService
@Autowired public MultistepFormsService(SaveFormService saveFormService, FormsRepository formsRepository, FormItemsRepository formItemsRepository, FormStepsRepository formStepsRepository, FormSettingsRepository formSettingsRepository)
-
-
Method Details
-
getSessionKey
public static final String getSessionKey(String formName, jakarta.servlet.http.HttpServletRequest request) Build the session key used to store per-form, per-request step data.- Parameters:
formName- logical form namerequest- HTTP request providing the CSRF token header- Returns:
- stable session key in format
MultistepForm_<formName>_<domainId>_<csrf>
-
getNewSessionKey
Build a new session key for the given form and CSRF token.- Parameters:
formName- logical form namecsrf- CSRF token value- Returns:
- session key string
-
getFormName
Reads theformNamevalue from a parameter map.- Parameters:
params- map potentially containing keyformName- Returns:
- form name, or an empty string when the value is missing
-
getFormName
Reads theformNameparameter from the request.- Parameters:
request- HTTP request containing parameterformName- Returns:
- form name, or an empty string when the parameter is missing
-
getRegExOptions
public static final List<LabelValue> getRegExOptions(RegExpRepository regExpRepository, jakarta.servlet.http.HttpServletRequest request) Provide available regular expression validations as label/value pairs for UI.- Parameters:
regExpRepository- repository of regex definitionsrequest- request used to resolve localized titles- Returns:
- list of label/value options
-
getFieldTypes
public static final Pair<List<LabelValue>,List<LabelValue>> getFieldTypes(jakarta.servlet.http.HttpServletRequest request) Provide supported form field types as label/value pairs.- Parameters:
request- request used to resolve localized labels- Returns:
- pair containing localized visible options and technical iterable/text classifications
-
isFieldtypeIterable
public static final boolean isFieldtypeIterable(String fieldType, jakarta.servlet.http.HttpServletRequest request) -
isFileUploadField
Determine whether a form field stores an asynchronously uploaded attachment.- Parameters:
fieldType- configured form field type- Returns:
truefor multi-upload variants and the single-file input
-
getFiledTypeVisibility
public static final List<LabelValue> getFiledTypeVisibility(jakarta.servlet.http.HttpServletRequest request) Provide visibility configuration per field type (which technical fields are hidden). Adds a special optionallwaysHidden.- Parameters:
request- request used to resolve localized labels- Returns:
- list of visibility label/value pairs
-
clearUnsupportedItemValues
public static final void clearUnsupportedItemValues(FormItemEntity entity, jakarta.servlet.http.HttpServletRequest request) Clears values that are not available for the selected form item type.- Parameters:
entity- form item being savedrequest- request used to resolve the field visibility configuration
-
getFieldTabVisibility
public static final List<LabelValue> getFieldTabVisibility(jakarta.servlet.http.HttpServletRequest request) Provide tab visibility configuration per field type.Depending on the field type, returns the visibility, requirement, and statistics tabs that should be shown in administration.
- Parameters:
request- request used to resolve localized labels and field metadata- Returns:
- list mapping field type to a comma-separated list of visible tabs
-
getNextStep
public static final FormStepEntity getNextStep(String formName, FormStepEntity currentStep, FormStepsRepository repo) Get the next step following the provided step within a form sequence.- Parameters:
formName- logical form namecurrentStep- current step entityrepo- repository used to fetch ordered steps- Returns:
- next step entity or
nullif current step is the last - Throws:
IllegalStateException- when the expected next step does not exist in the current domain
-
getPreviousStep
public static final FormStepEntity getPreviousStep(String formName, FormStepEntity currentStep, FormStepsRepository repo) Get the step preceding the provided step within a form sequence.- Parameters:
formName- logical form namecurrentStep- current step entityrepo- repository used to fetch ordered steps- Returns:
- previous step entity or
nullif current step is the first - Throws:
IllegalStateException- when the expected previous step does not exist in the current domain
-
getRowViewItemTypes
Return technical field types used only for row/column layout in the form editor.- Returns:
- list of non-input layout item field types
-
getFieldName
Resolve human-readable field name for validation and UI messages.- Parameters:
stepItem- form item definitionprop- localization provider- Returns:
- localized field label or plain text extracted from custom HTML label
-
getChartStatInfo
public static final Pair<String,String> getChartStatInfo(jakarta.servlet.http.HttpServletRequest request) Extract chart statistics parameters from request.- Parameters:
request- HTTP request containing optionalformNameanditemFormId- Returns:
- pair of
(formName, itemFormId)when both are present, otherwisenull
-
getFormId
Resolves the settings identifier of a form in the current domain.- Parameters:
formName- logical form name- Returns:
- form settings identifier, or
-1when the form is not found
-
getFormIdStatic
Resolves a form settings identifier through the registered service bean.- Parameters:
formName- logical form name- Returns:
- form settings identifier, or
-1when the form is not found
-
validateFormInfo
public final boolean validateFormInfo(String formName, Long currentStepId, jakarta.servlet.http.HttpServletRequest request) Validate whether provided form and step represent an allowed step for current session.- Parameters:
formName- logical form namecurrentStepId- step id to validaterequest- request with session context- Returns:
truewhen the step exists and is permitted in current session
-
getSavedStepData
public final Pair<org.json.JSONObject,org.json.JSONObject> getSavedStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) Load values previously saved for a step and prepare metadata for temporary uploads.- Parameters:
formName- logical form namestepId- step identifierrequest- request containing the form session- Returns:
- pair containing saved values and Dropzone-compatible upload metadata
-
getDraftStepData
public final Pair<org.json.JSONObject,org.json.JSONObject> getDraftStepData(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) Returns unconfirmed step values and metadata for completed temporary uploads.- Parameters:
formName- logical form namestepId- step identifierrequest- request identifying the form instance- Returns:
- draft values and upload metadata, without changing confirmed answers
-
saveStepDraft
public final void saveStepDraft(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request) throws SaveFormException, IOException Stores a complete draft of the current step without field validation or submission side effects. Only configured fields are accepted; CAPTCHA responses and widget metadata are not retained. Plain strings are restored through control values; rich text is sanitized before editor restoration.- Parameters:
formName- logical form namestepId- current step identifierrequest- request containing field values and the form session- Throws:
SaveFormException- when cookie or CSRF checks failIOException- when reading the JSON body failsIllegalStateException- when the form or step is not permitted, the form counter is invalid, or the request body is emptyIllegalArgumentException- when a configured field contains unsupported JSON values
-
clearStepDrafts
Removes all drafts for the completed or definitively terminated form instance.- Parameters:
formName- logical form namerequest- request identifying the form instance and its session
-
getSavedTempFilePreview
public IwcmFile getSavedTempFilePreview(String formName, String fileKey, jakarta.servlet.http.HttpServletRequest request) Resolves a previewable temporary image owned by the current form session.The file key must belong to an upload field stored in the session. Missing files, unsupported image formats, and SVG files are rejected.
- Parameters:
formName- logical form namefileKey- temporary upload keyrequest- request containing the form session- Returns:
- validated image file, or
nullwhen it cannot be previewed
-
getAutocompleteOptions
public final List<LabelValue> getAutocompleteOptions(String formName, Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request) Return matching configured options for an autocomplete form item.- Parameters:
formName- form name used to validate the current session; the item's form name is used when emptystepId- current form stepitemId- autocomplete form itemterm- text entered by the user; at least two characters are requiredrequest- current form request- Returns:
- matching label/value options
-
getAutocompleteOptions
public final List<LabelValue> getAutocompleteOptions(Long stepId, Long itemId, String term, jakarta.servlet.http.HttpServletRequest request) Backward-compatible variant for callers that do not provide the form instance name.- Parameters:
stepId- current form stepitemId- autocomplete form itemterm- text entered by the userrequest- current form request- Returns:
- matching label/value options
-
getAvailableConditionFields
Build available source fields for condition builder up to the current step.- Parameters:
formName- logical form namestepId- current step idprop- localization provider- Returns:
- sorted condition field options grouped by step labels
-
prepareConditionFieldOptions
public final List<LabelValue> prepareConditionFieldOptions(List<FormItemEntity> fields, String formName, Prop prop) Build condition field options from arbitrary field collection.- Parameters:
fields- fields to transform into optionsformName- logical form name used to resolve step labels/positionsprop- localization provider- Returns:
- sorted options in format
(Step X) Field Name
-
getFormStepsOptions
Build human-readable options for steps of a form suitable for selection inputs.- Parameters:
formName- logical form nameprop- localization provider used for step labels- Returns:
- list of label/value pairs for the form steps
-
getValidItemFormId
Generates a validitemFormIdfor a form item within a form.For
radiofields, derives the identifier from the label or field type and required flag, allowing radio buttons to share the same logical identifier. For other fields, adds a numeric suffix to avoid collisions within the form and domain.- Parameters:
entity- form item to generate id for- Returns:
- identifier safe for storage and queries, unique for non-radio fields
-
updateFormPattern
Updates or creates the pattern entity for a form by concatenating its validation item identifiers in order. Upload fields append the-fileNamespostfix.- Parameters:
formName- logical form name
-
validateField
public final Map<String,String> validateField(String formName, Long stepId, String fieldId, jakarta.servlet.http.HttpServletRequest request) throws SaveFormException, IOException Validates one field without saving values or invoking step processors and statistics. Conditional visibility and requirement rules are evaluated only during step submission.- Parameters:
formName- logical form namestepId- current step identifierfieldId- logical identifier of the field to validaterequest- request containing the field value and the form session- Returns:
- localized errors for the requested field, or an empty map when valid
- Throws:
SaveFormException- when CSRF, cookie, or XSS checks failIOException- when reading the request body failsIllegalStateException- when the form or step is not permitted, the form counter is invalid, or the request body is emptyIllegalArgumentException- when the field is not in the step or is an upload, CAPTCHA, or WYSIWYG field
-
saveFormStep
public final void saveFormStep(String formName, Long stepId, jakarta.servlet.http.HttpServletRequest request, org.json.JSONObject response) throws SaveFormException, IOException Validate and persist a single step of a multistep form into session, and optionally finalize the form submission. Performs CSRF/CAPTCHA/file validations and invokes custom processors. When the last step is completed, triggers final save into DB. Omitted current-step values are cleared before condition evaluation, and hidden answers are excluded from confirmed data while their drafts are retained. Field validation errors are returned throughresponsewithout saving the submitted step. On completion, adds the configured redirect or rendered thank-you page content to the response; unavailable inline content leaves the client to display its standard success message.- Parameters:
formName- logical form namestepId- current step identifierrequest- HTTP request containing JSON body of field valuesresponse- JSON response to be enriched with errors, next step, forward or thank-you content- Throws:
SaveFormException- when validation or processing fails in a controlled wayIOException- when reading request body fails
-
getFormItemsForValidation
Returns independent validation-field copies for the form in the current domain. Consecutive radio options sharing a logical identifier are collapsed for form-wide processing.- Parameters:
formName- logical form name- Returns:
- simplified items in step and item display order, or an empty list for an empty form name
-
clearValidationFieldsCache
Evicts a form's validation definitions locally and requests domain-wide eviction on the cluster. Called explicitly after saving, deleting, duplicating, or reordering the form structure.- Parameters:
formName- logical form namedomainId- domain owning the form
-
refresh
public static void refresh(long domainId) Handles cluster refresh requests using the same monitor as validation-field loading.- Parameters:
domainId- domain whose validation definitions should be evicted locally
-
updateStepsPositions
Refresh step positions after row reorder operation payload.- Parameters:
rowReorderDto- datatable row reorder payload
-
updateStepsPositions
Recompute current and max positions for all steps in a form.- Parameters:
formName- logical form name
-
getFormCounter
Retrieve the form instance counter for the current request.When multiple instances of the same form appear on a single page, each gets a unique counter value stored in the session during
MultistepFormApp.view(org.springframework.ui.Model, jakarta.servlet.http.HttpServletRequest).- Parameters:
formName- logical form namerequest- HTTP request with session containing the counter- Returns:
- stored form instance counter clamped to at least
-1, or-1when absent
-
updateFormValues
public static final StringBuilder updateFormValues(String formName, jakarta.servlet.http.HttpServletRequest request, StringBuilder formHtml) Replaces form value placeholders with values stored for the current session.- Parameters:
formName- logical form namerequest- request containing values saved by earlier stepsformHtml- form markup containing!fieldId!placeholders- Returns:
- updated markup,
nullwhenformHtmlisnull
-
updateFormValues
public static final StringBuilder updateFormValues(Map<String, String> formData, StringBuilder formHtml) Replaces placeholders using prepared values without reading the submission session. HTML entities are normalized before escaping to avoid double-escaping filtered values.- Parameters:
formData- values keyed by logical field IDs, containing HTML-escaped text, sanitized WYSIWYG HTML, saved filenames and empty answers; markup in these values is escaped for placeholder replacementformHtml- markup containing!fieldId!placeholders- Returns:
- updated markup, or
nullwhenformHtmlisnull
-