Skip to content

Serialize Form Data #573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rmorshea opened this issue Jan 10, 2022 · 12 comments · Fixed by #699
Closed

Serialize Form Data #573

rmorshea opened this issue Jan 10, 2022 · 12 comments · Fixed by #699
Labels
flag-good-first-issue A well defined and self-contained task. priority-2-moderate Should be resolved on a reasonable timeline.
Milestone

Comments

@rmorshea
Copy link
Collaborator

Current Situation

Currently, onSubmit events for form elements do not serialize the data contained within them. To do this we need to serialize the form.elements attribute.

Proposed Changes

diff --git a/src/client/packages/idom-client-react/src/event-to-object.js b/src/client/packages/idom-client-react/src/event-to-object.js
index b11e653..80b098b 100644
--- a/src/client/packages/idom-client-react/src/event-to-object.js
+++ b/src/client/packages/idom-client-react/src/event-to-object.js
@@ -49,6 +49,13 @@ const elementTransformCategories = {
       return {};
     }
   },
+  hasElements: (element) => {
+    const result = {};
+    for (key in element.elements) {
+      result[key] = serializeDomElement(element.elements[key]);
+    }
+    return result;
+  }
 };
 
 function defaultElementTransform(element) {
@@ -69,6 +76,7 @@ const elementTagCategories = {
   ],
   hasCurrentTime: ["AUDIO", "VIDEO"],
   hasFiles: ["INPUT"],
+  hasElements: ["FORM"],
 };
 
 const elementTransforms = {};

Implementation Details

No response

@rmorshea rmorshea added the flag-triage Not prioritized. label Jan 10, 2022
@rmorshea rmorshea added this to the 1.0 milestone Jan 11, 2022
@rmorshea rmorshea added enhancement priority-2-moderate Should be resolved on a reasonable timeline. and removed flag-triage Not prioritized. labels Jan 11, 2022
@rmorshea rmorshea added the flag-good-first-issue A well defined and self-contained task. label Feb 9, 2022
@Archmonger
Copy link
Contributor

There's going to need to be considerations made for file fields. We're also going to need to make considerations related to backpressure, especially since there's the potential to upload files with an uncapped size.

Probably worth generalizing the data serialization (perhaps even as a separate package?). If it's generic enough, there's a possibility that down the line it would allow for using the WS to stream video.

@rmorshea
Copy link
Collaborator Author

I think there's an issue (or discussion) about serializing files.

Could you make file serialization into an issue if it isn't one and create an separate issue for dealing with back-pressure?

@rmorshea
Copy link
Collaborator Author

@acivitillo this seems like a less-trivial first issue.

@Archmonger
Copy link
Contributor

File serialization issue appears to exist: #574

Shouldn't backpressure be handled within the file serialization issue? Feels strange creating a new issue to handle an not yet developed limitation.

@rmorshea
Copy link
Collaborator Author

I think back-pressure is a general problem. Any event, not just those with files, could take a long time for the network to send and the server to process which would thus cause things to back up.

@Archmonger
Copy link
Contributor

Archmonger commented Feb 18, 2022

Something else I'm generally thinking about on this is there's going to need to be some degree of consideration for Django here.

Django forms have a validator function that is run to verify the form's data. I'm not sure how we'd work that in to an "IDOM form"...

Maybe we need some sort of concept of form middleware? Would also need some class mixins within Django IDOM, most likely.

@acivitillo
Copy link
Contributor

Well, from my end I can take a stab at the initial PR idea, but I am not sure if I can also consider all the other cases. Could we implement form serialization incrementally via multiple PRs?

@Archmonger
Copy link
Contributor

Yeah it can be handled incrementally.

@acivitillo
Copy link
Contributor

ok so I started working on this, there is a problem with keys. This is because a form can have an indefinite number of elements, so target will be a json of multiple targets.

We can go with index keys, but then I need to understand how to build a test case for FORM in event-to-object.test.js

  hasElements: (element) => {
    const result = {};
    Object.keys(element).forEach((key) => {
      result[key] = serializeDomElement(element.elements[key])
    });
    return result;
  }

gives the below json

{
  "target": {
    "0": {
      "boundingClientRect": {
        "x": 8,
        "y": 8,
        "width": 149,
        "height": 22,
        "top": 8,
        "right": 157,
        "bottom": 30,
        "left": 8
      },
      "value": ""
    },
    "1": {
      "boundingClientRect": {
        "x": 8,
        "y": 80,
        "width": 52,
        "height": 22,
        "top": 80,
        "right": 60,
        "bottom": 102,
        "left": 8
      },
      "value": "Submit"
    },
    "2": {
      "boundingClientRect": {
        "x": 60,
        "y": 80,
        "width": 149,
        "height": 22,
        "top": 80,
        "right": 209,
        "bottom": 102,
        "left": 60
      },
      "value": ""
    },
    "boundingClientRect": {
      "x": 8,
      "y": 8,
      "width": 408,
      "height": 128,
      "top": 8,
      "right": 416,
      "bottom": 136,
      "left": 8
    },
    "__reactInternalInstance$6poh51syf6f": null,
    "__reactEventHandlers$6poh51syf6f": null
  },
  "currentTarget": {
    "0": {
      "boundingClientRect": {
        "x": 8,
        "y": 8,
        "width": 149,
        "height": 22,
        "top": 8,
        "right": 157,
        "bottom": 30,
        "left": 8
      },
      "value": ""
    },
    "1": {
      "boundingClientRect": {
        "x": 8,
        "y": 80,
        "width": 52,
        "height": 22,
        "top": 80,
        "right": 60,
        "bottom": 102,
        "left": 8
      },
      "value": "Submit"
    },
    "2": {
      "boundingClientRect": {
        "x": 60,
        "y": 80,
        "width": 149,
        "height": 22,
        "top": 80,
        "right": 209,
        "bottom": 102,
        "left": 60
      },
      "value": ""
    },
    "boundingClientRect": {
      "x": 8,
      "y": 8,
      "width": 408,
      "height": 128,
      "top": 8,
      "right": 416,
      "bottom": 136,
      "left": 8
    },
    "__reactInternalInstance$6poh51syf6f": null,
    "__reactEventHandlers$6poh51syf6f": null
  },
  "relatedTarget": null
}

@acivitillo
Copy link
Contributor

I tried playing with a FORM test case but I get Cannot read property 'tagName' of undefined

  ...["AUDIO", "VIDEO"].map((tagName) => ({
    case: `adds 'currentTime' attribute for ${tagName} element`,
    tagName,
    output: { target: { currentTime: allTargetData.currentTime } },
  })),
  ...["FORM"].map((tagName) => ({
    case: `adds 'value' attribute for ${tagName} element`,
    tagName,
    output: { target: { value: allTargetData.value } },
  })),

@rmorshea
Copy link
Collaborator Author

rmorshea commented Mar 3, 2022

Can you put up PR so I can look at the diff?

@acivitillo
Copy link
Contributor

acivitillo commented Mar 3, 2022

here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flag-good-first-issue A well defined and self-contained task. priority-2-moderate Should be resolved on a reasonable timeline.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants