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/weblo
Mar 26, 2015
Intro to Building Desktop-Style Web UIs
JavaScript on Grails
Torey LomendaSenior ConsultantObject Partners Inc.
[email protected]://twitter.com/tlomendahttp://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 Grails UI
JavaScript Namespace: ExtProvides high performance, customizable “real-world” UI widgets
Well designed, documented and extensible component model
Uses adapters to work seamlesslywith other libraries (YUI, JQuery,Prototype)
Open sourced under GPLv3
Commercial License$289 per developer$1159 for 5 developers
JavaScript Namespace: GRAILSUIA 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
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 elementbefore render completed.
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.
Procedural Programming
Event Programming
DOM Manipulation
Ext JS YUI
Finding Nodesvar elById = Ext.get(elId)var elBySelector = Ext.DomQuery.selectNode( 'a.mycls[@href*=”myref”]:first');
Manipulating DOMExt.DomHelper
Finding Nodesvar elById = YAHOO.util.Dom.get(elId);var elBySelector = YAHOO.util.Selector.query('li a');
Manipulating DOMYAHOO.util.Dom
Ajax Support
Ext JS YUI
var successFn = function(res) {};var failureFn = function(res) {};
Ext.Ajax.request({ url: 'someUrl', method: 'GET|POST', success: successFn, failure: failureFn});
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
Administer Leagues
Manage Players
Manage Scouting Reports
League Admin
Player Admin
Scout
Use Case Model
User
Role
RequestMapping
Player
PlayerStats PlayerNews
ScoutingReport
ScoutingNotes
League Season
Team
Game
Domain Model
home visitor
Hockey Stats App Using Grails UI
Hockey Stats App Using Ext JS
<Grails Plugin>hockeystats-domain
hockeystats-extjs
hockeystats-yui
<Grails Plugin>acegi
(Spring Security
<Grails Plugin>yui
<Grails Plugin>ext-js
Browser
<Grails Plugin>Grails UI
<Grails Plugin>Bubbling
RESTful Web Sevices(League, Team, Player,
Scouting Report)
<Grails Plugin>hockeystats-domain
<Grails Plugin>acegi
(Spring Security)
REST
HTML
REST
HTML
Component Model
(JSON)
(GSP)
(JSON)
(GSP)
Step 1 – Border LayoutExt JS YUI
*Leverage Grails SiteMesh Integration
var viewport = new Ext.ViewPort({ layout: 'border', renderTo: 'some-div',
items: [
{region: 'northnorth',xtype: 'panel'},
{region: 'westwest',xtype: 'panel'},
{region: 'southsouth',xtype: 'panel'},
]});
var layout = YAHOO.widget.Layout({ units: [
{position: 'top', body: 'header-div'},
{position: 'left', body: 'side-div'},
{position: 'bottom', body: 'footer-div'}, ]});
Step 2 – Menus
Ext JS YUI
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}
]}
]});
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 Grails UI / YUI
Nice Dynamic Forms
Highlighted Features:Rich ComboBox Support Collapsible Field SetsBuilt-in Field ValidationBinding buttons to forms
Can use applyTo() to decorate existing HTML form.
Preferred option is dynamic
Minimal GrailsUI support for Forms
Grails UI Widgets:Date PickerExpandable Panel
Why the SplitButton?Should have used Grails UI Autocomplete
YUI decorates existing HTML formmarkup
Custom validation can be added to a form
Step 4 - Trees
Ext JS YUIUse:
Ext.tree.TreePanelExt.Tree.TreeLoader
Use:YAHOO.widget.TreeViewYAHOO.util.Connect
new Ext.tree.TreePanel({useArrows: true,
root: {nodeType: “async”,text: “Some Tree”,draggable: false,id: “someRootNode”
},
loader: someTreeLoader});
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 Grails UI
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]
]
}
]
});
<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 Grails UIvar 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
}});
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 GrailsUI / YUI
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”
});
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 BehaviourGRAILSUI.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 YUIvar dragSource =
new Ext.dd.DragSource(‘someDivElementId’,{someConfig: “prop1”});
var dropTarget = new Ext.dd.DropTarget(
‘someDropTarget’,notifyDrop: someFn});
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 GrailsUI / YUI
Use 3rd Party Widgets such as TinyMCE (http://tinymce.moxiecode.com/)
<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 Firebugto Inspect DOM.
Ext JS (Style Accordion) Grails UI (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;
border-top: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;}
#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
Pros– Powerful, intuitive, easy to use.
(it actually works??)
– Readable, extensible JS component model
– feature rich components out-of-the-box. Many config options available.
– 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.
Pros– Powerful, intuitive, easy to use.
(it actually works??)
– Nice tag support to embed components through mark-up
– Active communities (SpringSource, Yahoo)
– 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
Ext JS GrailsUI / YUI
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?