Friday, February 13, 2015

JavaScript Form Generator: from Java EE to Bootstrap 3 (Part 2)

I was recently asked to extend one of my previous blog posts with the ability to inspect nested, annotation-based, Java EE back-end domain objects using a JavaScript, Bootstrap 3 front-end.

Metawidget generates widgets for domain object properties using a five-stage pipeline, specifically WidgetBuilders. There are WidgetBuilders for creating text boxes for string types, number inputs for number types, and so on. However whenever Metawidget encounters a property that its WidgetBuilders don't have a widget for, it creates a nested Metawidget and starts the pipeline process all over again:

The nested Metawidget shares the same pipeline objects as the outer Metawidget (i.e. same Inspectors, WidgetBuilders, etc). This makes nested Metawidgets very lightweight and performant. However it also means the Inspectors must be aware they can be used in multiple modes: in 'top-level' mode, and in 'nested mode'.

Inspectors can tell the difference because of the names array they're passed. In nested mode, the names array will be populated with a path of sub-properties to traverse. It's important the Inspectors honour this.

Back to our Java EE example. We'll expect two back-end REST schema calls: one for /rest/schema/person and one for /rest/schema/person/address. Clearly the back-end must also be expecting this and return different schemas for each (we recommend using client-side expiry headers on REST-based schemas: schemas don't change very often, and you can increase the performance of your UI by not making calls unnecessarily).

I've put together a complete example you can download here.

Of course, you may find multiple REST calls unacceptable for your use-case. Another approach would be to have your REST service return a JSON schema containing all your nested schemas at once. Then use metawidget.inspector.JsonSchemaInspector to inspect it. JsonSchemaInspector includes the ability to automatically traverse nested schemas, based on the names array.


Boyan Dzambazov said...

Thank you for your prompt response. I ended up with similar solution. But I did it externally i.e. using Backbone models I create the complete JSON schema I need and then pass it to the MW builder.
Your solution looks very elegant ... I will try to incorporate it in my current setup.

Christian Lesage said...

This is the example I've been waiting for. It really shines in showing off the essential stuff in a very concise manner.

I've known Metawidget for about a year and a half and I've always thought it was a great idea. To me, automatic, client-side UI generation is the next logical step to building RESTful services. However, I haven't used Metawidget in a real project until now since I was not very proficient in both Java and JavaScript back in 2013 when I discovered it. But now, I am confident enough about my knowledge in all the technologies involved. Thank you for making this project available and please, keep up the good work!