Skip to content

[#4821] Persist profile attached documents through validation errors#5115

Merged
cielf merged 1 commit into
rubyforgood:mainfrom
danielabar:4821-part3-partner-profile-persist-docs-validation-errors
Mar 27, 2025
Merged

[#4821] Persist profile attached documents through validation errors#5115
cielf merged 1 commit into
rubyforgood:mainfrom
danielabar:4821-part3-partner-profile-persist-docs-validation-errors

Conversation

@danielabar
Copy link
Copy Markdown
Collaborator

Resolves #4821

Description

This is the final part 3 of improvements to editing partner profile Attached Documents section. It fixes the following situation:

  1. Invited partner edits their profile, uploading one or more documents in the "Attached Documents" section.
  2. They also fill out some other field resulting in a validation error (eg: 4 pick up email addresses, or leaving all social media fields blank and not checking off "No social media presence").
  3. When they click "Save Progress", the form re-renders with validation errors, BUT their file uploads are lost, and they need to realize this and select them again.

There are a few moving parts to solve this:

1. Direct Uploads

The first part of the solution is to use direct uploads feature of Active Storage (already enabled via a previous PR). This ensures that the selected files are persisted to the storage service, and written as new records in active_storage_blobs table, via ajax requests, even if the model didn't get saved on form submission.

2. Submit hidden signed_id

When direct uploads is enabled, each document's signed_id is accessible from the partner profile model, even if it failed to be saved due to validation errors. So the form partial app/views/partners/profiles/step/_attached_documents_form.html.erb can iterate over these and submit hidden field(s) for each document that was attempted to be attached, but not persisted. This allows Rails to associate these files to the model, upon the next successful form submission. The file names are also available from the model.

3. Display to user previously selected files

It's one thing to have the signed_id's as hidden fields, it's quite another to let the user know that we still have their files so they don't need to select them again.

The native file picker (which is rendered from the file_field form helper), has a files attribute, and when its null/empty, it displays "No files selected". But the only way the files attribute of the native picker can be populated is from the user literally clicking on the "Choose file" button. This means that in the form validation error case, even though we still have the user's file selections, the native file picker will show "No file selected".

It would be nice if we could set the files attribute of the native file picker via JavaScript, but this is not supported - see MDN on file input type for details.

The solution then is to hide the native file input (still functional though) and instead render a custom "Choose files" button that when clicked, delegates to the native file picker. This is handled via a Stimulus controller app/javascript/controllers/file_input_controller.js. This controller was introduced in a previous PR related to attached documents. At the time the only purpose was to customize the display of selected files (because the native file picker only displays number of files chosen, not the actual file names).

Now the Stimulus controller is enhanced to accept a value Array of file names, and if provided, display these as the selected files.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

For manual testing - follow the steps in the description. When the form re-renders with validation errors, scroll down to the "Attached Documents" section, open it up, and you should see your previously selected files are still rendered as "Selected files". Then if you fix the validation error(s) and click Save Progress, the attached documents should be saved.

For automated testing - see spec/system/partners/profile_edit_system_spec.rb, new test added: it "persists multiple file uploads when there are validation errors" do...

Screenshots

The native file picker for attached documents is hidden and a new custom button is displayed in its place:
image

After user selects some files, they're shown in a custom listing (this behaviour was added in a previous PR, but now a sub-header of "Selected files" is also rendered to make it clear these are what user just selected):
image

If form re-renders with validation errors, and user previously selected files, they are preserved - i.e. rendering looks the same as if they had just selected those files:
image

After user fixes validation error and Saves Progress again, the preserved files are now attached:
image

Here's what it looks like with a combination of existing attached files, plus a few new ones selected:
image

…ion errors

Use direct uploads for multiple file input so that file blobs remain
available even if the model fails to save due to validation errors.

- Submit hidden fields containing the signed_id of attached but
  unpersisted documents so that previously selected documents will be
  saved on the next successful form submission
- Hide the native file input to prevent "No file chosen" from
  appearing when files were selected before a validation error
- Use a custom button and file listing to display selected files
  during the current selection or on form re-render
Copy link
Copy Markdown
Collaborator

@cielf cielf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passes functionality review. Over to @awwaiid and/or @dorner for technical thoughts.

Copy link
Copy Markdown
Collaborator

@dorner dorner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All OK on my end.

@danielabar I think it's pretty nuts that this (which seems to be a common pattern) is so complex to get working. I'm wondering if there's a way to package this up into either a PR to Rails/Stimulus or a separate gem/package - it seems like a good open source opportunity.

@cielf cielf merged commit ace0ee3 into rubyforgood:main Mar 27, 2025
@github-actions
Copy link
Copy Markdown
Contributor

@danielabar: Your PR [#4821] Persist profile attached documents through validation errors is part of today's Human Essentials production release: 2025.03.30.
Thank you very much for your contribution!

@danielabar
Copy link
Copy Markdown
Collaborator Author

All OK on my end.

@danielabar I think it's pretty nuts that this (which seems to be a common pattern) is so complex to get working. I'm wondering if there's a way to package this up into either a PR to Rails/Stimulus or a separate gem/package - it seems like a good open source opportunity.

Thanks for the suggestion! Yes this definitely seems like something that might be easier resolved from within Rails rather than in application code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Partner profile -- rework additional documents to be more workable

3 participants