SlideShare a Scribd company logo
Speed up your GWT coding with gQuery
Manuel Carrasco Moñino
GWT.create 2015
► Run these slides
1/35
About me...
Open Source advocate
Vaadin R&D
GWT Maintainer
Apache James PMC
Jenkins Committer
 
@dodotis
+ManuelCarrascoMoñino
2/35
What is gQuery?
Write less. Do more!
An entire GWT rewrite of the famous jQuery javascript library.
Use the jQuery API in GWT applications without including the jQuery,
while leveraging the optimizations and type safety provided by GWT.
3/35
It looks like jQuery
The API and syntax of GQuery is almost identical to jQuery.
Existing jQuery code can be easily adapted into GQuery and used in
your GWT applications.
jQuery gQuery
$(".article:not(.hidden)>.header")
.width($("#mainHeader").innerWidth())
.click(function(){
$(this)
.siblings(".content")
.load("/article/"+$(this).parent().id(),
null,
function(){
$(this).fadeIn(250);
});
});
importstaticcom.google.gwt.query.client.GQuery.*;
$(".article:not(.hidden)>.header")
.width($("#mainHeader").innerWidth())
.click(newFunction(){
publicvoidf(){
$(this)
.siblings(".content")
.load("/article/"+$(this).parent().id(),
null,
newFunction(){
publicvoidf(){
$(this).fadeIn(250);
}
});
}
});
4/35
But it's much more
It integrates gently with GWT
shares and enhances its event mechanism
knows about widgets hierarchy
GWT Optimizers
Provides a simpler deferred binding mechanism
Provide many utilities for GWT.
Plenty of useful methods
5/35
Current gQuery status
Very active development
3000 downloads per month
In the top 5 of the most popular GWT libraries
Stable versions since 2010
Official sponsored & supported by ArcBees
6/35
gQuery Fundamentals
7/35
Easy DOM manipulation
GQuery eases traversal and manipulation of the DOM.
Use $() to wrap, find and create elements or widgets
Chaining methods: select & modify several elements in just one line
of code.
friendly css style properties syntax.
Use $$() to set style properties or for animations
It also supports type safe CSS
$(".slides>section").css("background-color","green")
.animate($$("top:+80%"))
.animate($$("top:0,background-color:transparent")).size();
$("<p>Hello</p>").appendTo(".current");
8/35
Full GWT Widget integration
Whatever you do with elements, you can do with widgets
Query, Enhance, Manipulate, Modify
Promote elements to widgets inserting them in gwt hierarchy
Improve widgets events
Adding events not implemented by the widget
Buttonb=new Button("Clickme");
b.addClickHandler(new ClickHandler(){
publicvoidonClick(ClickEventevent){
console.log("ClickedonButton");
}
});
//PromoteanyDOMelementtoaGWTpanel
Panelp=$("section.current.jCode-div").as(Widgets).panel().widget();
//UseitasanyotherwidgetinGWThierarchy
p.add(b);
//EnhanceWidgetDOM
$("<ahref='javascript:'>Clickme</a>").prependTo($(b)).on("click",new Function(){
publicbooleanf(Evente){
console.log("ClickedonLink");
returnfalse;
}
});
9/35
Event Handling
Handle and fire any native event.
Create your own events.
Support for event name spaces.
Delegate events.
Pass data to listeners using events
Tip: Replacement to EventBus
console.log("Clickoncodetexttoseethefontcolor.");
$("#console").on("foo",new Function(){
publicbooleanf(Evente,Object...args){
console.log(args[0]);
returntrue;
}
});
$(".current.jCode").on("tap","span",new Function(){
publicbooleanf(Evente){
$("#console").trigger("foo",$(e).css("color"));
returnfalse;
}
});
10/35
Promises
GQuery implements the promises API existing in jQuery.
when, then, and, or, progress, done, fail, always
Use it as an alternative to nested callback based code.
Declarative syntax.
Can be used in the JVM
//Launchthingsatthesametimewithwhen
GQuery.when(
$(".ball.yellow").animate($$("bottom:0"),1000),
$(".ball.red").animate($$("bottom:0"),2000)
).done(new Function(){
publicvoidf(){
$(".ball").fadeOut();
}
});
11/35
Ajax
GQuery provides an easy API for Ajax.
Syntax sugar
Promises
Progress
Works in JVM
$("#response").load("gwtcreate2015.html#hello>div");
12/35
Data Binding
GQuery ships an easy data binding system to and from JSON or XML
Light weight implementation: each object wraps a JS object
JVM compatible.
publicinterfacePersonextendsJsonBuilder{
PersonsetName(Strings);
StringgetName();
PersonsetAge(inti);
intgetAge();
List<Person>getChildren();
PersongetPartner();
PersonsetPartner(Personp);
}
Personme=GQ.create(Person.class).setAge(10).setName("Manolo");
console.log(me);
13/35
Utilities
GQuery ships a set of GWT utilities which makes your live easier
Avoiding writing GWT JSNI
export, import
Simplifying GWT Deferred binding
browser.isIe, browser.isWebkit ... flags
Browser syntax logging
console.log, console.err ...
Import external JS in JSNIBlocks
JsniBundle
14/35
All Right, but how can gQuery help in my GWT project ?
Writing less code !
For certain actions you can save 60-90% of code
Making your code more expressive
Chaining is more declarative.
Promises try to solve nested and complex asynchronous blocks.
Using pure DOM elements instead of creating widgets for everything.
The tendency is to avoid Widgets
Web-components are here
Reusing existing code (js, html)
15/35
When can I use gQuery in my GWT project?
1.- Doesn't matter the final GWT architecture of your project
Plain GWT, MVP, GWTP
GXT, MGWT, Vaadin
2.- As usual separate Views from your Business logic.
In your Views: gQuery will help you to enhance & manipulate the DOM
In your Logic: you can use Ajax, Promises, and Json binding and test in the
JVM
16/35
I want to write less and do more...
Show me the code
17/35
Don't extend GWT widgets to change it's behavior.
Modify the widget when it attaches or detaches.
Modify its DOM
Add effects
Add events
Tip: when GWT attaches/detaches you must set events again
Easy to use in UiBinder classes
Widgetwidget=new Label("Hello");
widget.addAttachHandler(new Handler(){
publicvoidonAttachOrDetach(AttachEventevent){
$(event.getSource())
.append("<span>GWT</span><span>Create</span>")
.animate($$("y:+200px,x:+50px,color:yellow"),3000)
.on("click","span",new Function(){
publicvoidf(){
console.log($(this).text());
}
});
}
});
RootPanel.get().add(widget);
18/35
Decouple your widgets
Find any widget of a specific java class.
By default it looks for widgets attached to the RootPanel
Enclose your search using especific selectors like '.gwt-Label' or specific
contexts.
Then you can use those widgets as usual in your GWT application
//YougetalistwithallMyBreadCrumbmatchingtheselector
List<MyBreadCrumb>list=$(".gwt-Label").widgets(MyBreadCrumb.class);
MyBreadCrumbcrumbs=list.get(0);
crumbs.addCrumb("Rocks");
19/35
GWT Ajax never was simpler.
Just one line of code vs dozen of lines using RequestBuilder
Reusable responses via Promises
Advanced features
Upload/Download progress, FormData, CORS
Usable in the JVM
//ConfigurableviaPropertiessyntax
Ajax.get("/my-rest-service/items",$$("customer:whatever"));
Ajax.post("/my-rest-service/save",$$("id:foo,description:bar"));
Ajax.loadScript("/my-cdn-host/3party.js");
Ajax.importHtml("/bower_components/3party-web-component.html");
//OrviatheSettingsinterface
Ajax.ajax(Ajax.createSettings()
.setUrl("/my-3party-site/service")
.setWithCredentials(true)
.setData(GQ.create().set("parameter1","value")))
.fail(new Function(){
publicvoidf(){
console.log("Thecallshouldfailbecauseurl'sareinvalid");
}
});
20/35
Make your async code more declarative and simpler
Avoid nesting callbacks
Chain promises methods to add callbacks
Reuse resolved promises to avoid requesting twice the same service
resolved status is maintained for ever
Pipe your callbacks
//Wecanreusetheloginpromiseanytime
PromiseloginDone=Ajax.post("/my-login-service",$$("credentials:whatever"));
GQuery.when(loginDone)
.then(Ajax.post("/my-rest-service",$$().set("param","value")))
.done(new Function(){
publicObjectf(Object...args){
returnsuper.f(args);
}
}).fail(new Function(){
publicvoidf(){
console.log("LoginError");
}
});
21/35
JSNI sucks, how does gQuery help?
Export java functions to JS objects
This will be covered by JsInterop
But sometimes you will be interested on simply export one method
Execute external functions
Automatically boxes and un-boxes parameters and return values
Wrap any JS object with JsonBuilders
It supports functions
Load external libraries via JsniBundle
JsUtils.export(window,"foo",new Function(){
publicObjectf(Object...args){
returnargs[0];
}
});
Stringresponse=JsUtils.jsni(window,"foo","ByeByeJSNI");
console.log(response);
22/35
Simplifying deferred binding
gQuery Browser flags are set in compilation time.
They return true or false, making the compiler get rid of other borwsers
code
Not necessity of create classes nor deal with module files
if(browser.webkit){
console.log("WebKit");
}elseif(browser.ie6){
//Thiscodewillneverbeinchromepermutation
Window.alert("IE6doesnothaveconsole");
}else{
//Thiscodewillneverbeinchromepermutation
console.log("NotwebkitnorIE.Maybemozilla?"+browser.mozilla);
}
23/35
Extending gQuery
24/35
How to extend gQuery?
Plugins add new methods to GQuery objects
It's easy to call new methods via the as(Plugin) method
Plugins also could modify certain behaviors of gQuery:
support for new selectors
synthetic events
new css properties ...
publicstaticclassCss3AnimationsextendsGQuery{
//Wejustneedaconstructor,andareferencetothenewregisteredplugin
protectedCss3Animations(GQuerygq){
super(gq);
}
publicstaticfinalClass<Css3Animations>Css3Animations=GQuery
.registerPlugin(Css3Animations.class,new Plugin<Css3Animations>(){
publicCss3Animationsinit(GQuerygq){
returnnew Css3Animations(gq);
}
});
//Wecanaddnewmethodsoroverrideexistingones
publicCss3Animationscss3Animate(Propertiesproperties){
super.animate(properties);
returnthis;
}
}
$(".ball").as(Css3Animations.Css3Animations).animate($$("rotateX:180deg,rotateY:180deg"
25/35
How to port a jQuery plugin to gQuery
Gesture Plugin Differences
Take original JS code
Create JsBuider interfaces so as syntax is similar to JS
Set appropriate java types to JS variables
Gesture Plugin Source Gighub
Gesture Plugin Demo
$(".current.jCode").as(Gesture.Gesture).on("taptwo",new Function(){
publicvoidf(){
console.log("DoubleTap");
}
});
26/35
What is the future of gQuery
Type safe functions and promises
Full support for java 8 lambdas
Mobile friendly
Integration with JsInterop
GQueryg=$(".ball");
g.each(new IsElementFunction(){
publicvoidrun(Elementelm){
$(elm).animate("scale:1.2");
}
});
g.on("tapone",new IsEventFunction(){
publicBooleancall(Eventevt){
return$(evt).animate($$("rotateX:90deg")).animate($$("rotateX:0deg")).FALSE;
}
});
//PredefinedreturntypesinthegQuerychain
g.on("taptwo",(e)->$(e).animate($$("x:+=50")).TRUE);
//Gettheresultofmultiplecallbacks
$.when(()->"aaa",()->"bbb",Ajax.get("/lambdas.html"))
.done((Object[]s)->console.log(s[0],s[1],s[3]))
.fail((s)->console.log("Fail"));
27/35
Show me more cool code ...
28/35
Example: Material Design Hierarchical Timing.
boxes.each(new Function(){
intscale=boxes.isVisible()?0:1;
publicvoidf(Elemente){
GQueryg=$(this);
intdelay=(int)(g.offset().left+g.offset().top);
g.animate("duration:200,delay:"+delay+",scale:"+scale);
}
});
29/35
Example: Material Design Ripple Effect.
//Createtherippleelementtobeanimated
finalGQueryripple=$("<div>").as(Transitions.Transitions).css(
$$("position:absolute,width:40px,height:40px,background:white,border-radius:50%"
//Addrippleeffectstocertainelementswhentheyaretapped
$(".jCode,.button,h1").on("tap.ripple",new Function(){
publicbooleanf(Evente){
GQuerytarget=$(this).css($$("overflow:hidden")).append(ripple);
intx=e.getClientX()-20-target.offset().left;
inty=e.getClientY()-20-target.offset().top;
intf=Math.max(target.width(),target.height())/40*3;
ripple.css($$("opacity:0.8,scale:0.5")).css("left",x+"px").css("top",y+"px");
ripple.animate($$("opacity:0,scale:"+f),new Function(){
publicvoidf(){
ripple.detach();
}
});
returnfalse;
}
});
30/35
Example: Wrapping Web Components with gQuery
Use bower to install components in the public folder
bower install Polymer/paper-slider
Use Ajax utility methods to load polyfills and import templates
Web Components can be created and manipulated as any other
element.
We can change its properties or bind events.
Ajax.loadScript("bower_components/webcomponentsjs/webcomponents.js");
Ajax.importHtml("bower_components/paper-slider/paper-slider.html");
GQueryslider=$("<paper-slider/>").appendTo($("#sliders-container"));
slider.prop("value",67);
slider.on("change",(e)->{
console.log($(e).prop("value"));
returntrue;
});
$("#sliders-container").append("<paper-slidervalue=183max=255editable>");
31/35
Example: Binding Attributes of Web Components.
JsonBuilder can wrap any JavaScript element
Light Weight wrapper
Type safe
Chain setters
publicinterfacePaperSliderextendsJsonBuilder{
//get/setprefixesareoptional
intgetValue();
//Chainingsettersisoptional
PaperSlidersetValue(intvalue);
PaperSlidermin(intvalue);
PaperSlidermax(intvalue);
PaperSliderstep(intvalue);
PaperSlidersnaps(booleanvalue);
PaperSliderpin(booleanvalue);
}
//Waituntilthepolyfillandthewebcomponenthasbeenloaded
GQuery.when(
Ajax.loadScript("bower_components/webcomponentsjs/webcomponents.js"),
Ajax.importHtml("bower_components/paper-slider/paper-slider.html")
).done(new Function(){
publicvoidf(){
//CreateandappendtheelementasusualingQuery
GQueryg=$("<paper-slider>").appendTo($("#slider-container"));
//WrapthenativeelementinaPOJO
PaperSliderslider=GQ.create(PaperSlider.class).load(g);
//Useitasajavaobject
slider.setValue(300).max(400).step(50).snaps(true).pin(true);
}
});
32/35
Example: Uploading files with progress bar.
finalGQueryprogress=$("<div>").css($$("height:12px,width:0%,background:#75bff4,position:absolu
finalGQueryfileUpload=$("<inputtype='file'accept='image/*'>").appendTo(document).hide
fileUpload.on("change",new Function(){
publicbooleanf(Evente){
finalJsArray<JavaScriptObject>files=$(e).prop("files");
JavaScriptObjectformData=JsUtils.jsni("eval","newFormData()");
for(inti=0,l=files.length();i<l;i++){
JsUtils.jsni(formData,"append","file-"+i,files.get(i));
}
Ajax.ajax(Ajax.createSettings()
.setUrl(uploadUrl).setData(formData).setWithCredentials(true))
.progress(new Function(){
publicvoidf(){
progress.animate("width:"+arguments(2)+"%",1000);
}
}).always(new Function(){
publicvoidf(){
progress.remove();
}
}).done(new Function(){
publicvoidf(){
uploadImg.attr("src",uploadUrl+"&show=file-0-0");
}
});
returntrue;
}
}).trigger("click");
33/35
Real Examples
www.GwtProject.org
www.Arcbees.com
GwtQuery Slides
www.Talkwheel.com
34/35
Questions and Answers
Rate this talk: http://gwtcreate.com/agenda
when(()->"Talk")
.then((o)->"Questions")
.and((o)->"Answers")
.done((o)->console.log("Thanks"));
35/35

More Related Content

What's hot (20)

PDF
Vaadin Components @ Angular U
Joonas Lehtinen
 
PPTX
The Many Ways to Build Modular JavaScript
Tim Perry
 
PDF
React
중운 박
 
PDF
Javascript Module Patterns
Nicholas Jansma
 
PDF
GWTcon 2015 - Beyond GWT 3.0 Panic
Cristiano Costantini
 
PDF
A friend in need - A JS indeed
Yonatan Levin
 
PDF
Difference between java script and jquery
Umar Ali
 
PDF
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
GWTcon
 
PDF
Vaadin Components
Joonas Lehtinen
 
PDF
Building a Startup Stack with AngularJS
FITC
 
PDF
Introduction to VueJS & Vuex
Bernd Alter
 
PPTX
Sword fighting with Dagger GDG-NYC Jan 2016
Mike Nakhimovich
 
PDF
Gwt.Create Keynote San Francisco
Ray Cromwell
 
PPT
GWT Introduction and Overview - SV Code Camp 09
Fred Sauer
 
PDF
Using ReactJS in AngularJS
Boris Dinkevich
 
PPTX
Vue business first
Vitalii Ratyshnyi
 
PDF
The Complementarity of React and Web Components
Andrew Rota
 
PPT
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
Srijan Technologies
 
PPTX
AngularJS
LearningTech
 
PPT
GWT Training - Session 2/3
Faiz Bashir
 
Vaadin Components @ Angular U
Joonas Lehtinen
 
The Many Ways to Build Modular JavaScript
Tim Perry
 
React
중운 박
 
Javascript Module Patterns
Nicholas Jansma
 
GWTcon 2015 - Beyond GWT 3.0 Panic
Cristiano Costantini
 
A friend in need - A JS indeed
Yonatan Levin
 
Difference between java script and jquery
Umar Ali
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
GWTcon
 
Vaadin Components
Joonas Lehtinen
 
Building a Startup Stack with AngularJS
FITC
 
Introduction to VueJS & Vuex
Bernd Alter
 
Sword fighting with Dagger GDG-NYC Jan 2016
Mike Nakhimovich
 
Gwt.Create Keynote San Francisco
Ray Cromwell
 
GWT Introduction and Overview - SV Code Camp 09
Fred Sauer
 
Using ReactJS in AngularJS
Boris Dinkevich
 
Vue business first
Vitalii Ratyshnyi
 
The Complementarity of React and Web Components
Andrew Rota
 
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
Srijan Technologies
 
AngularJS
LearningTech
 
GWT Training - Session 2/3
Faiz Bashir
 

Similar to Speed up your GWT coding with gQuery (20)

PPT
GWT
Lorraine JUG
 
PPTX
Google web toolkit web conference presenation
Stephen Erdman
 
PPTX
GWT = easy AJAX
Olivier Gérardin
 
PPT
Google Web Toolkits
Yiguang Hu
 
PPT
GWT Extreme!
cromwellian
 
PPT
GWT is Smarter Than You
Robert Cooper
 
PDF
Javascript as a target language - GWT KickOff - Part 2/2
JooinK
 
PDF
Google Web Toolkit
Software Park Thailand
 
PDF
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
IMC Institute
 
PPT
Introduction to Google Web Toolkit
Didier Girard
 
PPTX
Gwt session
Ahmed Akl
 
ODP
Google Web toolkit
Priyank Kapadia
 
ODP
Building Ajax apps with the Google Web Toolkit
vivek_prahlad
 
PPTX
Gwt session
Mans Jug
 
PPT
Google Web Toolkit Introduction - eXo Platform SEA
nerazz08
 
PPTX
Extending GWT
isurusndr
 
PPTX
Ext GWT - Overview and Implementation Case Study
Avi Perez
 
PDF
Javaland 2014 / GWT architectures and lessons learned
pgt technology scouting GmbH
 
PDF
GWT - AppDays - (25 aprile 2014, pordenone)
firenze-gtug
 
PPT
GWT
yuvalb
 
Google web toolkit web conference presenation
Stephen Erdman
 
GWT = easy AJAX
Olivier Gérardin
 
Google Web Toolkits
Yiguang Hu
 
GWT Extreme!
cromwellian
 
GWT is Smarter Than You
Robert Cooper
 
Javascript as a target language - GWT KickOff - Part 2/2
JooinK
 
Google Web Toolkit
Software Park Thailand
 
Java Web Programming on Google Cloud Platform [3/3] : Google Web Toolkit
IMC Institute
 
Introduction to Google Web Toolkit
Didier Girard
 
Gwt session
Ahmed Akl
 
Google Web toolkit
Priyank Kapadia
 
Building Ajax apps with the Google Web Toolkit
vivek_prahlad
 
Gwt session
Mans Jug
 
Google Web Toolkit Introduction - eXo Platform SEA
nerazz08
 
Extending GWT
isurusndr
 
Ext GWT - Overview and Implementation Case Study
Avi Perez
 
Javaland 2014 / GWT architectures and lessons learned
pgt technology scouting GmbH
 
GWT - AppDays - (25 aprile 2014, pordenone)
firenze-gtug
 
GWT
yuvalb
 
Ad

More from Manuel Carrasco Moñino (20)

PDF
The Java alternative to Javascript
Manuel Carrasco Moñino
 
PDF
GWT and PWA
Manuel Carrasco Moñino
 
PDF
Present and Future of GWT from a developer perspective
Manuel Carrasco Moñino
 
PDF
GWT Contributor Workshop
Manuel Carrasco Moñino
 
PDF
CRUD with Polymer 2.0
Manuel Carrasco Moñino
 
PDF
Web Components and PWA
Manuel Carrasco Moñino
 
PPTX
Building Components for Business Apps
Manuel Carrasco Moñino
 
PDF
Vaadin codemotion 2014
Manuel Carrasco Moñino
 
PDF
GwtQuery the perfect companion for GWT, GWT.create 2013
Manuel Carrasco Moñino
 
PDF
Rapid and Reliable Developing with HTML5 & GWT
Manuel Carrasco Moñino
 
PDF
Aprendiendo GWT
Manuel Carrasco Moñino
 
PDF
Apache James/Hupa & GWT
Manuel Carrasco Moñino
 
PDF
GWT: Why GWT, GQuery, and RequestFactory
Manuel Carrasco Moñino
 
PDF
Mod security
Manuel Carrasco Moñino
 
PDF
Gwt IV -mvp
Manuel Carrasco Moñino
 
PDF
Gwt III - Avanzado
Manuel Carrasco Moñino
 
PDF
Gwt II - trabajando con gwt
Manuel Carrasco Moñino
 
PDF
Gwt I - entendiendo gwt
Manuel Carrasco Moñino
 
PDF
Seguridad en redes de computadores
Manuel Carrasco Moñino
 
PDF
Gwt seminario java_hispano_manolocarrasco
Manuel Carrasco Moñino
 
The Java alternative to Javascript
Manuel Carrasco Moñino
 
Present and Future of GWT from a developer perspective
Manuel Carrasco Moñino
 
GWT Contributor Workshop
Manuel Carrasco Moñino
 
CRUD with Polymer 2.0
Manuel Carrasco Moñino
 
Web Components and PWA
Manuel Carrasco Moñino
 
Building Components for Business Apps
Manuel Carrasco Moñino
 
Vaadin codemotion 2014
Manuel Carrasco Moñino
 
GwtQuery the perfect companion for GWT, GWT.create 2013
Manuel Carrasco Moñino
 
Rapid and Reliable Developing with HTML5 & GWT
Manuel Carrasco Moñino
 
Aprendiendo GWT
Manuel Carrasco Moñino
 
Apache James/Hupa & GWT
Manuel Carrasco Moñino
 
GWT: Why GWT, GQuery, and RequestFactory
Manuel Carrasco Moñino
 
Gwt III - Avanzado
Manuel Carrasco Moñino
 
Gwt II - trabajando con gwt
Manuel Carrasco Moñino
 
Gwt I - entendiendo gwt
Manuel Carrasco Moñino
 
Seguridad en redes de computadores
Manuel Carrasco Moñino
 
Gwt seminario java_hispano_manolocarrasco
Manuel Carrasco Moñino
 
Ad

Recently uploaded (16)

PPTX
some leadership theories MBA management.pptx
rkseo19
 
PDF
Generalization predition MOOCs - Conference presentation - eMOOCs 2025
pmmorenom01
 
PPTX
Presentationexpressions You are student leader and have just come from a stud...
BENSTARBEATZ
 
PDF
The Impact of Game Live Streaming on In-Game Purchases of Chinese Young Game ...
Shibaura Institute of Technology
 
PDF
Cloud Computing Service Availability.pdf
chakrirocky1
 
PPTX
presentation on legal and regulatory action
raoharsh4122001
 
PPTX
Great-Books. Powerpoint presentation. files
tamayocrisgie
 
PPTX
Pastor Bob Stewart Acts 21 07 09 2025.pptx
FamilyWorshipCenterD
 
PDF
Leveraging the Power of Jira Dashboard.pdf
siddharthshukla742740
 
PPTX
2025-07-06 Abraham 06 (shared slides).pptx
Dale Wells
 
PPTX
Inspired by VeinSense: Supercharge Your Hackathon with Agentic AI
ShubhamSharma2528
 
PPTX
BARRIERS TO EFFECTIVE COMMUNICATION.pptx
shraddham25
 
PPTX
AI presentation for everyone in every fields
dodinhkhai1
 
PPTX
STURGEON BAY WI AG PPT JULY 6 2025.pptx
FamilyWorshipCenterD
 
PPTX
Food_and_Drink_Bahasa_Inggris_Kelas_5.pptx
debbystevani36
 
PDF
The Family Secret (essence of loveliness)
Favour Biodun
 
some leadership theories MBA management.pptx
rkseo19
 
Generalization predition MOOCs - Conference presentation - eMOOCs 2025
pmmorenom01
 
Presentationexpressions You are student leader and have just come from a stud...
BENSTARBEATZ
 
The Impact of Game Live Streaming on In-Game Purchases of Chinese Young Game ...
Shibaura Institute of Technology
 
Cloud Computing Service Availability.pdf
chakrirocky1
 
presentation on legal and regulatory action
raoharsh4122001
 
Great-Books. Powerpoint presentation. files
tamayocrisgie
 
Pastor Bob Stewart Acts 21 07 09 2025.pptx
FamilyWorshipCenterD
 
Leveraging the Power of Jira Dashboard.pdf
siddharthshukla742740
 
2025-07-06 Abraham 06 (shared slides).pptx
Dale Wells
 
Inspired by VeinSense: Supercharge Your Hackathon with Agentic AI
ShubhamSharma2528
 
BARRIERS TO EFFECTIVE COMMUNICATION.pptx
shraddham25
 
AI presentation for everyone in every fields
dodinhkhai1
 
STURGEON BAY WI AG PPT JULY 6 2025.pptx
FamilyWorshipCenterD
 
Food_and_Drink_Bahasa_Inggris_Kelas_5.pptx
debbystevani36
 
The Family Secret (essence of loveliness)
Favour Biodun
 

Speed up your GWT coding with gQuery

  • 1. Speed up your GWT coding with gQuery Manuel Carrasco Moñino GWT.create 2015 ► Run these slides 1/35
  • 2. About me... Open Source advocate Vaadin R&D GWT Maintainer Apache James PMC Jenkins Committer   @dodotis +ManuelCarrascoMoñino 2/35
  • 3. What is gQuery? Write less. Do more! An entire GWT rewrite of the famous jQuery javascript library. Use the jQuery API in GWT applications without including the jQuery, while leveraging the optimizations and type safety provided by GWT. 3/35
  • 4. It looks like jQuery The API and syntax of GQuery is almost identical to jQuery. Existing jQuery code can be easily adapted into GQuery and used in your GWT applications. jQuery gQuery $(".article:not(.hidden)>.header") .width($("#mainHeader").innerWidth()) .click(function(){ $(this) .siblings(".content") .load("/article/"+$(this).parent().id(), null, function(){ $(this).fadeIn(250); }); }); importstaticcom.google.gwt.query.client.GQuery.*; $(".article:not(.hidden)>.header") .width($("#mainHeader").innerWidth()) .click(newFunction(){ publicvoidf(){ $(this) .siblings(".content") .load("/article/"+$(this).parent().id(), null, newFunction(){ publicvoidf(){ $(this).fadeIn(250); } }); } }); 4/35
  • 5. But it's much more It integrates gently with GWT shares and enhances its event mechanism knows about widgets hierarchy GWT Optimizers Provides a simpler deferred binding mechanism Provide many utilities for GWT. Plenty of useful methods 5/35
  • 6. Current gQuery status Very active development 3000 downloads per month In the top 5 of the most popular GWT libraries Stable versions since 2010 Official sponsored & supported by ArcBees 6/35
  • 8. Easy DOM manipulation GQuery eases traversal and manipulation of the DOM. Use $() to wrap, find and create elements or widgets Chaining methods: select & modify several elements in just one line of code. friendly css style properties syntax. Use $$() to set style properties or for animations It also supports type safe CSS $(".slides>section").css("background-color","green") .animate($$("top:+80%")) .animate($$("top:0,background-color:transparent")).size(); $("<p>Hello</p>").appendTo(".current"); 8/35
  • 9. Full GWT Widget integration Whatever you do with elements, you can do with widgets Query, Enhance, Manipulate, Modify Promote elements to widgets inserting them in gwt hierarchy Improve widgets events Adding events not implemented by the widget Buttonb=new Button("Clickme"); b.addClickHandler(new ClickHandler(){ publicvoidonClick(ClickEventevent){ console.log("ClickedonButton"); } }); //PromoteanyDOMelementtoaGWTpanel Panelp=$("section.current.jCode-div").as(Widgets).panel().widget(); //UseitasanyotherwidgetinGWThierarchy p.add(b); //EnhanceWidgetDOM $("<ahref='javascript:'>Clickme</a>").prependTo($(b)).on("click",new Function(){ publicbooleanf(Evente){ console.log("ClickedonLink"); returnfalse; } }); 9/35
  • 10. Event Handling Handle and fire any native event. Create your own events. Support for event name spaces. Delegate events. Pass data to listeners using events Tip: Replacement to EventBus console.log("Clickoncodetexttoseethefontcolor."); $("#console").on("foo",new Function(){ publicbooleanf(Evente,Object...args){ console.log(args[0]); returntrue; } }); $(".current.jCode").on("tap","span",new Function(){ publicbooleanf(Evente){ $("#console").trigger("foo",$(e).css("color")); returnfalse; } }); 10/35
  • 11. Promises GQuery implements the promises API existing in jQuery. when, then, and, or, progress, done, fail, always Use it as an alternative to nested callback based code. Declarative syntax. Can be used in the JVM //Launchthingsatthesametimewithwhen GQuery.when( $(".ball.yellow").animate($$("bottom:0"),1000), $(".ball.red").animate($$("bottom:0"),2000) ).done(new Function(){ publicvoidf(){ $(".ball").fadeOut(); } }); 11/35
  • 12. Ajax GQuery provides an easy API for Ajax. Syntax sugar Promises Progress Works in JVM $("#response").load("gwtcreate2015.html#hello>div"); 12/35
  • 13. Data Binding GQuery ships an easy data binding system to and from JSON or XML Light weight implementation: each object wraps a JS object JVM compatible. publicinterfacePersonextendsJsonBuilder{ PersonsetName(Strings); StringgetName(); PersonsetAge(inti); intgetAge(); List<Person>getChildren(); PersongetPartner(); PersonsetPartner(Personp); } Personme=GQ.create(Person.class).setAge(10).setName("Manolo"); console.log(me); 13/35
  • 14. Utilities GQuery ships a set of GWT utilities which makes your live easier Avoiding writing GWT JSNI export, import Simplifying GWT Deferred binding browser.isIe, browser.isWebkit ... flags Browser syntax logging console.log, console.err ... Import external JS in JSNIBlocks JsniBundle 14/35
  • 15. All Right, but how can gQuery help in my GWT project ? Writing less code ! For certain actions you can save 60-90% of code Making your code more expressive Chaining is more declarative. Promises try to solve nested and complex asynchronous blocks. Using pure DOM elements instead of creating widgets for everything. The tendency is to avoid Widgets Web-components are here Reusing existing code (js, html) 15/35
  • 16. When can I use gQuery in my GWT project? 1.- Doesn't matter the final GWT architecture of your project Plain GWT, MVP, GWTP GXT, MGWT, Vaadin 2.- As usual separate Views from your Business logic. In your Views: gQuery will help you to enhance & manipulate the DOM In your Logic: you can use Ajax, Promises, and Json binding and test in the JVM 16/35
  • 17. I want to write less and do more... Show me the code 17/35
  • 18. Don't extend GWT widgets to change it's behavior. Modify the widget when it attaches or detaches. Modify its DOM Add effects Add events Tip: when GWT attaches/detaches you must set events again Easy to use in UiBinder classes Widgetwidget=new Label("Hello"); widget.addAttachHandler(new Handler(){ publicvoidonAttachOrDetach(AttachEventevent){ $(event.getSource()) .append("<span>GWT</span><span>Create</span>") .animate($$("y:+200px,x:+50px,color:yellow"),3000) .on("click","span",new Function(){ publicvoidf(){ console.log($(this).text()); } }); } }); RootPanel.get().add(widget); 18/35
  • 19. Decouple your widgets Find any widget of a specific java class. By default it looks for widgets attached to the RootPanel Enclose your search using especific selectors like '.gwt-Label' or specific contexts. Then you can use those widgets as usual in your GWT application //YougetalistwithallMyBreadCrumbmatchingtheselector List<MyBreadCrumb>list=$(".gwt-Label").widgets(MyBreadCrumb.class); MyBreadCrumbcrumbs=list.get(0); crumbs.addCrumb("Rocks"); 19/35
  • 20. GWT Ajax never was simpler. Just one line of code vs dozen of lines using RequestBuilder Reusable responses via Promises Advanced features Upload/Download progress, FormData, CORS Usable in the JVM //ConfigurableviaPropertiessyntax Ajax.get("/my-rest-service/items",$$("customer:whatever")); Ajax.post("/my-rest-service/save",$$("id:foo,description:bar")); Ajax.loadScript("/my-cdn-host/3party.js"); Ajax.importHtml("/bower_components/3party-web-component.html"); //OrviatheSettingsinterface Ajax.ajax(Ajax.createSettings() .setUrl("/my-3party-site/service") .setWithCredentials(true) .setData(GQ.create().set("parameter1","value"))) .fail(new Function(){ publicvoidf(){ console.log("Thecallshouldfailbecauseurl'sareinvalid"); } }); 20/35
  • 21. Make your async code more declarative and simpler Avoid nesting callbacks Chain promises methods to add callbacks Reuse resolved promises to avoid requesting twice the same service resolved status is maintained for ever Pipe your callbacks //Wecanreusetheloginpromiseanytime PromiseloginDone=Ajax.post("/my-login-service",$$("credentials:whatever")); GQuery.when(loginDone) .then(Ajax.post("/my-rest-service",$$().set("param","value"))) .done(new Function(){ publicObjectf(Object...args){ returnsuper.f(args); } }).fail(new Function(){ publicvoidf(){ console.log("LoginError"); } }); 21/35
  • 22. JSNI sucks, how does gQuery help? Export java functions to JS objects This will be covered by JsInterop But sometimes you will be interested on simply export one method Execute external functions Automatically boxes and un-boxes parameters and return values Wrap any JS object with JsonBuilders It supports functions Load external libraries via JsniBundle JsUtils.export(window,"foo",new Function(){ publicObjectf(Object...args){ returnargs[0]; } }); Stringresponse=JsUtils.jsni(window,"foo","ByeByeJSNI"); console.log(response); 22/35
  • 23. Simplifying deferred binding gQuery Browser flags are set in compilation time. They return true or false, making the compiler get rid of other borwsers code Not necessity of create classes nor deal with module files if(browser.webkit){ console.log("WebKit"); }elseif(browser.ie6){ //Thiscodewillneverbeinchromepermutation Window.alert("IE6doesnothaveconsole"); }else{ //Thiscodewillneverbeinchromepermutation console.log("NotwebkitnorIE.Maybemozilla?"+browser.mozilla); } 23/35
  • 25. How to extend gQuery? Plugins add new methods to GQuery objects It's easy to call new methods via the as(Plugin) method Plugins also could modify certain behaviors of gQuery: support for new selectors synthetic events new css properties ... publicstaticclassCss3AnimationsextendsGQuery{ //Wejustneedaconstructor,andareferencetothenewregisteredplugin protectedCss3Animations(GQuerygq){ super(gq); } publicstaticfinalClass<Css3Animations>Css3Animations=GQuery .registerPlugin(Css3Animations.class,new Plugin<Css3Animations>(){ publicCss3Animationsinit(GQuerygq){ returnnew Css3Animations(gq); } }); //Wecanaddnewmethodsoroverrideexistingones publicCss3Animationscss3Animate(Propertiesproperties){ super.animate(properties); returnthis; } } $(".ball").as(Css3Animations.Css3Animations).animate($$("rotateX:180deg,rotateY:180deg" 25/35
  • 26. How to port a jQuery plugin to gQuery Gesture Plugin Differences Take original JS code Create JsBuider interfaces so as syntax is similar to JS Set appropriate java types to JS variables Gesture Plugin Source Gighub Gesture Plugin Demo $(".current.jCode").as(Gesture.Gesture).on("taptwo",new Function(){ publicvoidf(){ console.log("DoubleTap"); } }); 26/35
  • 27. What is the future of gQuery Type safe functions and promises Full support for java 8 lambdas Mobile friendly Integration with JsInterop GQueryg=$(".ball"); g.each(new IsElementFunction(){ publicvoidrun(Elementelm){ $(elm).animate("scale:1.2"); } }); g.on("tapone",new IsEventFunction(){ publicBooleancall(Eventevt){ return$(evt).animate($$("rotateX:90deg")).animate($$("rotateX:0deg")).FALSE; } }); //PredefinedreturntypesinthegQuerychain g.on("taptwo",(e)->$(e).animate($$("x:+=50")).TRUE); //Gettheresultofmultiplecallbacks $.when(()->"aaa",()->"bbb",Ajax.get("/lambdas.html")) .done((Object[]s)->console.log(s[0],s[1],s[3])) .fail((s)->console.log("Fail")); 27/35
  • 28. Show me more cool code ... 28/35
  • 29. Example: Material Design Hierarchical Timing. boxes.each(new Function(){ intscale=boxes.isVisible()?0:1; publicvoidf(Elemente){ GQueryg=$(this); intdelay=(int)(g.offset().left+g.offset().top); g.animate("duration:200,delay:"+delay+",scale:"+scale); } }); 29/35
  • 30. Example: Material Design Ripple Effect. //Createtherippleelementtobeanimated finalGQueryripple=$("<div>").as(Transitions.Transitions).css( $$("position:absolute,width:40px,height:40px,background:white,border-radius:50%" //Addrippleeffectstocertainelementswhentheyaretapped $(".jCode,.button,h1").on("tap.ripple",new Function(){ publicbooleanf(Evente){ GQuerytarget=$(this).css($$("overflow:hidden")).append(ripple); intx=e.getClientX()-20-target.offset().left; inty=e.getClientY()-20-target.offset().top; intf=Math.max(target.width(),target.height())/40*3; ripple.css($$("opacity:0.8,scale:0.5")).css("left",x+"px").css("top",y+"px"); ripple.animate($$("opacity:0,scale:"+f),new Function(){ publicvoidf(){ ripple.detach(); } }); returnfalse; } }); 30/35
  • 31. Example: Wrapping Web Components with gQuery Use bower to install components in the public folder bower install Polymer/paper-slider Use Ajax utility methods to load polyfills and import templates Web Components can be created and manipulated as any other element. We can change its properties or bind events. Ajax.loadScript("bower_components/webcomponentsjs/webcomponents.js"); Ajax.importHtml("bower_components/paper-slider/paper-slider.html"); GQueryslider=$("<paper-slider/>").appendTo($("#sliders-container")); slider.prop("value",67); slider.on("change",(e)->{ console.log($(e).prop("value")); returntrue; }); $("#sliders-container").append("<paper-slidervalue=183max=255editable>"); 31/35
  • 32. Example: Binding Attributes of Web Components. JsonBuilder can wrap any JavaScript element Light Weight wrapper Type safe Chain setters publicinterfacePaperSliderextendsJsonBuilder{ //get/setprefixesareoptional intgetValue(); //Chainingsettersisoptional PaperSlidersetValue(intvalue); PaperSlidermin(intvalue); PaperSlidermax(intvalue); PaperSliderstep(intvalue); PaperSlidersnaps(booleanvalue); PaperSliderpin(booleanvalue); } //Waituntilthepolyfillandthewebcomponenthasbeenloaded GQuery.when( Ajax.loadScript("bower_components/webcomponentsjs/webcomponents.js"), Ajax.importHtml("bower_components/paper-slider/paper-slider.html") ).done(new Function(){ publicvoidf(){ //CreateandappendtheelementasusualingQuery GQueryg=$("<paper-slider>").appendTo($("#slider-container")); //WrapthenativeelementinaPOJO PaperSliderslider=GQ.create(PaperSlider.class).load(g); //Useitasajavaobject slider.setValue(300).max(400).step(50).snaps(true).pin(true); } }); 32/35
  • 33. Example: Uploading files with progress bar. finalGQueryprogress=$("<div>").css($$("height:12px,width:0%,background:#75bff4,position:absolu finalGQueryfileUpload=$("<inputtype='file'accept='image/*'>").appendTo(document).hide fileUpload.on("change",new Function(){ publicbooleanf(Evente){ finalJsArray<JavaScriptObject>files=$(e).prop("files"); JavaScriptObjectformData=JsUtils.jsni("eval","newFormData()"); for(inti=0,l=files.length();i<l;i++){ JsUtils.jsni(formData,"append","file-"+i,files.get(i)); } Ajax.ajax(Ajax.createSettings() .setUrl(uploadUrl).setData(formData).setWithCredentials(true)) .progress(new Function(){ publicvoidf(){ progress.animate("width:"+arguments(2)+"%",1000); } }).always(new Function(){ publicvoidf(){ progress.remove(); } }).done(new Function(){ publicvoidf(){ uploadImg.attr("src",uploadUrl+"&show=file-0-0"); } }); returntrue; } }).trigger("click"); 33/35
  • 35. Questions and Answers Rate this talk: http://gwtcreate.com/agenda when(()->"Talk") .then((o)->"Questions") .and((o)->"Answers") .done((o)->console.log("Thanks")); 35/35