Grails and Dojo

60 %
40 %
Information about Grails and Dojo

Published on October 23, 2007

Author: hansamann

Source: slideshare.net

Description

Introduction to AJAX with Dojo using the Grails Rapid Web Development Framework.

GRAILS & DOJO

About Sven Using Groovy & Grails since Aug 2006 Grails Podcast, Groovy Series Working at Yahoo!, Inc Find out yourself www.svenhaiges.de

Using Groovy & Grails since Aug 2006

Grails Podcast, Groovy Series

Working at Yahoo!, Inc

Find out yourself www.svenhaiges.de

Goals You know how to get started! You know how AJAX is supported by Grails Tags, Libraries, Abstraction Layer You know why Groovy & Grails support your AJAX development, using Dojo Controllers & Actions, render(), Builders, Templates Tipps, gotchas, further resources

You know how to get started!

You know how AJAX is supported by Grails

Tags, Libraries, Abstraction Layer

You know why Groovy & Grails support your AJAX development, using Dojo

Controllers & Actions, render(), Builders, Templates

Tipps, gotchas, further resources

Getting Started

Getting started… Install Grails – done! Install Dojo Best download from dojotoolkit.org Place in web-app/js Or use the CDN version of dojo, no installation on your own server! ‘grails install-dojo’ installs dojo 0.4.3 !

Install Grails – done!

Install Dojo

Best

download from dojotoolkit.org

Place in web-app/js

Or use the CDN version of dojo, no installation on your own server! ‘grails install-dojo’ installs dojo 0.4.3 !

How to add Dojo to your pages 0.4.3: Load the dojo core library in your pages <g:javascript library=&quot;dojo&quot; /> Want to use dojo 0.9? Just use CDN: <script type=&quot;text/javascript&quot; djConfig=&quot;isDebug: true&quot; src=&quot;http://o.aolcdn.com/dojo/0.9.0/dojo/dojo.xd.js&quot;></script> <script type=&quot;text/javascript&quot;> dojo.addOnLoad(function(){ alert('loaded, all good'); }); </script>

0.4.3:

Load the dojo core library in your pages <g:javascript library=&quot;dojo&quot; />

Want to use dojo 0.9? Just use CDN:

Understanding Grails & AJAX What a surprise, Grails can serve JavaScript, too! Grails supports AJAX with special tags that provide basic AJAX support for these libraries: prototype, Yahoo! UI, Dojo Abstraction Layer Dojo currently has to be installed separately, Y UI and Prototype come with.

What a surprise, Grails can serve JavaScript, too!

Grails supports AJAX with special tags that provide basic AJAX support for these libraries: prototype, Yahoo! UI, Dojo

Abstraction Layer

Dojo currently has to be installed separately, Y UI and Prototype come with.

Dojo is more than AJAX Many say AJAX but really mean AJAX + Widgets. Dojo is very strong in Widgets. Besides this, you get way more: package system, animations, utilities, ShrinkSafe… But: you have to code this in your own code, in javascript. No tags can help you here.

Many say AJAX but really mean AJAX + Widgets.

Dojo is very strong in Widgets.

Besides this, you get way more: package system, animations, utilities, ShrinkSafe…

But: you have to code this in your own code, in javascript. No tags can help you here.

Learning Path Get familiar with Grails Use some Grails AJAX Tags in your pages, see what source code they generate Experiment with your own Javascript / Dojo code Really understand JavaScript & CSS

Get familiar with Grails

Use some Grails AJAX Tags in your pages, see what source code they generate

Experiment with your own Javascript / Dojo code

Really understand JavaScript & CSS

Grails AJAX Tags

 

remoteLink Creates an <a> Link, submits the request via AJAX and is capable of replacing a div upon response. Several onXXX Methods to customize the call. <div id=&quot;message&quot;></div> <g:remoteLink action=&quot;remoteLinkCallId&quot; id=&quot;1&quot; update=&quot;message&quot;> AJAX Call, id=1 </g:remoteLink> def remoteLinkCallId = { log.debug(&quot;${actionName} Action called with ${params.id}&quot;) render &quot;You called ${actionName} in ${controllerName} with ${params.id}&quot; }

Creates an <a> Link, submits the request via AJAX and is capable of replacing a div upon response. Several onXXX Methods to customize the call.

formRemote Creates a <form> that will submit all input fields via AJAX. <g:formRemote url=&quot;[action:'formRemoteCall']&quot; name=&quot;form2&quot; update=&quot;message&quot; onLoading=&quot;toggleSpinner(true)&quot; onLoaded=&quot;toggleSpinner(false)&quot; > User: <input name=&quot;user&quot; type=&quot;text&quot;></input> <input type=&quot;submit&quot; value=&quot;formRemote Call&quot;></input> </g:formRemote> def formRemoteCall = { log.debug(&quot;${actionName} Action called with ${params.user}&quot;) render &quot;You called ${actionName} in ${controllerName} with ${params.user}&quot; }

Creates a <form> that will submit all input fields via AJAX.

submitToRemote Same as formRemote, just the submit logic is executed on a specific submit button, not all submit buttons. <g:javascript library=&quot;dojo&quot; /> <g:javascript> dojo.require(&quot;dojo.io.IframeIO&quot;); </g:javascript> <g:form url=&quot;[action:'submitToRemoteCall']&quot; id=&quot;form2&quot; enctype=&quot;multipart/form-data&quot;> File: <input name=&quot;someFile&quot; type=&quot;file&quot;></input> <g:submitToRemote value=&quot;Submit Upload&quot; name=&quot;form2&quot; action=&quot;submitToRemoteUpload&quot; update=&quot;[success:'message',failure:'error']&quot; /> </g:form>

Same as formRemote, just the submit logic is executed on a specific submit button, not all submit buttons.

submitToRemote Form uploads require us to send the response in an HTML textarea field! def submitToRemoteUpload = { def f = request.getFile('someFile') if(f.empty) { render &quot;No file!&quot; } else { def fileName = f.getOriginalFilename() render(text:&quot;<html><body><textarea>You called ${actionName} in ${controllerName} with file ${fileName}</textarea></body></html>&quot;, contentType:&quot;text/html&quot;, encoding:&quot;UTF-8&quot;) } }

Form uploads require us to send the response in an HTML textarea field!

remoteField Creates an <input> field that submits itself automatically <g:remoteField before=&quot;if (this.value.length < 3) return false;&quot; action=&quot;quickSearch&quot; update=&quot;tableContent&quot; name=&quot;search&quot; paramName=&quot;search&quot;/> <span id=&quot;spinner&quot; style=&quot;display:none;&quot;> <img src=&quot;${createLinkTo(dir:'images',file:'spinner_mac.gif')}&quot; alt=&quot;Spinner&quot; /> </span> def quickSearch = { def devices = Device.findAllByModelLike(&quot;%${params.search}%&quot;, [max:20, sort :&quot;model&quot;, order:'asc']) render(template:'tableContent', model:[deviceList:devices]) }

Creates an <input> field that submits itself automatically

remoteField list.gsp <table> <thead> <tr> ... </tr> </thead> <tbody id=&quot;tableContent&quot;> <g:each in=&quot;${deviceList}&quot; var=&quot;device&quot;> ... </g:each> </tbody> </table> _tableContent.gsp <g:each in=&quot;${deviceList}&quot; var=&quot;device&quot;> <tr> <td>${device.id}</td> ... </tr> </g:each>

onXXX Methods

Grails AJAX Tags Basic AJAX functionality, good to get started or for very easy use cases More complex stuff: master dojo define the content you send yourself 0.9 Complex UI changes

Basic AJAX functionality, good to get started or for very easy use cases

More complex stuff: master dojo

define the content you send yourself

0.9

Complex UI changes

Grails AJAX Tags do not provide Support for Dijit Widgets … but Grails is the ideal server part for many data-hungry widgets – next section.

Support for Dijit Widgets

… but Grails is the ideal server part for many data-hungry widgets – next section.

Grails AJAX support

Render() is your best friend Whether you render pure text, html or JSON/XML formatted text, render() does it all. Creating simple responses is quick and easy: render &quot;This is easy.“ render &quot;{font:{id:10, name:'Arial'}}&quot; If you got larger, more complex responses, use a template to keep it clean: render(template:'podcastList', model:[podcasts:Podcast. findAll ()])

Whether you render pure text, html or JSON/XML formatted text, render() does it all.

Creating simple responses is quick and easy:

If you got larger, more complex responses, use a template to keep it clean:

Rendering JSON JSON is faster than XML, it should be AJAJ XML is evil, don’t use it Really, guess what’s faster: <?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?><linked-hash-map> <entry> <string>identifier</string> <string>id</string> </entry> <entry> <string>items</string> <list> <linked-hash-map> <entry> <string>id</string> <long>1</long> </entry> <entry> <string>url</string> <string>http://url1/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>2</long> </entry> <entry> <string>url</string> <string>http://url2/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>3</long> </entry> <entry> <string>url</string> <string>http://url3/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>4</long> </entry> <entry> <string>url</string> <string>http://url4/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>5</long> </entry> <entry> <string>url</string> <string>http://url5/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>6</long> </entry> <entry> <string>url</string> <string>http://url6/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>7</long> </entry> <entry> <string>url</string> <string>http://url7/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>8</long> </entry> <entry> <string>url</string> <string>http://url8/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>9</long> </entry> <entry> <string>url</string> <string>http://url9/rss</string> </entry> </linked-hash-map> <linked-hash-map> <entry> <string>id</string> <long>10</long> </entry> <entry> <string>url</string> <string>http://url10/rss</string> </entry> </linked-hash-map> </list> </entry> </linked-hash-map> {&quot;identifier&quot;:&quot;id&quot;,&quot;items&quot;:[{&quot;id&quot;:1,&quot;url&quot;:&quot;http://url1/rss&quot;},{&quot;id&quot;:2,&quot;url&quot;:&quot;http://url2/rss&quot;},{&quot;id&quot;:3,&quot;url&quot;:&quot;http://url3/rss&quot;},{&quot;id&quot;:4,&quot;url&quot;:&quot;http://url4/rss&quot;},{&quot;id&quot;:5,&quot;url&quot;:&quot;http://url5/rss&quot;},{&quot;id&quot;:6,&quot;url&quot;:&quot;http://url6/rss&quot;},{&quot;id&quot;:7,&quot;url&quot;:&quot;http://url7/rss&quot;},{&quot;id&quot;:8,&quot;url&quot;:&quot;http://url8/rss&quot;},{&quot;id&quot;:9,&quot;url&quot;:&quot;http://url9/rss&quot;},{&quot;id&quot;:10,&quot;url&quot;:&quot;http://url10/rss&quot;}]} XML or JSON?

JSON is faster than XML, it should be AJAJ

XML is evil, don’t use it

Really, guess what’s faster:

JSON is easy to read, too { &quot;identifier&quot;:&quot;id&quot;, &quot;items&quot;: [ { &quot;id&quot;:1, &quot;url&quot;:&quot;http://url1/rss&quot; }, { &quot;id&quot;:2, &quot;url&quot;:&quot;http://url2/rss&quot; }, { &quot;id&quot;:3, &quot;url&quot;:&quot;http://url3/rss&quot; }, { &quot;id&quot;:4, &quot;url&quot;:&quot;http://url4/rss&quot; } ] }

JSON is easy to create, too Then work with it in you app: render(builder:'json') { element(imagePath: &quot; /app/myimage.png&quot;) } {&quot;element&quot;:{&quot;imagePath&quot;:&quot;/app/myimage.png&quot;}} dojo.io.iframe.send( { url: &quot;/some/url&quot;, form: dojo.byId('formImage'), handleAs: &quot; json &quot;, method: &quot;POST&quot;, handle: function(response, ioArgs) { var fileName = response.elementImage.fileName; } });

Then work with it in you app:

Using converter & Render Converts domain objects to JSON import grails.converters.JSON def podcastJSON = { def podcast = Podcast.get(1) render podcast as JSON } { &quot;id&quot;:1, &quot;class&quot;:&quot;Podcast&quot;, &quot;author&quot;:&quot;Author1&quot;, &quot;feedURL&quot;:&quot;http://url1/rss&quot; }

Converts domain objects to JSON

import grails.converters.JSON

def podcastJSON = {

def podcast = Podcast.get(1)

render podcast as JSON

}

Special Dojo Widgets & Grails

Data-hungry widgets ComboBox Provides a list of acceptable values but user can still enter his own value. Has a value, just like a textbox. FilteringSelect Much like ComboBox, but has label/value like a select. Will set ‘identifier’ as value of selected label. Tree

ComboBox

Provides a list of acceptable values but user can still enter his own value. Has a value, just like a textbox.

FilteringSelect

Much like ComboBox, but has label/value like a select. Will set ‘identifier’ as value of selected label.

Tree

Dojo ComboBox & Grails GSP <div dojoType=&quot;dojo.data.ItemFileReadStore&quot; jsId=&quot;stateStore&quot; url=&quot;<g:createLink controller=&quot;widget&quot; action=&quot;comboboxConverterData“ />&quot;> </div> <input dojoType=&quot;dijit.form.ComboBox&quot; store=&quot;stateStore&quot; hasDownArrow=&quot;false&quot; value=&quot;&quot; searchAttr=&quot;url&quot; name=“feed&quot; onChange=&quot;setValue&quot; />

GSP

Dojo ComboBox & Grails Grails Action def comboboxConverterData = { def items = [] def podcasts = Podcast.findAll(); podcasts.each { podcast -> items << [id:podcast.id, url:podcast.feedURL] } def json = [identifier:&quot;id&quot;, items: items] render json as JSON } Using the Grails Converter simplifies the creation of the expected json structure.

Grails Action

Using the Grails Converter simplifies the creation of the expected json structure.

Dojo FilterSelect & Grails GSP <div dojoType=&quot;dojo.data.ItemFileReadStore&quot; jsId=&quot;feedStore&quot; url=&quot;<g:createLink controller=&quot;widget&quot; action=&quot;filterSelectData&quot; />&quot;> </div> <input dojoType=&quot;dijit.form.FilteringSelect&quot; id=&quot;chooser&quot; store=&quot;feedStore&quot; searchAttr=&quot;url&quot; name=&quot;feed&quot; autocomplete=&quot;true&quot; pageSize=&quot;5&quot; />

GSP

Dojo FilterSelect & Grails Grails Action – the same…but! def filterSelectData = { def items = [] def podcasts = Podcast.findAll(); podcasts.each { podcast -> items << [id:podcast.id, url:podcast.feedURL] } def json = [identifier:&quot;id&quot;, items: items] render json as JSON } Once the user has chosen a label from the list, the identifier (here: podcast.id value) will be used as the value of the widget.

Grails Action – the same…but!

Once the user has chosen a label from the list, the identifier (here: podcast.id value) will be used as the value of the widget.

Dojo Tree & Grails GSP <div dojoType=&quot;dojo.data.ItemFileReadStore&quot; jsId=&quot;treeStore&quot; url=&quot;<g:createLink controller=&quot;widget&quot; action=&quot;treeData&quot; />&quot;> </div> <div dojoType=&quot;dijit.Tree&quot; store=&quot;treeStore&quot; childrenAttr=&quot;children&quot; labelAttr=&quot;url&quot;> </div>

GSP

Dojo Tree & Grails Grails Action def treeData = { def items = [] def children = [] (1..3).each { children << [_reference:&quot;${it}&quot;] } def podcasts = Podcast.findAll(); podcasts.each { podcast -> items << [id:podcast.id, url:podcast.feedURL, children:children ] } def json = [ identifier:&quot;id&quot; , label:'url', items: items] render json as JSON }

Grails Action

Tipps & Resources

Resources Download Dojo, check the test directories for tons of examples Dojo API Tool soon available for 0.9 http://www.dojotoolkit.org/api Converters Plugin http://www.grails.org/Converters+Plugin Dynamic Controller Methods, incl. render() grails.org/Controller+Dynamic+Methods

Download Dojo, check the test directories for tons of examples

Dojo API Tool soon available for 0.9

http://www.dojotoolkit.org/api

Converters Plugin

http://www.grails.org/Converters+Plugin

Dynamic Controller Methods, incl. render()

grails.org/Controller+Dynamic+Methods

Resources JSON Formatter http://www.curiousconcept.com/jsonformatter Blogs blogs blogs Grails Podcast http://hansamann.podspot.de/rss

JSON Formatter

http://www.curiousconcept.com/jsonformatter

Blogs blogs blogs

Grails Podcast

http://hansamann.podspot.de/rss

THX Y IM/SKYPE hansamann

Add a comment

Related presentations

Related pages

Grails Plugin: Dojo 1.7.2.0 for Grails

Targets: grails install-custom-dojo. This target will build an optimized version of dojo that is tailored to your application. Read the FAQ for more ...
Read more

Dojo or flex with Grails? - Stack Overflow

I plan to build a database management system using Grails as the main framework. On the client side, I'm thinking whether to use dojo or flex to make a ...
Read more

The Grails Framework

Grails is a powerful web framework, for the Java platform aimed at multiplying developers’ productivity thanks to a Convention-over-Configuration, ...
Read more

Grails & Dojo: Part I - DZone Web Dev

I've been working on integrating Grails and the recently released Dojo 1.0.2. I'm particularly interested in the Dijit components that are now part of Dojo.
Read more

Grails Dojo ItemFileReadStore - Stack Overflow

Setting up a simple grails app with Dojo, i used the . grails install-plugin dojo to setup the dojo js files. In my main.gsp i have this
Read more

使用 Dojo 和 Grails 快速实现数据的增删改查(CRUD)

使用 Grails 可以快速开发 web 应用,但其自带的 CRUD 功能(scaffold)过于简陋,本文选用 Dojo 丰富的控件来美化用户 ...
Read more

Grails+Dojo Ajax File Upload - CodeProject

Grails+Dojo Ajax File Upload. Matt Stine, 14 Apr 2009 CPOL 5.00 (2 votes) 1: 2: 3: 4: 5: 5.00/5 - 2 votes. μ 5.00, σ a 5.00 ...
Read more

GitHub - cfxram/grails-dojo: rob@netapplogic.com

grails-dojo - rob@netapplogic.com ... Clone with HTTPS Use Git or checkout with SVN using the web URL.
Read more

Grails und dojo - altes groovy/grails-Forum @CODEKICKER

Diese Seite zeigt den Thread "Grails und dojo" der ehemaligen Webseite groovy-forum.de, welche durch einen Serverunfall zerstört wurde ...
Read more