Friday, July 4, 2008

Google Web Toolkit - Suggest Box (RPC)

The Google Web Toolkit provides many advanced features to make a web page come alive. One feature that is used commonly in AJAX webpages is a select box that has context sensitive options.

I have already covered the SuggestBox, this article will focus on retrieving your suggestion through an asynchronous Javascript call. You may want to read the following articles as this article builds off some of those concepts.

* GWT suggest box
* GWT RPC Call

To create an RPC Suggest Box you will need to do the following
* Create a Service to serve your suggestions. This service will take an input and return a collection of data.
* Create an oracle that wraps the calls to the Service

Create Suggestion RPC Service

Your client side Suggestion box will fire an onchange event when the user enters a keystroke. When this happens you want to send over the entered text and instruct the control to suggest only items that match the pattern.

To do this we need to define a Service. As we saw in
GWT RPC Call we need to define two interfaces we'll call them:
  • IQuoteService
  • IQuoteServiceAsync

public interface IQuoteService extends RemoteService {

public static class Util {
public static IQuoteServiceAsync getInstance() {
IQuoteServiceAsync instance=(IQuoteServiceAsync) GWT.create(IQuoteService.class);
ServiceDefTarget target = (ServiceDefTarget) instance;
target.setServiceEntryPoint("/GWT/quote");
return instance;
}
}

public SuggestOracle.Response getQuote(SuggestOracle.Request req);
}

public interface IQuoteServiceAsync {
public void getQuote(SuggestOracle.Request req, AsyncCallback callback);
}

Your Oracle will need to return a class with a com.google.gwt.user.client.ui.SuggestOracle.Suggestion interface. To faciliate this we create a new class called ItemSuggestion.

Note: This class must reside on the client side else you will get serialization errors when you run the app.


public class ItemSuggestion implements IsSerializable, Suggestion {

private String s;
// Required for IsSerializable to work
public ItemSuggestion() {
}

// Convenience method for creation of a suggestion
public ItemSuggestion(String s) {
this.s = s;
}

public String getDisplayString() {
return s;
}

public String getReplacementString() {
return s;
}
} // end inner class ItemSuggestion



Now define the actual service on the server side:
public class RandomQuoteService extends RemoteServiceServlet implements IQuoteService {


public SuggestOracle.Response getQuote(SuggestOracle.Request req) {

// req has request properties that you can use to perform a db search
// or some other query. Then populate the suggestions up to req.getLimit() and
// return in a SuggestOracle.Response object.
SuggestOracle.Response resp = new SuggestOracle.Response();

List<suggestion> suggestions = new ArrayList<suggestion>();
suggestions.add(new ItemSuggestion("It is a good day to die"));
suggestions.add(new ItemSuggestion("I shall return"));
suggestions.add(new ItemSuggestion("There is nothing to fear but fear itself"));

resp.setSuggestions(suggestions);
return resp;
}
}
Create Suggestion Oracle

So far we've created our service now we need to create the Oracle.

You simply extend SuggestOracle and instruct it to use the Service for its suggestions.

public class ItemSuggestOracle extends SuggestOracle {

public boolean isDisplayStringHTML() {
return true;
}

public void requestSuggestions(SuggestOracle.Request req,SuggestOracle.Callback callback) {
IQuoteService.Util.getInstance().getQuote(req, new ItemSuggestCallback(req, callback));
}

class ItemSuggestCallback implements AsyncCallback {

private SuggestOracle.Request req;
private SuggestOracle.Callback callback;

public ItemSuggestCallback(SuggestOracle.Request _req,
SuggestOracle.Callback _callback) {
req = _req;
callback = _callback;
}

public void onFailure(Throwable error) {
callback.onSuggestionsReady(req, new SuggestOracle.Response());
}

public void onSuccess(Object retValue) {
callback.onSuggestionsReady(req,
(SuggestOracle.Response) retValue);
}
}
}


And now the result of all our work, we create a new SuggestBox with the new oracle.

public void display() {

ItemSuggestOracle oracle = new ItemSuggestOracle();
SuggestBox sb = new SuggestBox(oracle);

// Add it to the root panel.
RootPanel.get().add(sb);
}


That's it! It looks like its a lot of work but its mostly plumbing and you should find its pretty easy to do once you get the hang of it.

Give it a try and leave a comment to let me know how it goes.

71 comments:

Dan Kibler said...

I tried to put this to work in GWT 1.5. One thing you leave our of your blog entry is the code for the ItemSuggestion class. It appears to be a custom Suggestion. I tried to write my own but I'm getting a serialization error -

Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'com.getrolling.cis.client.TourSuggestion' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.

developer-resource said...

Dan, I'm guessing your defining your suggestion class on the Server Side.

You must define it on the client side, then you can import it into the Server side class and it should work.

I've updated my example to hopefully make that more clear.

Hope that helps...

petertparker said...

Hi Nice Blog web development services designs custom sites for businesses and non-profit organizations. We can build a site of any size that will reflect the spirit and flavor of your organization. We can rebuild sites that are out-dated or that fail to attract your target audience. We build web sites from anywhere; we work with organizations all over the North America. Best of all, we are not done until you are satisfied.We design customized banners, buttons, and embellishments for your website. We can also implement flash animation, a customized intro page, and other special features. All pages include descriptor tags and keywords for search engine indexing.

Anonymous said...

What a stupid article. The code doesn't even work. Test the stuff before you post it.

developer-resource said...

Anonymous, I'm sorry it didn't work for you.

It works on my machine. If you want, post what you tried and I'd be glad to help you out.

Manikandan said...

Good article.It works fine. It helped me in very important time to finish my work. Thanks.

Anonymous said...

Worked great, thanks

Mike Kienenberger said...

You neglected to mention in this post that you have to define a servlet in the web.xml file for the service

<servlet>
<servlet-name>quoteServiceServlet</servlet-name>
<servlet-class>yourpackage.server.RandomQuoteService</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>quoteServiceServlet</servlet-name>
<url-pattern>/GWT/quote</url-pattern>
</servlet-mapping>

AtlAl said...
This comment has been removed by the author.
AtlAl said...

Has anybody received this error:[ERROR] Uncaught exception escaped
java.lang.NullPointerException: null
at com.google.gwt.user.client.ui.
SuggestBox.showSuggestions
(SuggestBox.java:616)
at com.google.gwt.user.client.ui.
SuggestBox.access$0
SuggestBox.java:615)

at
com.google.gwt.user.client.
ui.SuggestBox$1.
onSuggestionsReady
(SuggestBox.java:386)
at
.ItemSuggestOracle
$ItemSuggestCallback.
onFailure
(ItemSuggestOracle.java:36)

Where can i download the source code?

Anonymous said...

Hallo I go in accordance this tutorial except 1 thing I give List ItemSuggestion suggestions = new ArrayList ItemSuggestion (); instead List suggestion suggestions = new ArrayList suggestion ();

App is going. But wrong. It's not select true item. screenshot> http://stargate.cnl.tuke.sk/~maly/gwt.png

I use gwt 1.6.4, where is the problem?

Anonymous said...

Hi AtlAl -- see the previous comment about servlet mapping. This will probably fix your problem if the mapping is consistent with ServiceDefTarget.setServiceEntryPoint() in your interface that extends the RemoteService.

Thanks for this post Developer Resource!

prusch said...

Thanks for the post. I had some trouble till I realized I had put ItemSuggestOracle on the server side. Then it worked perfectly.

dianbo said...

This post helps me a lot, thx!

Seb said...

Nice tutorial. The RPCs work fine but I have the same problem like Anonymous before.

The true items where not automatically selected.
How can I solve this problem?

Kevin Jansz said...

thanks for a very helpful post. For the comments that items aren't selected - is it because the css is missing? This is what I'm using:

/* suggestions */
.gwt-SuggestBoxPopup {
border:2px solid #C3D9FF;
background-color: window;
}
.gwt-SuggestBoxPopup .item {
padding:2px;
}
.gwt-SuggestBoxPopup .item-selected {
background-color:#C3D9FF;
padding:2px;
cursor: pointer;
}

Web Design Company said...

very well written post. i have been long looking for some nice blogs on web design and especially the one writen on web 3.0 web designs was damn interesting....very enlightening article....keep up the good work. Web Design company

Anonymous said...

I tried this tutorial in GTW 2.0.x - RPC is working fine. :) Unfortunately the SuggestBox is not working properly. It shows all the words/strings I put into the response and it always and only selects the first entry in the popup, no matter what I type. I can select other entries manually, but I think this is not the way the SuggestBox should work?!

Alvin said...

These pictures are so impressive. I am sure my peers will enjoy these too.Property development

Web Design Company said...

Great article. Thank you for your provided information.childrens keyboards

Kevin said...

KidsDesk.net brings innovative products and educational resources to parents, caretakers and educators. With products ranging preschool to grade school age children.childrens furniture

Santosh said...

Interesting...
---------------
facebook history

strumpfhosen said...

This is a GREAT post! I hope you not mind.I published an excerpt on the site and linked back to your own blog for people to read the full version. Thanks for your advice.

Uk Ties said...

Interesting layout on your blog. I really enjoyed reading it and also I will be back to read more in the future.

Harry said...

Felix Labs is a best web Design Company india, providing top flash web design services, website development services and 3d animation services. Get high quality website development and web design services from the experts.Web design company

Maninder Kaur said...

This is a good common sense article. Very helpful to one who is just finding the resources about this part. It will certainly help educate me. Web Designing Company

Dropship Wholesale said...

Thanks for taking this opportunity to discuss this, I feel fervently about this and I like learning about this subject.Dropship

Anonymous said...

Easily, the publish is really the greatest on this laudable topic. I concur with your conclusions and will thirstily look forward to your future updates. Saying thanks will not just be sufficient, for the fantastic lucidity in your writing. I will instantly grab your rss feed to stay privy of any updates. Solid work and much success in your business enterprise!

Ashly said...

Hi,

This was a great article.. thanks a lot..

I was trying to tweek this a little bit.. Here, when ever you type something in the box, server side call is initiated. I have restricted this to minimum of 5 letters and it works fine with the below code in ItemSuggestOracle class

public void requestSuggestions(SuggestOracle.Request req,SuggestOracle.Callback callback) {
if(req.getQuery().length() > 4){
getService().getBroadBeanLocations(req, new ItemSuggestCallback(req, callback));
}
}


Thinking over it, if I get the list of items that matches 5 letters and loaded to the SuggestBox, why do I need to call the RPC method for letters more than 5 (because they are included in the SuggestBox already). But unfortunately this does not happen.. Could you please help me on how to achieve this please.

The reason why I'm asking this is, I have got 50000 records to search on. So, searching on all these records for each character will not be a good idea. Please help...

Thanks,
-ash

Thermage chicago said...

This is a good common sense article. Very helpful to one who is just finding the resources about this part. It will certainly help educate me.

web development services said...

You got numerous positive points there. I made a search on the issue and found nearly all peoples will agree with your blog...Loving the information on this site.

Electrical Contractor Houston said...

Spot on with this write-up, I really think this website needs much more consideration. I’ll probably be again to learn way more, thanks for that info.

Lingerie Pantyhose said...

Now thats what I call a great online resource. I am gonna go ahead and share it with my friends.

Arun said...

Hi,
I am getting following exception while executing the code.
Plzz help...
com.google.gwt.user.client.rpc.SerializationException: Type 'com.mine.service.client.ItemSuggestion' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.infy.service.client.ItemSuggestion@8cb15b

Mady-Censored said...

Works Perfectly Fine... awesome one...

Mady-Censored said...

i have changes my class this way

public class ItemSuggestOracle extends SuggestOracle {

public boolean isDisplayStringHTML() {
return true;
}

public void requestSuggestions(SuggestOracle.Request req,SuggestOracle.Callback callback) {
final IQuoteServiceAsync service = GWT.create(IQuoteService.class);
service.getQuote(req, new ItemSuggestCallback(req, callback));
}

class ItemSuggestCallback implements AsyncCallback {

private SuggestOracle.Request req;
private SuggestOracle.Callback callback;

public ItemSuggestCallback(SuggestOracle.Request _req,
SuggestOracle.Callback _callback) {
req = _req;
callback = _callback;
}

public void onFailure(Throwable error) {
callback.onSuggestionsReady(req, new SuggestOracle.Response());
}

public void onSuccess(Object retValue) {
callback.onSuggestionsReady(req,
(SuggestOracle.Response) retValue);
}
}
}

Mady-Censored said...

and

@RemoteServiceRelativePath("rpc/searchUserService")
public interface IQuoteService extends RemoteService {

public SuggestOracle.Response getQuote(SuggestOracle.Request req);

}

Tango kurs said...

Interesting and important information. It is really beneficial for us. Thanks

Cheap penny auctions sites said...

Thank you, thats very interesting information. I need to share with my friends.

Fulton Septic Cleaning said...

I found your website perfect for my needs. It contains wonderful and helpful posts. I have read most of them and learned a lot from them. You are doing some great work. Thank you for making such a nice website.

Fort Lauderdale criminal lawyer said...

Interesting layout on your blog. I really enjoyed reading it and also I will be back to read more in the future.

Pantyhose said...

just couldn’t leave your website before telling you that we really enjoyed the quality information you offer to your visitors… Will be back often to check up on new posts.

Fort Lauderdale criminal lawyer said...

This Blog is going places, the people, the layout, amazing to see such dedication and focus.

SEO Services said...

We're a group of volunteers and opening a new scheme in our community. Your web site provided us with valuable information to work on. You have done an impressive job and our whole community will be grateful to you.

RFA52S said...

Thanks you. Very good post.Unless they can offer a really compelling reason for users to come back, it will be the next Bebo, MySpace

Zolpidem No Prescription said...

It is an interesting post, and really appreciable. The clearness in your post is simply spectacular and i can assume you are an expert on this subject. I will grap each and every information and refer to my friends also.

deep cycle battery said...

Wow, Fantastic Blog, it’s so helpful to me, and your blog is very good,
I’ve learned a lot from your blog here, Keep on going, my friend, I will keep an eye on it,

where to buy essential oils said...

I found your website perfect for my needs. It contains wonderful and helpful posts. I have read most of them and learned a lot from them. You are doing some great work. Thank you for making such a nice website.

custom software said...

great job on the "Google Web Toolkit - Suggest Box (RPC)"

Training Tampa said...

I have to say, every time I come to #hostname you have another interesting post to read. A friend of mine was telling me about this topic a few weeks ago, so I think I'll e-mail them the link here and see what they say.

Leicester fridges said...

I just couldn’t leave your website before telling you that we really enjoyed the quality information you offer to your visitors… Will be back often to check up on new posts.

SEO said...

Buy Sigma Lenses, Sigma Prime, Sigma Telephoto, Sigma Zoom, Sigma Fisheye Lens for Canon, Nikon, Pentax, Sony and Four Thirds Olympus, Panasonic from Microglobe in very cheap price.

Vancouver Internet Marketing said...

This is a good common sense Blog. Very helpful to one who is just finding the resources about this part. It will certainly help educate me.

Sign Installation said...

Interesting and important information. It is really beneficial for us. Thanks

Web Design Company said...

Thanks for sharing such an informative blog . Well done . hope to get more informative blogs like this .
Regards

Software development company

blackberry developer said...

I think the code needs some repairment because some pieces of it do not work properly. SO it'd be great if the author will reconsider it as it might be really useful.

Jake Gyllenhall workout said...

Thanks for such a very informative information. very nice I thing to get more information like this...

Channing Tatum workout said...

Easily, the publish is really the greatest on this laudable topic. I concur with your conclusions and will thirstily look forward to your future updates. Saying thanks will not just be sufficient, for the fantastic lucidity in your writing. I will instantly grab your rss feed to stay privy of any updates. Solid work and much success in your business enterprise!

Anonymous said...

Just fetch data if leng=5, not lenght> 4

Luxury British Watches said...

Nice job. Personally I like this article. I think it would be more and more helpful for all those people are want to drive their career in SEO field.

rocky case said...

Stephen Stapinski

Really your blog is very interesting.... it contains great and unique information. I enjoyed to visiting your blog. It's just amazing.... Thanks very much for the share.

Web development Company said...

This is a nice web site. Good fresh interface and nice informative articles. I will be coming back soon, thanks for the great article.

Aanya Dsouza said...

I am very much impressed with this blog. I am very much interested in magento web development also. But this is something different for getting more information.

click here said...

This website was... how do I say it? Relevant!! Finally I have found something which helped me. Thank you!
get information

Best Enterprise application said...

Thanks for the blog. It's great i like it.

Daedg Microsoft said...

Assuming in the last quarter of 2014 APL Logistics generates revenues north tiffany boxing day sale of $400m – which is achievable based on weekly revenues of more than $30m in recent quarters – its annual revenues will stand at about $1.6bn. tiffany and co australia sale The unit has fared pretty well in recent times, having grown in all its markets: Asia, Middle East, Americas and Europe. Assuming steady operating margins, Swarovski australia sale it may generate Ebitda of about $80m in 2014, up from $76m in 2013.

Ruby on Rails Development said...

Lovely blog having such a valuable content!!!.

papayoung said...

cheap ray ban sunglasses clearance cheap ass from ray ban sunglasses clearance sale his pocket and took out a trembling hand has almost broken cigarette, handed in front outlet, hehe smile, said small leaves, cheap ray ban sunglasses clearance to taste my smoke, but my collection for a long time cheap ray ban sunglasses clearance than you that fifty box a lot better. Grass, this is what http://www.centremk.co.uk you face, you do not believe ah, this is the cheap ray ban sunglasses clearance Sanjiang cards, three dollars a pack.

Frank Roberts said...

I regret to comment on this blog but don't really have other options left have to try it for some reason.
Regards
Frank
hire offshore developers

jennifer smith said...

Decent Job. By and by I like this article. I think it would be increasingly useful for every one of those individuals are need to drive their vocation in SEO field.

hellanadam said...

Being new to the blogging world I feel like there is still so much to learn. Your tips helped to clarify a few things for me as well as giving..
ios App Development Company
Android App Development Company
Mobile App Development Company