DEV Community

loading...

JSON Form Definition

megazear7
Loves to learn, create and share. Websites, games, stories or simply ideas. Sharing all the possibilities of a "blank canvas" on www.alexlockhart.me
・1 min read

I work in the area of web development called web content management or WCM for short. One of the problems that often needs resolved is an easy and repeatable way to define forms through which WCM authors use to create content.

An often first step in the creation of any new feature is defining a form which may include text fields, checkboxes, radio options, specialized text fields such as urls, dates, or paths to other pieces of content. On top of this having a multivalued list of any of these fields is also common such as a list of links each with a corresponding checkbox to determine if the link opens in a new tab or not. These forms can become quite complex and having an easy way to define them speeds up development of new features.

It occurred to me that using JSON as a means of defining a form would allow a developer to define what JSON they expect back from the form after the user interacts with it. This is similar to the idea behind GraphQL, tell the API what JSON you want to see and then it gives it to you. I have created an example of what this form-definition JSON might look like:

{
   "firstName":"",
   "isDeveloper":true,
   "height":0
}

In this example we have a text field with the name of "firstName", a checkbox with the name "isDeveloper", and a number field with the name "height". However what if we wanted to add default values to these fields? You might already see what I am seeing:


{
   "firstName":"Default first name",
   "isDeveloper":true,
   "height":60
}

The default value of each form field can just be the value of the field in the JSON. What if we wanted the user of this form to be able to define a list of contacts? Maybe with a "+" button in the form to allow them to add new fields to a list?


{
   "firstName":"Default first name",
   "isDeveloper":true,
   "height":60,
   "contacts":[
      ""
   ]
}

We add an array value to the JSON which represents a multi valued form element. In this way the user could add a list text fields, each of which represents a contact. However what if we want each contact to have a name and an email?

{
   "firstName":"Default first name",
   "isDeveloper":true,
   "height":60,
   "contacts":[
      {
         "firstName":"",
         "email":""
      }
   ]
}

Now we put an object in the array instead of a simple string field. This means that each multi valued element within the contact list has two associated values, "firstName" and "email".

However what if for one of our fields we want to explicitly specify an associated label, validation that should be applied, or a placeholder value?

{
   "firstName":{
      "type":"",
      "defaultValue":"Default first name",
      "placeholder":"Example Place holder"
   },
   "isDeveloper":{
      "type":true,
      "label":"Are you a developer?"
   },
   "height":60,
   "contacts":[
      {
         "firstName":"",
         "email":{
            "type":"",
            "validation":"email"
         }
      }
   ]
}

Now the objects can either represent a set of fields for the form or if they have the "type" property they represent a single field of the given type. This provides an entry point for defining things such as validation, labels, and other data that the form may need for the field. Notice that the default value for the field is no longer passed in the string itself but is provided in a "defaultValue" property. This is so that we can reserve the use of the "type" property as you will see next.

Not all strings are created equal. What if we wanted a string field that represents a path to another piece of data in the WCM system or maybe a date field?

{
   "firstName":{
      "type":"",
      "defaultValue":"Default first name",
      "placeholder":"Example Place holder"
   },
   "birthDate":{
      "type":"date"
   },
   "homePage":{
      "type":"path"
   },
   "isDeveloper":{
      "type":true,
      "label":"Are you a developer?"
   },
   "height":60,
   "contacts":[
      {
         "firstName":"",
         "email":{
            "type":"",
            "validation":"email"
         }
      }
   ]
}

Now custom dialog field types can be specified that store the resulting value as a string, but have a custom user interaction for determining that string. Now what would the JSON that the form generates look like? Well it looks almost exactly the same, except wherever you see the "type" field in the JSON that object is replaced with a value of the given type:

{
   "firstName":"Joe Smith",
   "birthDate":"5/26/1983",
   "homePage":"/some/example/path/that/specifies/joe/smiths/homepage",
   "isDeveloper":true,
   "height":71,
   "contacts":[
      {
         "firstName":"Steve Adams",
         "email":"steve.adams@example.com"
      },
      {
         "firstName":"Bob Greene",
         "email":"bobgreen12@example.com"
      }
   ]
}

When the user submits the form this JSON can then be stored in a database or in your WCM system however you would like.

Now I just need to create the JavaScript library that creates the form and then generates the JSON based upon the form. I might do that has a side project in the coming months if time allows. I know this would be useful in some of the projects that I have going on.

Check out my blog for more of my musings upon technology and various other topics.

Discussion (4)

Collapse
misterhtmlcss profile image
Roger K. • Edited

Hi Alex,

Came across this today. I've been interested in what you proposed for a while and I came across (jsonform.github.io/jsonform) while doing some research for my employer.

I'd love to know your thoughts as it relates to your idea above.

Update: brutusin.org/json-forms | just found this one too.

Collapse
megazear7 profile image
megazear7 Author

Nice finds! My original goal was to come up with something similar to GraphQL where you basically just specify the data exactly as you want to see it and then what you get back is the same data structure. However the more I have thought about it the more I realized that for a form you need to know more than just the data types and data hierarchy. Most of these libraries I have found went in the same direction.

If I were to create such a library I would try to maintain a few guidelines:

  1. The schema should be completely separated from the display of the form.
  2. Interpreting the form as a JSON object should be separated from generating the form from the schema.
  3. Layout and display configuration should be a library layered on top of these first items 1 and 2.

Many of these libraries I have found as well as the two you mentioned are very intriguing. I am thinking however that there is probably room for something new as I haven't found anything that meets the above three criteria.

Collapse
misterhtmlcss profile image
Roger K. • Edited

I bet what you are thinking is a little bit like how platforms like Wix likely (I suspect) work with their data/content.

I'd be game to work on it with you. Let me know. Otherwise good luck and share your progress!

Thread Thread
megazear7 profile image
megazear7 Author

It looks like this is actually right on the money for what I was thinking about: github.com/json-editor/json-editor

It uses json-schema.org/ and then generates an HTML form and comes with integration capabilities with bootstrap, foundation, and jQueryUI.

I think this is actually perfect because it separates concerns it into three pieces:

  1. JSON Schema
  2. HTML Form Generation
  3. Integration with UI frameworks