SlideShare a Scribd company logo
1 of 28
Download to read offline
Building Progressive UIs with
            Grails
         Rob Fletcher
        Energized Work
Who am I?
Examples



  gr8-examples.cloudfoundry.com

github.com/robfletcher/gr8-examples
What is Progressive Enhancement?

Approach to building web UIs that emphasizes:
• Semantic markup
• Separation of markup, appearance, behaviour
• Rich appearance and
  behaviour applied selectively
• Adaptive design for cross-browser & cross-
  device support
• Distinct from 'graceful degradation’
Designing with Progressive
      Enhancement




 http://filamentgroup.com/dwpe/
Is this worth the effort?
• Cross-browser compatibility
• SEO compliance
• Mobile device support
• Support for assistive devices e.g.
  screenreaders
• Low bandwidth environments
• Maintainable structure
• Testability
Fundamentals



• JavaScript and CSS separated from markup
• Script reads and enhances markup
• Presentational markup injected by script
dowebsitesneedtolookexactlythesameineverybrowser.com
Don’t Break The Web!
Separation of markup & behaviour


Markup:
<a href="/foo” class="profile">Click me</a>
 <a href="/foo"
 onclick="return doSomething()">
     Click me
External script file:
</a>
   $('a.profile').click(doSomething);
Read and enhance markup


<a href="/foo" class="popup">Click me</a>

$('a.popup').click(function() {
    displayInPopup('/foo');
    displayInPopup($(this).attr('href'));
    return false;
});
Form enhancements and dialogs

EXAMPLE
The X-Ray Perspective


1. Map design components to basic HTML
2. Build markup with simple styles & no JS
3. Layer visual & interaction enhancements
   using JS & CSS
Data visualisation

EXAMPLE
How can Grails help?

request.xhr
•  different response for AJAX requests
•  render template / view
•  disable SiteMesh
•  forward rather than redirect
withFormat
•  respond with different data types
WebUtils.isIncludeRequest
•  tailor response for full page or content section
Varying output for AJAX

def show = {
    def model = // … whatever
    if (request.xhr) {
        render template: "basket", model: model
    } else {
        return model
    }
}
Disabling SiteMesh for AJAX


<!doctype html>
<html>
    <head>
        <g:if test="${!request.xhr}">
            <meta name="layout" content="main">
        </g:if>
Pagination -> infinite scroll

EXAMPLE
Test-driven progressive
           enhancement
Use browser capability detection to…
• activate script-driven behaviour
• activate 'polyfills' on less capable
   browsers
• selectively load JavaScript and CSS files
• apply advanced CSS rules to capable
   browsers
Modernizr
<html class="js flexbox canvas canvastext
    webgl no-touch geolocation postmessage
    no-websqldatabase indexeddb hashchange
.dialog {
if (Modernizr.geolocation) { rgba
    history draganddrop no-websockets
    background-color: #ccc;
    hsla multiplebgs backgroundsize
    // use native geolocation
    borderimage borderradius boxshadow
}
} else {
    textshadow opacity no-cssanimations
.rgba .dialog cssgradients no-cssreflections
    csscolumns {
    // activate JavaScript polyfill
    csstransforms no-csstransforms3d0, 0.3);
    background-color: rgba(0, 0,
} csstransitions fontface video audio
}   localstorage sessionstorage webworkers
    applicationcache svg inlinesvg smil
    svgclippaths">
FOUC prevention

EXAMPLE
Yepnope.js


yepnope({
    test : Modernizr.geolocation,
    yep : 'normal.js',
    nope : ['polyfill.js', 'wrapper.js’]
});
AJAX-enhanced pagination

EXAMPLE
Mobile-first progressive
           enhancement
body {
    background: url(low-res-image.png);
}
• Build for mobile devices first
@media screen and (min-width: 480px) {
•   Layer up to desktop using media queries
    body {
        background: url(hi-res-image.png);
•   }Prevent large images & supplementary
 
        max-width: 1140px;

     content sections loading
    #main, #sidebar { float: left; }
    #main { width: 65%; }
    #sidebar { width: 35%; }
}
What to avoid in Grails


AJAX tags:
•   g:formRemote
•   g:remoteField
•   g:remoteFunction
•   g:remoteLink
Resources plugin & templates

<r:use module="div-enhance-script"/>


•    Useful for highly modular apps
•    Script included at end of page
•    Can be used multiple times & script is
     only included once
Resources plugin & yepnope.js

<r:script disposition="head">
    yepnope({
        test : Modernizr.geolocation,
        yep  : "${r.resource(uri: 'normal.js')}",
        nope : [
            "${r.resource(uri: 'polyfill.js')}",
            "${r.resource(uri: 'wrapper.js')}"
        ]
    });
</r:script>
Thank you!


@rfletcherEW

adhockery.blogspot.com

www.energizedwork.com

More Related Content

What's hot

Relevance trilogy may dream be with you! (dec17)
Relevance trilogy  may dream be with you! (dec17)Relevance trilogy  may dream be with you! (dec17)
Relevance trilogy may dream be with you! (dec17)Woonsan Ko
 
Mongodb
MongodbMongodb
Mongodbfoliba
 
Pre rendering media sites with nuxt.js & netlify
Pre rendering media sites with nuxt.js & netlifyPre rendering media sites with nuxt.js & netlify
Pre rendering media sites with nuxt.js & netlifynuppla
 
Mongo db transcript
Mongo db transcriptMongo db transcript
Mongo db transcriptfoliba
 
The Basics of MongoDB
The Basics of MongoDBThe Basics of MongoDB
The Basics of MongoDBvaluebound
 
Drupal performance and scalability
Drupal performance and scalabilityDrupal performance and scalability
Drupal performance and scalabilityTwinbit
 
N hidden gems in forge (as of may '17)
N hidden gems in forge (as of may '17)N hidden gems in forge (as of may '17)
N hidden gems in forge (as of may '17)Woonsan Ko
 
Hidden gems in Apache Jackrabbit and BloomReach Forge
Hidden gems in Apache Jackrabbit and BloomReach ForgeHidden gems in Apache Jackrabbit and BloomReach Forge
Hidden gems in Apache Jackrabbit and BloomReach ForgeWoonsan Ko
 
Getting started with the Lupus Nuxt.js Drupal Stack
Getting started with the Lupus Nuxt.js Drupal StackGetting started with the Lupus Nuxt.js Drupal Stack
Getting started with the Lupus Nuxt.js Drupal Stacknuppla
 
Top 10 frameworks of node js
Top 10 frameworks of node jsTop 10 frameworks of node js
Top 10 frameworks of node jsHabilelabs
 
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal StackDecoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stacknuppla
 
Mojo Facets – so, you have data and browser?
Mojo Facets – so, you have data and browser?Mojo Facets – so, you have data and browser?
Mojo Facets – so, you have data and browser?Dobrica Pavlinušić
 
MongoDB basics & Introduction
MongoDB basics & IntroductionMongoDB basics & Introduction
MongoDB basics & IntroductionJerwin Roy
 

What's hot (20)

Relevance trilogy may dream be with you! (dec17)
Relevance trilogy  may dream be with you! (dec17)Relevance trilogy  may dream be with you! (dec17)
Relevance trilogy may dream be with you! (dec17)
 
Mongodb
MongodbMongodb
Mongodb
 
Pre rendering media sites with nuxt.js & netlify
Pre rendering media sites with nuxt.js & netlifyPre rendering media sites with nuxt.js & netlify
Pre rendering media sites with nuxt.js & netlify
 
Mongo db transcript
Mongo db transcriptMongo db transcript
Mongo db transcript
 
The Basics of MongoDB
The Basics of MongoDBThe Basics of MongoDB
The Basics of MongoDB
 
Introduction to mongo db
Introduction to mongo dbIntroduction to mongo db
Introduction to mongo db
 
Drupal performance and scalability
Drupal performance and scalabilityDrupal performance and scalability
Drupal performance and scalability
 
N hidden gems in forge (as of may '17)
N hidden gems in forge (as of may '17)N hidden gems in forge (as of may '17)
N hidden gems in forge (as of may '17)
 
Hidden gems in Apache Jackrabbit and BloomReach Forge
Hidden gems in Apache Jackrabbit and BloomReach ForgeHidden gems in Apache Jackrabbit and BloomReach Forge
Hidden gems in Apache Jackrabbit and BloomReach Forge
 
Getting started with the Lupus Nuxt.js Drupal Stack
Getting started with the Lupus Nuxt.js Drupal StackGetting started with the Lupus Nuxt.js Drupal Stack
Getting started with the Lupus Nuxt.js Drupal Stack
 
Top 10 frameworks of node js
Top 10 frameworks of node jsTop 10 frameworks of node js
Top 10 frameworks of node js
 
Node js crash course session 5
Node js crash course   session 5Node js crash course   session 5
Node js crash course session 5
 
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal StackDecoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
Decoupling Drupal mit dem Lupus Nuxt.js Drupal Stack
 
Mojo Facets – so, you have data and browser?
Mojo Facets – so, you have data and browser?Mojo Facets – so, you have data and browser?
Mojo Facets – so, you have data and browser?
 
A faster web
A faster webA faster web
A faster web
 
MongoDB
MongoDBMongoDB
MongoDB
 
Webpack
WebpackWebpack
Webpack
 
Lean and mean MongoDB
Lean and mean MongoDBLean and mean MongoDB
Lean and mean MongoDB
 
Intro Couchdb
Intro CouchdbIntro Couchdb
Intro Couchdb
 
MongoDB basics & Introduction
MongoDB basics & IntroductionMongoDB basics & Introduction
MongoDB basics & Introduction
 

Viewers also liked

GR8Conf 2009: Griffon by Jim Shingler
GR8Conf 2009: Griffon by Jim ShinglerGR8Conf 2009: Griffon by Jim Shingler
GR8Conf 2009: Griffon by Jim ShinglerGR8Conf
 
GR8Conf 2011: Grails Infinispanplugin, Tom Fuller
GR8Conf 2011: Grails Infinispanplugin, Tom FullerGR8Conf 2011: Grails Infinispanplugin, Tom Fuller
GR8Conf 2011: Grails Infinispanplugin, Tom FullerGR8Conf
 
GR8Conf 2011: Canoo RIA Suite
GR8Conf 2011: Canoo RIA SuiteGR8Conf 2011: Canoo RIA Suite
GR8Conf 2011: Canoo RIA SuiteGR8Conf
 
GR8Conf 2011: Groovy 1.8 update
GR8Conf 2011: Groovy 1.8 updateGR8Conf 2011: Groovy 1.8 update
GR8Conf 2011: Groovy 1.8 updateGR8Conf
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf
 
Grails EE
Grails EEGrails EE
Grails EEGR8Conf
 

Viewers also liked (6)

GR8Conf 2009: Griffon by Jim Shingler
GR8Conf 2009: Griffon by Jim ShinglerGR8Conf 2009: Griffon by Jim Shingler
GR8Conf 2009: Griffon by Jim Shingler
 
GR8Conf 2011: Grails Infinispanplugin, Tom Fuller
GR8Conf 2011: Grails Infinispanplugin, Tom FullerGR8Conf 2011: Grails Infinispanplugin, Tom Fuller
GR8Conf 2011: Grails Infinispanplugin, Tom Fuller
 
GR8Conf 2011: Canoo RIA Suite
GR8Conf 2011: Canoo RIA SuiteGR8Conf 2011: Canoo RIA Suite
GR8Conf 2011: Canoo RIA Suite
 
GR8Conf 2011: Groovy 1.8 update
GR8Conf 2011: Groovy 1.8 updateGR8Conf 2011: Groovy 1.8 update
GR8Conf 2011: Groovy 1.8 update
 
GR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul KingGR8Conf 2009: Industrial Strength Groovy by Paul King
GR8Conf 2009: Industrial Strength Groovy by Paul King
 
Grails EE
Grails EEGrails EE
Grails EE
 

Similar to Building Progressive UIs with Grails

It's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking ModernizrIt's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking ModernizrMichael Enslow
 
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5Sadaaki HIRAI
 
Web Development for UX Designers
Web Development for UX DesignersWeb Development for UX Designers
Web Development for UX DesignersAshlimarie
 
Front-End Frameworks: a quick overview
Front-End Frameworks: a quick overviewFront-End Frameworks: a quick overview
Front-End Frameworks: a quick overviewDiacode
 
Client Side Optimization
Client Side OptimizationClient Side Optimization
Client Side OptimizationPatrick Huesler
 
The Heron Mapping Client - Overview, Functions, Concepts
The Heron Mapping Client - Overview, Functions, Concepts The Heron Mapping Client - Overview, Functions, Concepts
The Heron Mapping Client - Overview, Functions, Concepts Just van den Broecke
 
Introduction to Jquery
Introduction to JqueryIntroduction to Jquery
Introduction to JqueryGurpreet singh
 
HTML5 & CSS3 refresher for mobile apps
HTML5 & CSS3 refresher for mobile appsHTML5 & CSS3 refresher for mobile apps
HTML5 & CSS3 refresher for mobile appsIvano Malavolta
 
[2015/2016] HTML5 and CSS3 Refresher
[2015/2016] HTML5 and CSS3 Refresher[2015/2016] HTML5 and CSS3 Refresher
[2015/2016] HTML5 and CSS3 RefresherIvano Malavolta
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationAndrew Rota
 
Responsive content
Responsive contentResponsive content
Responsive contenthonzie
 
HTML5: An Overview
HTML5: An OverviewHTML5: An Overview
HTML5: An OverviewNagendra Um
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Webmikeleeme
 
Html 5 mobile - nitty gritty
Html 5 mobile - nitty grittyHtml 5 mobile - nitty gritty
Html 5 mobile - nitty grittyMario Noble
 
Developing High Performance Web Apps
Developing High Performance Web AppsDeveloping High Performance Web Apps
Developing High Performance Web AppsTimothy Fisher
 
Web Apps and more
Web Apps and moreWeb Apps and more
Web Apps and moreYan Shi
 
Web app and more
Web app and moreWeb app and more
Web app and morefaming su
 
Developing JavaScript Widgets
Developing JavaScript WidgetsDeveloping JavaScript Widgets
Developing JavaScript WidgetsBob German
 

Similar to Building Progressive UIs with Grails (20)

It's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking ModernizrIt's a Mod World - A Practical Guide to Rocking Modernizr
It's a Mod World - A Practical Guide to Rocking Modernizr
 
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
Familiar HTML5 - 事例とサンプルコードから学ぶ 身近で普通に使わているHTML5
 
Web Development for UX Designers
Web Development for UX DesignersWeb Development for UX Designers
Web Development for UX Designers
 
Front-End Frameworks: a quick overview
Front-End Frameworks: a quick overviewFront-End Frameworks: a quick overview
Front-End Frameworks: a quick overview
 
Client Side Optimization
Client Side OptimizationClient Side Optimization
Client Side Optimization
 
The Heron Mapping Client - Overview, Functions, Concepts
The Heron Mapping Client - Overview, Functions, Concepts The Heron Mapping Client - Overview, Functions, Concepts
The Heron Mapping Client - Overview, Functions, Concepts
 
Html5 more than just html5 v final
Html5  more than just html5 v finalHtml5  more than just html5 v final
Html5 more than just html5 v final
 
Introduction to Jquery
Introduction to JqueryIntroduction to Jquery
Introduction to Jquery
 
HTML5 & CSS3 refresher for mobile apps
HTML5 & CSS3 refresher for mobile appsHTML5 & CSS3 refresher for mobile apps
HTML5 & CSS3 refresher for mobile apps
 
[2015/2016] HTML5 and CSS3 Refresher
[2015/2016] HTML5 and CSS3 Refresher[2015/2016] HTML5 and CSS3 Refresher
[2015/2016] HTML5 and CSS3 Refresher
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Responsive content
Responsive contentResponsive content
Responsive content
 
HTML5: An Overview
HTML5: An OverviewHTML5: An Overview
HTML5: An Overview
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Web
 
Html 5 mobile - nitty gritty
Html 5 mobile - nitty grittyHtml 5 mobile - nitty gritty
Html 5 mobile - nitty gritty
 
Developing High Performance Web Apps
Developing High Performance Web AppsDeveloping High Performance Web Apps
Developing High Performance Web Apps
 
Web Apps and more
Web Apps and moreWeb Apps and more
Web Apps and more
 
Web app and more
Web app and moreWeb app and more
Web app and more
 
Developing JavaScript Widgets
Developing JavaScript WidgetsDeveloping JavaScript Widgets
Developing JavaScript Widgets
 
HTML5 - A Whirlwind tour
HTML5 - A Whirlwind tourHTML5 - A Whirlwind tour
HTML5 - A Whirlwind tour
 

More from GR8Conf

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your TeamGR8Conf
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle GR8Conf
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with GebGR8Conf
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidGR8Conf
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the DocksGR8Conf
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsGR8Conf
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applicationsGR8Conf
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3GR8Conf
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGR8Conf
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEBGR8Conf
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCGR8Conf
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshopGR8Conf
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spockGR8Conf
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedGR8Conf
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGR8Conf
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and GroovyGR8Conf
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineGR8Conf
 

More from GR8Conf (20)

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your Team
 
Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle Creating and testing REST contracts with Accurest Gradle
Creating and testing REST contracts with Accurest Gradle
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developer
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with Geb
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and Android
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the Docks
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature plugins
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applications
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloud
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEB
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPC
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshop
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem Revisited
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and Groovy
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual Machine
 

Recently uploaded

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

Building Progressive UIs with Grails

  • 1. Building Progressive UIs with Grails Rob Fletcher Energized Work
  • 4. What is Progressive Enhancement? Approach to building web UIs that emphasizes: • Semantic markup • Separation of markup, appearance, behaviour • Rich appearance and behaviour applied selectively • Adaptive design for cross-browser & cross- device support • Distinct from 'graceful degradation’
  • 5. Designing with Progressive Enhancement http://filamentgroup.com/dwpe/
  • 6. Is this worth the effort? • Cross-browser compatibility • SEO compliance • Mobile device support • Support for assistive devices e.g. screenreaders • Low bandwidth environments • Maintainable structure • Testability
  • 7. Fundamentals • JavaScript and CSS separated from markup • Script reads and enhances markup • Presentational markup injected by script
  • 10. Separation of markup & behaviour Markup: <a href="/foo” class="profile">Click me</a> <a href="/foo" onclick="return doSomething()"> Click me External script file: </a> $('a.profile').click(doSomething);
  • 11. Read and enhance markup <a href="/foo" class="popup">Click me</a> $('a.popup').click(function() {     displayInPopup('/foo'); displayInPopup($(this).attr('href'));     return false; });
  • 12. Form enhancements and dialogs EXAMPLE
  • 13. The X-Ray Perspective 1. Map design components to basic HTML 2. Build markup with simple styles & no JS 3. Layer visual & interaction enhancements using JS & CSS
  • 15. How can Grails help? request.xhr • different response for AJAX requests • render template / view • disable SiteMesh • forward rather than redirect withFormat • respond with different data types WebUtils.isIncludeRequest • tailor response for full page or content section
  • 16. Varying output for AJAX def show = { def model = // … whatever if (request.xhr) { render template: "basket", model: model } else { return model } }
  • 17. Disabling SiteMesh for AJAX <!doctype html> <html> <head> <g:if test="${!request.xhr}"> <meta name="layout" content="main"> </g:if>
  • 18. Pagination -> infinite scroll EXAMPLE
  • 19. Test-driven progressive enhancement Use browser capability detection to… • activate script-driven behaviour • activate 'polyfills' on less capable browsers • selectively load JavaScript and CSS files • apply advanced CSS rules to capable browsers
  • 20. Modernizr <html class="js flexbox canvas canvastext webgl no-touch geolocation postmessage no-websqldatabase indexeddb hashchange .dialog { if (Modernizr.geolocation) { rgba history draganddrop no-websockets background-color: #ccc; hsla multiplebgs backgroundsize // use native geolocation borderimage borderradius boxshadow } } else { textshadow opacity no-cssanimations .rgba .dialog cssgradients no-cssreflections csscolumns { // activate JavaScript polyfill csstransforms no-csstransforms3d0, 0.3); background-color: rgba(0, 0, } csstransitions fontface video audio } localstorage sessionstorage webworkers applicationcache svg inlinesvg smil svgclippaths">
  • 22. Yepnope.js yepnope({ test : Modernizr.geolocation, yep : 'normal.js', nope : ['polyfill.js', 'wrapper.js’] });
  • 24. Mobile-first progressive enhancement body {     background: url(low-res-image.png); } • Build for mobile devices first @media screen and (min-width: 480px) { •   Layer up to desktop using media queries     body {      background: url(hi-res-image.png); •   }Prevent large images & supplementary   max-width: 1140px; content sections loading #main, #sidebar { float: left; } #main { width: 65%; } #sidebar { width: 35%; } }
  • 25. What to avoid in Grails AJAX tags: • g:formRemote • g:remoteField • g:remoteFunction • g:remoteLink
  • 26. Resources plugin & templates <r:use module="div-enhance-script"/> • Useful for highly modular apps • Script included at end of page • Can be used multiple times & script is only included once
  • 27. Resources plugin & yepnope.js <r:script disposition="head">     yepnope({         test : Modernizr.geolocation,         yep  : "${r.resource(uri: 'normal.js')}",         nope : [             "${r.resource(uri: 'polyfill.js')}",             "${r.resource(uri: 'wrapper.js')}"         ]     }); </r:script>