Skip to content

Instantly share code, notes, and snippets.

@alxgmpr
Last active September 19, 2021 14:47
Show Gist options
  • Save alxgmpr/d1d46dbe45771f0a63271be0e6435793 to your computer and use it in GitHub Desktop.
Save alxgmpr/d1d46dbe45771f0a63271be0e6435793 to your computer and use it in GitHub Desktop.

Sometimes, it is useful to gather form data from a webpage en masse.

The quick-script way to do this is to iterate via document.forms and construct FormData objects for each form on the page.

// es6 spread converts fancy collection obj into plain array
const allForms = [...document.forms]

allForms.forEach((f) => {
  const fd = new FormData(form)
  for (const [k, v] of fd.entries()) {
    console.log(k, v)
  }
})

To take this to the next step, we can construct an object containing all the form data on the page.

For keys like something[nested][deep], we can recursively create objects:

const keypairToDict = (k, v) => {
  // split key on [ or ], then remove them and empty strings
  const keyComponents = k.split(/\s*(\[|\])/).filter((split) => ![']', '[', ''].includes(split))
  if (keyComponents.length > 1) {
    // no need to completely reassemble, any 1 of the characters we split on above is sufficient
    return { [keyComponents[0]]: keypairToDict(keyComponents.slice(1).join(']'), v) }
  }
  return { [keyComponents[0]]: v }
}

Putting this alllll together (and using _.merge)

let allFormData = {}

[...document.forms].forEach((form) => { 
  const fd = new FormData(form)
  for (const [k, v] of fd.entries()) {
    _.merge(allFormData, keypairToDict(k, v))
  }
})

Produces output like:

{
  "_method": "patch",
  "authenticity_token": "up2UK4xxxY47aSs4OZLow",
  "step": "payment_method",
  "checkout": {
    "client_details": {
      "browser_width": "2545",
      "browser_height": "939",
      "javascript_enabled": "1",
      "color_depth": "24",
      "java_enabled": "false",
      "browser_tz": "300"
    },
    "reduction_code": "",
    "payment_gateway": "00000",
    "credit_card": {
      "vault": "false"
    },
    "different_billing_address": "false",
    "total_price": "123"
  },
  "previous_step": "payment_method",
  "s": "",
  "complete": "1"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment