Create Gaudi's File Easily With A Web App
Even if this file is easy to write, I wanted a graphical user interface to build it, for people who are not familiar with the documentation. So during the last hackday at marmelab, I spent a day working with the AngularJs and Joint.js libraries to create this interface.
What I Wanted The Application To Do
- List all available Gaudi components, and allow to drag and drop them in a "board".
- Components can be linked together, and a popin should display a form to edit the configuration of each component.
- A zone will be automatically updated with the current configuration, a download button should create the
.gaudi.ymlfile containing the configuration.
- I'm not a great designer, so to start with a good base I've downloaded Twitter Bootstrap to render a good looking UI.
- Components loading and configuration will be handled by AngularJs.
- François, my boss, recommended me to use Joint.js to link components together.
From The Paper To The Browser
The initial steps of application design (how to architecture the parts, which library to use, etc.) is always the fun part; but linking them together is very challenging. Here are three examples of the integration problems I've met during that day.
Integrating Joint.js and Angularjs
To be able to communicate with AngularJs, I created a custom jointjs element, triggering DOM events catched by AngularJs.
Jointjs convention slowed me down during the development (eg.
joint.shapes.html.GaudiGraphComponent should use a view called
joint.shapes.html.ElementView), but my recent work with Backbone.js on a marmelab project helped me debugging my custom Joint.js element.
Joint.js is not really easy to bootstrap, and the documentation is not easy to understand.
Integrating Jquery UI and AngularJs
The drag and drop is managed by the jQuery UI droppable (a familiar library for me). But the integration with AngularJs was not easy.
ng-repeat directive doesn't provide a way to trigger a callback once the list of components is renderer. So I had to create a new directive called after the rending of each element, and trigger an event if this element is the last one.
Integrating Bootstrap and AngularJs (yes again)
I found libraries like angular-ui bootstrap aiming to create Bootstrap components in directives. These were a great help.