Skip to content

[LiveComponent][RFC] File uploads in forms #289

Open
@Lustmored

Description

@Lustmored

I think last the missing piece of cake before LiveComponent form support can be considered full is functional file upload. I wasn't tracking changes for the last few weeks, so if there is functioning support already - let me know and I will celebrate and close the issue 😉

I have already experimented with file uploads within live component with forms and other logic in 2.0.x (in particular - this form has multiple steps in UI and that's where LiveComponent really shines). But to achieve functioning file upload I had to follow those steps:

  1. I've created separate LiveComponent to handle just the <input type="file"> and track its changes.
  2. Within this component I have Stimulus controller that tracks file changes, sends them to the server (that stores it somewhere and returns path), saves the path to hidden field and notifies live controller about changes.

This way once the file is uploaded it is not discarded during re-renders and I can work with it in submit action.

I think similar could be possible out of the box with LiveComponent and would love to work on it. But before I dive into it I'd love some feedback and suggestions. My proposed solution is inspired by how EasyAdmin handles image fields, but with major changes due to different nature of the problem.

EasyAdmin way:

  • custom form type for file upload
  • model transformer that handles file saving and translates values to File instances and back

It is simple, efficient, easily extendable and - most importantly - working well enough.

LiveComponent differences:

  • The file should be uploaded as soon as possible (not only on submit) to allow partial validation
  • Upon successful upload file should be transformed into serialized value that can be shared between back-end and front-end

Those are my rough implementation ideas, please help with them 😄

Front-end:

  • uploaded files details should be serializable into dataValue or a new parameter, eg. filesValue,
  • _makeRequest needs to be able to send files along with other data

Back-end:

  • ComponentWithFormTrait should be able to handle/validate files (there is a chance it does out of the box)
  • Upon successful file validation the file should be moved out of the system temp dir (to var/cache/ as a default maybe?) and return UploadedFile-like serializable object pointing to that file. I think it could be private trait method so that components can overwrite it with own logic. Also - exceptions raised within that logic should be handled with grace
  • Whenever form is recreated information about previously uploaded files should be also recreated and passed to form data

How does it sound? As LiveController is pretty complex already I'm unsure as to where exactly what part of this logic fits, so help with that would be also appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions