Transcript Slide 1

Intro to Building Desktop-Style Web UIs
JavaScript on Grails
Torey Lomenda
Senior Consultant
Object Partners Inc.
[email protected]
http://twitter.com/tlomenda
http://www.objectpartners.com/weblog
Introduction
 Founded 1996, privately held company
 Minneapolis based
– Branch office in Omaha, NE
 50 employees and growing
 Enterprise IT Consulting
– Leveraging leading edge and open source technologies
• Striving for the highest levels of productivity and quality
– Delivering mission critical applications that are:
• Performant
• Scalable
• Easier to enhance and maintain
 SpringSource partner
– Using Spring for 5+ years
– Excited about Grails
Agenda
 Introducing Ext JS and Grails UI
– Exploring in Ten Steps
– Event-based Applications (DOM Manipulation, Events, Ajax)
 Technologies Working Together
– Grails Platform
 Demo – Hockey Stats Application
– Side By Side Comparison of Ext JS and GrailsUI/Yahoo! UI
 Development Practices
A Note on Javascript Libraries
 Rich UI Goodness
– Dynamically change DOM and CSS based on user interaction
 Utility Libraries
– Prototype, script.aculo.us
– sprinkle effects on existing Web 1.0 app
 Mid-Level Libraries (Utilities and Controls)
– Yahoo! User Interface (YUI)
– JQuery
– Nice foundation to build full features Widgets
 Full-Featured (Out-of-the-box Widgets)
– Ext JS – A Nice UI Component Model
– GrailsUI - Extending YUI the Grails Way
– Dojo
Introducing Ext JS and Grails UI
Ext JS
JavaScript Namespace: Ext
Provides high performance,
customizable “real-world” UI
widgets
Well designed, documented and
extensible component model
Uses adapters to work seamlessly
with other libraries (YUI, JQuery,
Prototype)
Open sourced under GPLv3
Commercial License
$289 per developer
$1159 for 5 developers
Grails UI
JavaScript Namespace: GRAILSUI
A Grails plugin that provides an
extensive tag library of rich ajax
components based on the Yahoo! UI
(YUI) JavaScript library and a YUI
extension called the Bubbling Library.
It has been designed for ease-of-use as
well as configurability.
Yahoo! UI (YUI)
JavaScript Namespace: YAHOO
A set of utilities and controls,
written in JavaScript, for building
richly interactive web applications
using techniques such as DOM
scripting, DHTML and AJAX.
YUI is available under a BSD
license and is free for all uses.
Exploring in Ten Steps
Step 0: Layout
Step 1: Menus
Step 2: Dynamic Forms
Step 3: Tree Views
Step 4: Accordions and Tabs
Step 5: Data Grids
Step 6: Search Combo Box/AutoComplete
Step 7: Drag & Drop
Step 8: Rich Text Editor
Step 9: Customize Look and Feel
Highly Interactive Web Apps
 Websites/Web 1.0
– Informational based
– Some advanced features such as eCommerce and Content
Management
– CRUD style applications
 Web 2.0 Applications
– Full featured desktop-style interface; intuitive, immediate
interaction a user experiences
– Advanced features like workflow and other processes that
require a high level of user interaction
Event-Based Applications
 Paradigm Shift to event-based approach
– Flow of application determined by change of state or user
interaction (the event).
– Event is broadcast
– Listener/Observer acts on the event
 Common Traps
– Acting on a component or object before it is in a state to
handle the action. Caused by mixing procedural
programming with event-based programming.
 Things to Consider
– Is the DOM ready? Is the DOM Element available?
[eg: Ext.onReady(), YAHOO.util.Event.onDOMReady()]
– Is the component/object in a ready state?
– Timers to wait for conditions (ie: setTimeout, setInterval)
Common Trap
Procedural Programming
var panel = new Ext.Panel({
title: “My Panel”,
items: [{html: “We are Here!”}]});
panel.render();
panel.items.get(0).getEl();
getEl() returns undefined.
Tried to get the element
before render completed.
Event Programming
var panel = new Ext.Panel({
title: “My Panel”,
items: [{html: “We are Here!”}]});
panel.on(“render”,
function(thisPanel) {
thisPanel.items.get(0).getEl();
});
panel.render();
getEl() returns DOM
element. Invoked action
is event-based.
DOM Manipulation
Ext JS
YUI
Finding Nodes
Finding Nodes
var elById = Ext.get(elId)
var elBySelector =
Ext.DomQuery.selectNode(
'a.mycls[@href*=”myref”]:first');
var elById = YAHOO.util.Dom.get(elId);
var elBySelector =
YAHOO.util.Selector.query('li a');
Manipulating DOM
Ext.DomHelper
Manipulating DOM
YAHOO.util.Dom
Ajax Support
Ext JS
var successFn = function(res) {
};
var failureFn = function(res) {
};
Ext.Ajax.request({
url: 'someUrl',
method: 'GET|POST',
success: successFn,
failure: failureFn
});
YUI
var callback = {
success: function(res) {
},
failure: function(res) {
}
}
YAHOO.util.Connect.asyncRequest(
'POST',
'someUrl',
callback,
['param1=blah']);
Technologies Working Together
 Enabling Web Technologies
– CSS (Cascading Style Sheets)
– DOM (Document Object Model)
– Javascript & Ajax (Async Javascript)
 Grails Platform
–
–
–
–
Solid Foundation (Groovy, Spring, Hibernate, SiteMesh)
Plugin Architecture (Spring Security, Rich UI, many others)
Modularity: Easy to build custom plugins
RESTful Web Services
The Role of CSS
 Look and Feel
– Visual Styling
– Positioning
 Cool Effects
– Examples: Drag & Drop, Expand/Collapse, Overlaying,
many others
CSS Box Model
DEMO: Hockey Stats Manager
Use Case Model
Administer
Leagues
League Admin
Manage Players
Player Admin
Manage Scouting
Reports
Scout
Domain Model
Role
RequestMapping
User
Team
home
Player
ScoutingReport
visitor
ScoutingNotes
Game
League
Season
PlayerStats
PlayerNews
Component Model
Hockey Stats App Using Ext JS
hockeystats-extjs
<Grails Plugin>
hockeystats-domain
HTML
(GSP)
<Grails Plugin>
ext-js
<Grails Plugin>
acegi
(Spring Security
REST
(JSON)
RESTful Web Sevices
(League, Team, Player,
Scouting Report)
Browser
Hockey Stats App Using Grails UI
hockeystats-yui
<Grails Plugin>
hockeystats-domain
HTML
(GSP)
<Grails Plugin>
Grails UI
<Grails Plugin>
Bubbling
REST
(JSON)
<Grails Plugin>
yui
<Grails Plugin>
acegi
(Spring Security)
Step 1 – Border Layout
Ext JS
YUI
var viewport = new Ext.ViewPort({
layout: 'border',
renderTo: 'some-div',
items: [
{region: 'north',
xtype: 'panel'},
{region: 'west',
xtype: 'panel'},
{region: 'south',
xtype: 'panel'},
]
});
var layout = YAHOO.widget.Layout({
units: [
{position: 'top',
body: 'header-div'},
{position: 'left',
body: 'side-div'},
{position: 'bottom',
body: 'footer-div'},
]
});
*Leverage Grails SiteMesh Integration
Step 2 – Menus
Ext JS
new Ext.Toolbar({
renderTo: 'some-div',
items: [
{text: “Home”,
xtype: “tbbutton”,
handler: someFn},
{xtype: “tbseparator”},
{text: “Stats Menu”,
xtype: “tbbutton”,
menu: [
{title: “Sub 1”,
disabled: false;
handler: someFn
}
]
}
]
});
YUI
var menu =
new YAHOO.widget.Menubar();
menu.addItems([
{text: “Home”,
onclick: someFn
},
{text: “Stats Menu”
submenu: {
id: “sub1Menu”,
itemData: [
{text: “Sub 1”,
disabled: false,
onclick: someFn
}
]
}
]);
Step 3 – Dynamic Forms
Ext JS
Nice Dynamic Forms
Highlighted Features:
Rich ComboBox Support
Collapsible Field Sets
Built-in Field Validation
Binding buttons to forms
Can use applyTo() to decorate
existing HTML form.
Preferred option is dynamic
Grails UI / YUI
Minimal GrailsUI support for
Forms
Grails UI Widgets:
Date Picker
Expandable Panel
Why the SplitButton?
Should have used Grails UI
Autocomplete
YUI decorates existing HTML form
markup
Custom validation can be added
to a form
Step 4 - Trees
Ext JS
Use:
Ext.tree.TreePanel
Ext.Tree.TreeLoader
new Ext.tree.TreePanel({
useArrows: true,
root: {
nodeType: “async”,
text: “Some Tree”,
draggable: false,
id: “someRootNode”
},
loader: someTreeLoader
});
YUI
Use:
YAHOO.widget.TreeView
YAHOO.util.Connect
var loadFn = function(node,
onCompleteCallback) {
// Some Ajax call then complete
...
onCompleteCallback();
};
var tree =
new YAHOO.widget.TreeView(“Tree”);
var root = tree.getRoot();
var node = new YAHOO.widget.TextNode({
label: “Some Node”,
labelElId: “someNodeId”}, root);
node.id = “attachIdToNode”;
node.labelElId = “someNodId”);
node.setDynamicLoad(loadFn);
Step 5 – Accordions & Tabs
Ext JS
var p = new Ext.Panel({
layout: 'accordion',
renderTo: 'some-div',
cls: 'someCls',
items: [
{title: 'Blah'
collapsed: true,
xtype: 'panel'
},
{title: 'Blah Tabs',
collapsed: true,
xtype: 'panel',
items: [
xtype: 'tabpanel',
activeItem: 0,
items: [// tabs]
]
}
]
});
Grails UI
<gui:accordion id='someId'
class=”someCls”>
<gui:accordionElement id=”1”
title=”Blah”>
<div />
</gui:accordionElement>
<gui:accordionElement id=”2”
title=”Blah”>
<gui:tabView>
<gui:tab id=”tab1”
title=”Tab1”>
<div />
</gui:tab>
<gui:tabView>
</gui:accordionElement>
</gui:accordion>
Step 6 – Data Grids
Ext JS
var someGridStore =
new Ext.data.JsonStore({
data: dataObj,
root: “dataRoot”,
fields: [
{name: “col1”},
{name” “col2”}
]
});
new Ext.GridPanel({
store: someGridStore,
autoHeight: true,
columns: [
{header: “Col 1”,
dataIndex: “col1”},
{header: “Col 2”,
dataIndex: “col2”}
],
viewConfig: {
forceFit: true,
getRowClass: someCssFn
}
});
Grails UI
Markup:
<gui:dataTable id=“someDataTable”
draggableColumns=“true”
columnDefs=“[
[key:‘col1’, label:‘Col 1’],
[key :’col2’, label:’Col 2’]
]“
sortedBy: “col1”
controller: “someController”
action: “someAction”
params: [id:0]
resultList: “dataRoot”
rowExpansion: false
rowsPerPage: 10
/>
JS Code (Refresh Data):
GRAILSUI.someDataTable.
getDataSource().
sendRequest(“id=xxx”, callback);
Step 7 – Custom Search Combo
Ext JS
var resultTemplate = Ext.XTemplate(
‘<tpl for=“.”>’ +
‘<div id=“someItem”{id}’ +
‘({name})’ +
‘</div>’ +
‘</tpl>’
new Ext.form.ComboBox({
store: someStore,
typeAhead: false,
loadingText: “”,
cls: “”,
pageSize: 10,
minChars: 1,
hideTrigger: true,
tpl: resultTemplate,
itemSelector: “div.someItem”
});
GrailsUI / YUI
Markup:
<gui:autoComplete
id=“someCombo”
resultName=“dataRoot”
labelField=“resultLabel”
idField=“id”
controller=“someController”
action=“someAction”
minQueryLength=“1”
typeAhead=“false”
resultTypeList=“false”
JS Code (Refresh Data):
//Attach Behaviour
GRAILSUI.someCombo_autocomplete.
doBeforeParseData =
function(req, res, callback) {
// Build resultLabel
};
GRAILSUI.someCombo_autocomplete.
formatResult = function(d, q, m) {
// Put formatting code here
};
Step 8 – Drag & Drop
Ext JS
var dragSource =
new Ext.dd.DragSource(
‘someDivElementId’,
{someConfig: “prop1”});
var dropTarget =
new Ext.dd.DropTarget(
‘someDropTarget’,
notifyDrop: someFn});
YUI
var dragSource =
new YAHOO.util.DDProxy(
‘someDivElementId’);
dragSource.startDrag = function() {
// Do Something
}
dragSource.onDragDrop =
function(event, id) {
// Use id of node you are
// Dropping into
}
var dropTarget =
new YAHOO.util.DDTarget(
‘someDropTargetId’);
Step 9 – Rich Text Editor
Ext JS
Use 3rd Party Widgets such as
TinyMCE
(http://tinymce.moxiecode.com/)
GrailsUI / YUI
<gui:dialog title=“Some Editor”
draggable=“true
modal=“true”
buttons=“[
[text: ‘Ok’, isDefault: true]
]”
triggers:[]>
<gui:richEditor id=“SomeId”
value=“Default Text” />
</gui:dialog>
Step 10 – Look & Feel
* Understand the DOM generated. Use Firebug
to Inspect DOM.
Ext JS (Style Accordion)
.my-accordion {
}
.my-accordion .x-panel,
.my-accordion .x-accordion-hd {
background: none;
}
.my-accordion .x-panel-body {
border: 0px;
}
.my-accordion .x-panel-header {
background: transparent none repeat scroll 0 0;
border-bottom:1px solid !important;
border-left:medium none;
border-right:medium none;
bordertop:medium none;
width: 95%;
margin-top: 10px;
}.my-accordion .x-tool {
float: left;
}.my-accordion .x-panel-header-text {
margin-left: 5px;
font-weight: bold;
}
Grails UI (Style Accordion)
#playerProfileInfoAccordion .actions {
left:2px;
margin-right: 10px;
position:absolute;
text-align:right;
top:5px;
}
#playerProfileInfoAccordion .yui-panel{
border: 0px;
border-style: none !important;
}
#playerProfileInfoAccordion .hd {
background:none !important;
width: 95%;
border-bottom: 1px solid !important;
border-right: 0px !important;
padding:0 20px !important
General Comparison
Ext JS
 Pros
GrailsUI / YUI
 Pros
– Powerful, intuitive, easy to use.
(it actually works??)
– Powerful, intuitive, easy to use.
(it actually works??)
– Readable, extensible JS
component model
– Nice tag support to embed
components through mark-up
– feature rich components out-ofthe-box. Many config options
available.
– Active communities
(SpringSource, Yahoo)
– Lazy instantiation of
components
– Good documentation and
samples
 Cons
– Commercial license ($289 per
developer, $1159 for 5
developers)
– 2.2.x lacks accessibility
standards. 3.0 to change that.
– YUI has good documentation
and samples
 Cons
– Not as many features, eye
candy and customizable options
as Ext JS
– Grails UI documentation beyond
getting started documents
– YUI is a powerful library, but
needs to be extended with
custom code for more flashy
components
A Note on Performance
 Load time. Loading an application with lots of
JavaScript and CSS.
– Optimize with the help of Yslow Profiler
 Memory Footprint and execution speed on the
Browser
– JavaScript not known to be a fast language
– DOM elements take up a lot of memory
– JavaScript libraries strong focus on performance. Use
them
– Research coding optimization techniques. Especially on IE
 Browsers – support for Ajax applications getting
better
A Note on Web Accessibility
 Accessibility Guidelines
– Section 508 of Rehabilitation Act
– W3C Web Content Accessibility Guidelines (WCAG)
 Accessible Alternatives
– Degrading gracefully (Grade A browsers to lower grades)
– Providing an alternate site if Javascript is disabled (Gmail)
 Keyboard Navigation
 Screen Reader friendly generated HTML
 Notify user when Javascript changes appearance
 Both YUI and Ext JS are embracing 508 support.
Development Experience
 Groovy/Grails on Eclipse
– Need custom setup for a tolerable IDE experience. Blog coming soon
 Aptana
– JavaScript Editor
– IDE for AJAX Development
 Firebug
– JS debugging
– DOM inspection
– CSS control
– More...
 YSlow (Performance Recommendations)
– Performance Report Card based on 13 rules from Yahoo!'s Exception
Performance team
 Testing Tools
– Selenium
– HtmlUnit
– env.js
– Screw.Unit
References
 Demo code available at
 Recommended Books
– Ajax in Action. Dave Crane, Eric Pascarello, Darren James
– JavaScript Ninja. John Resig
– Ajax Security. Billy Hoffman, Bryan Sullivan
– Learning Ext JS. Shea Frederick, Colin Ramsay, Steve 'Cutter' Blades
– Learning Yahoo! User Interface. Dan Wellman
– Definitive Guide To Grails. Graeme Roche
 Reference Sites
– Ext JS (www.extjs.com)
– YUI (http://developer.yahoo.com/yui/)
– Grails UI (http://www.grails.org/GrailsUI+Plugin)
– Grails (www.grails.org)
Final Word?
 Embrace JavaScript and Ajax technologies
– They are elegant and are “fun” to work with (once you get
the hang of it.
 Grails is Grrreat!!
–
–
–
–
Straight forward for Java developers to pick up
Allows for rapid development
Features via plugins will only continue to grow
SpringSource support means the product will only get better
 Ext JS is a quality product. Is it worth $289?
 Grails UI is promising. Is generating in-line
JavaScript a problem?