jAces - Ultimate companion to create database applications on Grails
Dependency :
build ":jaces:1.7.2.2"Custom repositories :
mavenRepo "http://jaces.googlecode.com/svn/"
Summary
jAces streamlines the process of creating database applications. It combines the power of Dojo and Grails to create a superior platform for developing at lowest cost and at lowest complexity. It is even fun develop database application with jAces. Even full blown master-detail forms can be created within minutes.
Installation
grails install-plugin jaces
Description
jAces is a Grails plugin that bridges dojo and Grails for creating rich client web applications.
There is now a sample application available.http://jaces.googlecode.com/svn/jaces-samples-simple/The sample application contains:
- a nice index page with jaces hypar links and a dojo tab container as the body container
- a master-child form sample (From Person to ContactInfo)
- a combo sample fetching an N-to-1 relation (From ExchangeRate to Currency)
Would you like to see jAces in action? Click here to try the social networking application developed with jAces
The last build of jAces has dojo 1.7.2.
Dojo source is pulled into jAces source through svn:externals. The links from jAces to dojo are as follows:
Local Path Remote Path trunk/web-app/js/dojo/dojo http://svn.dojotoolkit.org/src/tags/release-1.7.2/dojo trunk/web-app/js/dojo/dijit http://svn.dojotoolkit.org/src/tags/release-1.7.2/dijit trunk/web-app/js/dojo/dojox http://svn.dojotoolkit.org/src/tags/release-1.7.2/dojox trunk/web-app/js/dojo/util http://svn.dojotoolkit.org/src/tags/release-1.7.2/util
The plugin already contains a custom dojo build. When there is a need to create your own custom build, follow these steps :
- Checkout jAces source from https://svn.codehaus.org/grails-plugins/grails-jaces/trunk
- Play with /web-app/js/release.profile.js to create the custom profile
- Play with
lines to load the classes common to all pages once at startup in /grails-app/views/jaces/header.gsp.dojo.require("..")- Run /runCustomBuild.bat from the command line within the same folder.
- The custom build will be placed into /web-app/js/release. If there is just one layer, as jAces has, you do not need to do anything else. In order to let dojo know about additional layers at runtime, though, you should multiply the following registerModulePath call for each additional layer.
require(['dojo/_base/kernel', 'dojo/_base/loader'], function(dojo){ dojo.registerModulePath("dijit", "<g:resource plugin="jaces" dir="/js" file="/release/dojo/layers/dijit"/>"); });
If you are not an expert on dojo custom builds start with the default configuration and create your custom build once you get familiar with dojo and jAces.The layout of dojo artifacts has been taken from the article Custom build in dojo 1.7. Reading it will help you certainly.What jAces is for?Grails itself is superior platform for developing web applications while dojo is the leader in the Javascript Rich Client world. You wonder what jAces does to create an additional value. Let us make the idea clear:Grails and dojo together is a good base where you can start building your database application. However you still need a lot to put onto the base to make the development smooth and fast. Below is a list of major functions jAces puts onto the base to make the development fast and smooth.
- A well defined data exhange protocol between dojo widgets and Grails
- jAces scaffolding template supporting CRUD operations, master/child forms, sorting, pagination, and form filtering
- Extension points where you can write code to change the default behaviors of jAces and to commit transactions in addition to the seamless jAces transactions
- Support for One-to-One, Many-to-One and One-to-Many associations on forms
| Class Name |
|---|
| jaces.jAcesClass |
| jaces.View |
| jaces.Hypar |
| jaces.layout.ContentPane |
| jaces.layout.Portlet |
| jaces.body.BoundedForm |
| jaces.body.BoundedGrid |
| jaces.body.Form |
| jaces.Store |
| jaces.form.StandardToolbar |
| jaces.form.AutoNavigator |
| jaces.form.Navigator |
| jaces.form.Delete |
| jaces.form.Update |
| jaces.form.Forward |
| jaces.form.Backward |
| jaces.form.New |
| jaces.form.Filter |
| jaces.form.ApplyFilter |
| jaces.form.RemoveFilter |
| jaces.form.Page |
| jaces.form.Pages |
| jaces.form.FormView |
| jaces.form.SheetView |
| jaces.form.PageLimit |
| jaces.form.SortAscending |
| jaces.form.SortDescending |
| jaces.form.ComboBox |
| jaces.form.TriStateCheckBox |
| jaces.social.BoundedGrid |
| jaces.social.Row |
| jaces.social.BoundedGrid |
| jaces.social.DojangoGrid |
| jaces.social.DojangoRow |
| jaces.social.DojangoRowTemplate |
Scaffolding Sample
Domain Class
class Country {
String title
static constraints = {
title(nullable : true)
}
}Controller Class
class CountryController{
def scaffold = true
def v_index = {
render (view: 'uw/v_create')
}
}View
<h1>Countries</h1><br> <div dojoType="jaces.View" style="height: 150px;" controller="<g:createLink controller="country"/>" form="Form"> <div dojoType="jaces.form.StandardToolbar"></div> <div dojoType="jaces.body.BoundedForm"> <br> <table> <tr> <td><label for="uid">ID:</label></td> <td> <input type="text" dojoType="dijit.form.TextBox" valueCol=".id"/> </td> </tr> <tr> <td><label for="uid">Title:</label></td> <td> <input type="text" dojoType="dijit.form.TextBox" valueCol=".title"/> </td> </tr> </table><br> </div> <div dojoType="jaces.form.Navigator"></div> </div>
Main Page
<html>
<head>
<meta name="layout" content="jaces_empty">
</head>
<body>
<g:include controller="country" action="v_index"/>
</body>
</html>Form and Sheet Views
Please pay attention to how jAces binds widgets to Grails. jaces.View is bounded to the scaffolded controller via the controller attribute as the form widgets are bounded to the domain class' properties via the widget attribute valueCol. If valueCol does not exist, jAces binds widgets to domain class' properties via id attribute.
jAces is not very happy with Grails resources plugin's existence and some dojo js files give 404. Till the problem is resolved, place the following line to your Config.groovygrails.resources.adhoc.excludes=['**']
For advanced samples, you may experiment the social networking application Hypar