Html to json api

Intro

I have a love, but sometimes hate, relationship with HTML Forms. HTML Forms are absolutely brilliant for out of the box validation, accessibility and usability. But they can be a pain to style!
Nevertheless, HTML Forms give you massive amounts of functionality with zero dependencies.

If you are anything like me, you prefer your API to be JSON based. Making it easier and more consistent to deal with requests and responses on the backend.
You could add a middleware to your API endpoint that’s going to handle your Form UI but why make that endpoint different from the rest?

What if you could send your Form data off in JSON format and handle it like all your other endpoints. Now you can!

Form Data

Introducing FormData, this is a really nice Web API for manipulating data in HTML Forms.

This allows us to easily convert a HTML Form to JSON using the following.

const formElement = document.querySelector('form') 
/** * Creates a json object including fields in the form * * @param form The form element to convert * @return The form data */ const getFormJSON = (form) =>  const data = new FormData(form); return Array.from(data.keys()).reduce((result, key) =>  result[key] = data.get(key); return result; >, <>); >; 
  1. Action the JSON Object result, however you want to handle the data from the form! Send it off with Fetch for example.

Gotcha’s

As with everything these are a few gotchas to look out for!

Checkbox’s

If ticked your checkbox’s will appear in the result as ‘on’. Probably not the boolean you want.
For example, if you’ve got this input in your form, which the user has checked.

 name="isOpen" type="checkbox" checked /> 

It would produce, using the function above:

You will probably want to check for the property and if it equals ‘on’ and convert it to a boolean.

File Uploads

This one really caught me out, if you’ve got a file input which accepts multiple files, like so:

 name="uploads" type="file" multiple /> 

If one file is uploaded you will get a File object.
But if you have multiple files uploaded, you will actually get a list of them.

Fortunately, there is a really simple fix for this to consistently provide you with a list of files.
Grab the files from the result and process them like so:

[files].flat().filter((file) => !!file.name) 

This will consistently give you a list of files, handling if only a single file is uploaded, no file is uploaded or multiples are uploaded.

This also means you can do more client side checks on file sizes and limits for example as well.

Inputs with the same name

Let’s say you’ve got a list of possible tags and a user can tick the ones that apply, perhaps which programming languagues they know, like so:

 name="tags" type="checkbox" value="javascript" />  name="tags" type="checkbox" value="python" /> 

With the current solution, you would only get the last selected checkbox as the keys would be overridden in the reduce. However there is a simple fix for this as well.

We check to see if the key (the name attribute on the input) already exists in the result, if it does then use a getAll method which will get a list of results.

/** * Creates a json object including fields in the form * * @param form The form element to convert * @return The form data */ const getFormJSON = (form) =>  const data = new FormData(form); return Array.from(data.keys()).reduce((result, key) =>  if (result[key])  result[key] = data.getAll(key) return result > result[key] = data.get(key); return result; >, <>); >; 

Similarly, to the file upload before, you’ll want to handle only one being ticked, no being ticked or multiple, with something like this.

Examples

Shut up and show me the code.

Simple Example

  lang="en">  charset="utf-8">   name="forms" id="forms"> Whats your username?  name="username" type="text" />  How many years have you been a developer?  name="age" type="number" />   type="submit">Submit  // get the form element from dom const formElement = document.querySelector('form#forms') // convert the form to JSON const getFormJSON = (form) =>  const data = new FormData(form); return Array.from(data.keys()).reduce((result, key) =>  result[key] = data.get(key); return result; >, <>); >; // handle the form submission event, prevent default form behaviour, check validity, convert form to JSON const handler = (event) =>  event.preventDefault(); const valid = formElement.reportValidity(); if (valid)  const result = getFormJSON(formElement); console.log(result) > > formElement.addEventListener("submit", handler)   

Full Example

  lang="en">  charset="utf-8">   name="forms" id="forms"> Whats your username?  name="username" type="text" />  How many years have you been a developer?  name="age" type="number" />  Upload images  name="images" type="file" accept="image/png, image/jpeg" multiple />  Do you know javascript?  name="languages" type="checkbox" value="javascript" />  Do you know python?  name="languages" type="checkbox" value="python" />  Enjoyed this blog?  name="isHappyReader" type="checkbox" />   type="submit">Submit  // get the form element from dom const formElement = document.querySelector('form#forms') // convert the form to JSON const getFormJSON = (form) =>  const data = new FormData(form); return Array.from(data.keys()).reduce((result, key) =>  if (result[key])  result[key] = data.getAll(key) return result > result[key] = data.get(key); return result; >, <>); >; // handle the form submission event, prevent default form behaviour, check validity, convert form to JSON const handler = (event) =>  event.preventDefault(); const valid = formElement.reportValidity(); if (valid)  const result = getFormJSON(formElement); // handle one, multiple or no files uploaded const images = [result.images].flat().filter((file) => !!file.name) // handle one, multiple or no languages selected const languages = [result.languages || []].flat(); // convert the checkbox to a boolean const isHappyReader = !!(result.isHappyReader && result.isHappyReader === 'on') // use spread function, but override the keys we've made changes to const output =  . result, images, languages, isHappyReader > console.log(output) > > formElement.addEventListener("submit", handler)   

Bonus: Example Test

it('should return a JSON representation of a form', () =>  const form = document.createElement('form'); const input = document.createElement('input'); input.name = 'test'; input.value = 'value'; form.appendChild(input); const number = document.createElement('input'); number.type = 'number'; number.name = 'int'; number.value = '10'; form.appendChild(number); const result = getFormJSON(form); expect(result).to.deep.equal( test: 'value', int: '10', >); >); 

Summary

In summary, you can use what browsers give you to get all the great benefits of HTML Forms, and then convert it to JSON so it’s easier to work with the data! I hope this has been useful.

Would you be interested in a series of what you can achieve with HTML and Web APIs?
What are you favourite web tips and tricks?

Источник

HTML to JSON

This library is capable to convert HTML string/element to JSON/JS Object or JSON to HTML.

Features

Example

div class pl-s">container"> ul> li>Hello strong>Worldstrong>li> ul> div>
< "type": "div", "attributes": < "class": "container" >, "content": [ < "type": "ul", "content": [ < "type": "li", "content": [ "Hello ", < "type": "strong", "content": [ "World" ] > ] > ] > ] >

Installation

Install html-to-json-parser with npm/yarn

npm install html-to-json-parser // npm yarn add html-to-json-parser // yarn

Usage/Examples

Convert HTML to JSON or JavaScript Object

Convert JSON to HTML using JavaScript

// Imports import  JSONToHTML > from 'html-to-json-parser'; // ES6 const  JSONToHTML > = require('html-to-json-parser'); // CommonJS // Data: JSON or JS Object const data =  type: "div", attributes:  class: "container" >, content: [  type: "ul", content: [  type: "li", content: [ "Hello ",  type: "strong", content: [ "World" ] > ] > ] > ] >; // Conversion let result = await JSONToHTML(data, false); // Default: true - true: return HTML String, false: return HTML Element

Convert JSON to HTML using TypeScript

// Imports import  JSONToHTML, JSONType > from 'html-to-json-parser'; // ES6 const  JSONToHTML, JSONType > = require('html-to-json-parser'); // CommonJS // Data: JSON or JS Object const data: JSONType =  type: "div", attributes:  class: "container" >, content: [  type: "ul", content: [  type: "li", content: [ "Hello ",  type: "strong", content: [ "World" ] > ] > ] > ] >; // Conversion let result = await JSONToHTML(data, false); // Default: true - true: return HTML String, false: return HTML Element

Contributing

  • Fork it!
  • Create your feature branch: git checkout -b my-new-feature
  • Commit your changes: git commit -am ‘Add some feature’
  • Push to the branch: git push origin my-new-feature
  • Submit a pull request 😀

Author

html-to-json-parser © Yousuf
Authored and maintained by Yousuf Kalim.

Источник

Читайте также:  All trades visible java
Оцените статью