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

PDF
GQuery a jQuery clone for Gwt, RivieraDev 2011
PDF
Rock GWT UI's with Polymer Elements
PDF
Introducing GWT Polymer (vaadin)
PDF
Web Components for Java Developers
PDF
Intro to Web Components, Polymer & Vaadin Elements
PDF
GWT integration with Vaadin
PPTX
Web Components the best marriage for a PWA
PPTX
Web components
GQuery a jQuery clone for Gwt, RivieraDev 2011
Rock GWT UI's with Polymer Elements
Introducing GWT Polymer (vaadin)
Web Components for Java Developers
Intro to Web Components, Polymer & Vaadin Elements
GWT integration with Vaadin
Web Components the best marriage for a PWA
Web components

What's hot (20)

PDF
Vaadin Components @ Angular U
PPTX
The Many Ways to Build Modular JavaScript
PDF
React
PDF
Javascript Module Patterns
PDF
GWTcon 2015 - Beyond GWT 3.0 Panic
PDF
A friend in need - A JS indeed
PDF
Difference between java script and jquery
PDF
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
PDF
Vaadin Components
PDF
Building a Startup Stack with AngularJS
PDF
Introduction to VueJS & Vuex
PPTX
Sword fighting with Dagger GDG-NYC Jan 2016
PDF
Gwt.Create Keynote San Francisco
PPT
GWT Introduction and Overview - SV Code Camp 09
PDF
Using ReactJS in AngularJS
PPTX
Vue business first
PDF
The Complementarity of React and Web Components
PPT
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
PPTX
AngularJS
PPT
GWT Training - Session 2/3
Vaadin Components @ Angular U
The Many Ways to Build Modular JavaScript
React
Javascript Module Patterns
GWTcon 2015 - Beyond GWT 3.0 Panic
A friend in need - A JS indeed
Difference between java script and jquery
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
Vaadin Components
Building a Startup Stack with AngularJS
Introduction to VueJS & Vuex
Sword fighting with Dagger GDG-NYC Jan 2016
Gwt.Create Keynote San Francisco
GWT Introduction and Overview - SV Code Camp 09
Using ReactJS in AngularJS
Vue business first
The Complementarity of React and Web Components
[Srijan Wednesday Webinar] Rails 5: What's in It for Me?
AngularJS
GWT Training - Session 2/3
Ad

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

PDF
Learning jQuery made exciting in an interactive session by one of our team me...
PDF
Introduction to jQuery
PDF
droidQuery: The Android port of jQuery
PDF
jQuery secrets
PDF
Jquery presentation
PDF
international PHP2011_Bastian Feder_jQuery's Secrets
PDF
Web UI test automation instruments
PDF
Vaadin 7 CN
PDF
Writing Maintainable JavaScript
PDF
PPTX
Blockly
PPTX
jQuery for web development
PDF
After max+phonegap
PDF
混搭移动开发:PhoneGap+JQurey+Dreamweaver
PDF
Enterprise Guice 20090217 Bejug
PDF
Improving android experience for both users and developers
PDF
Droidcon2013 android experience lahoda
PPT
Google Web Toolkit
PPTX
jQuery
Learning jQuery made exciting in an interactive session by one of our team me...
Introduction to jQuery
droidQuery: The Android port of jQuery
jQuery secrets
Jquery presentation
international PHP2011_Bastian Feder_jQuery's Secrets
Web UI test automation instruments
Vaadin 7 CN
Writing Maintainable JavaScript
Blockly
jQuery for web development
After max+phonegap
混搭移动开发:PhoneGap+JQurey+Dreamweaver
Enterprise Guice 20090217 Bejug
Improving android experience for both users and developers
Droidcon2013 android experience lahoda
Google Web Toolkit
jQuery
Ad

More from Manuel Carrasco Moñino (20)

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

Recently uploaded (20)

PPTX
2025-08-10 Joseph 02 (shared slides).pptx
PPTX
_ISO_Presentation_ISO 9001 and 45001.pptx
PPTX
Introduction-to-Food-Packaging-and-packaging -materials.pptx
PDF
oil_refinery_presentation_v1 sllfmfls.pdf
PPTX
lesson6-211001025531lesson plan ppt.pptx
PDF
Nykaa-Strategy-Case-Fixing-Retention-UX-and-D2C-Engagement (1).pdf
DOCX
"Project Management: Ultimate Guide to Tools, Techniques, and Strategies (2025)"
PPTX
fundraisepro pitch deck elegant and modern
PPTX
chapter8-180915055454bycuufucdghrwtrt.pptx
PPTX
The spiral of silence is a theory in communication and political science that...
PPTX
Introduction to Effective Communication.pptx
PPTX
Hydrogel Based delivery Cancer Treatment
PPTX
AcademyNaturalLanguageProcessing-EN-ILT-M02-Introduction.pptx
PPTX
English-9-Q1-3-.pptxjkshbxnnxgchchxgxhxhx
PPTX
Presentation for DGJV QMS (PQP)_12.03.2025.pptx
PDF
Swiggy’s Playbook: UX, Logistics & Monetization
PPTX
Learning-Plan-5-Policies-and-Practices.pptx
PPTX
Role and Responsibilities of Bangladesh Coast Guard Base, Mongla Challenges
PDF
Presentation1 [Autosaved].pdf diagnosiss
PPTX
worship songs, in any order, compilation
2025-08-10 Joseph 02 (shared slides).pptx
_ISO_Presentation_ISO 9001 and 45001.pptx
Introduction-to-Food-Packaging-and-packaging -materials.pptx
oil_refinery_presentation_v1 sllfmfls.pdf
lesson6-211001025531lesson plan ppt.pptx
Nykaa-Strategy-Case-Fixing-Retention-UX-and-D2C-Engagement (1).pdf
"Project Management: Ultimate Guide to Tools, Techniques, and Strategies (2025)"
fundraisepro pitch deck elegant and modern
chapter8-180915055454bycuufucdghrwtrt.pptx
The spiral of silence is a theory in communication and political science that...
Introduction to Effective Communication.pptx
Hydrogel Based delivery Cancer Treatment
AcademyNaturalLanguageProcessing-EN-ILT-M02-Introduction.pptx
English-9-Q1-3-.pptxjkshbxnnxgchchxgxhxhx
Presentation for DGJV QMS (PQP)_12.03.2025.pptx
Swiggy’s Playbook: UX, Logistics & Monetization
Learning-Plan-5-Policies-and-Practices.pptx
Role and Responsibilities of Bangladesh Coast Guard Base, Mongla Challenges
Presentation1 [Autosaved].pdf diagnosiss
worship songs, in any order, compilation

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