RSS Entries RSS
RSS Subscribe by Email

Struts 2 AJAX Tutorial – Dojo Autocompleter Example

This tutorial was written for Struts 2.1.2. A lot has changed in newer versions. The Dojo Plugin is no longer officially supported by the Struts 2 team. Also, please see Muhammad’s comment in the comment section if you’re using the latest version of Struts 2.  You may want to check out Google Closure if you’re looking for a good JS library.

Struts 2 comes with a Dojo Toolkit plugin which makes developing an AJAX application easier than ever.  In addition, the AJAX plugin I would most recommend is the Struts 2 JSON plugin.  In this example, we will use the two side-by-side to create an autocompleter.  In order to use the Ajax support provided in Struts 2, I would recommend Struts 2.1.2 or later.  Include struts2-dojo-plugin-2.1.2.jar and jsonplugin-0.30.jar in your WEB-INF/lib directory.

First, we will create the action for the field that we wish to autocomplete:

package com.lumidant.tutorial.struts2.action;

import java.util.HashMap;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;
import com.lumidant.tutorial.struts.dao.*;

public class AutocompleteField extends ActionSupport {

    private String city;
    private Map<String,String> json;

    public String execute() throws Exception() {
        return SUCCESS;
    }

    public String getCities() throws Exception() {
        json = new HashMap<String,String>();

        if(city != null && city.length() > 0) {
            CityDao dao = new CityDao();
            List<City> cities = dao.getCitiesStartingWith(city);
            for(City city : cities) {
                json.put(city.getId(), city.getName() + ", " + city.getState().getAbbreviation());
            }
        }

        return SUCCESS;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public Map<String,String> getJson() {
        return json;
    }

}

The getCities method in our action acts on the input String city that we’re given and creates a Map of cities starting with that text.  The key of our Map is going to be the hidden option value while the value of our Map is going to be our option text.

Next, we will modify our struts.xml configuration file to utilize the JSON plugin by extending json-default:

<package name="example" extends="json-default">
  <action name="AutocompleteField" class="com.lumidant.tutorial.struts2.action.AutocompleteField">
    <result type="json><param name="root">json</param></result>
  </action>
</package>

The root parameter that we specify is the name of the variable from our Action that we want to have converted and serialized to a JSON output.

If instead of serializing a Java object to JSON you wish to create the JSON string directly yourself, you can instead use a result type of “stream”:

<action name="jsondata" class="com.lumidant.tutorial.struts2.action.JsonDataAction">
  <result type="stream">
    <param name="contentType">application/json</param>
  </result>
</action>

And finally, we get to create our .jsp view:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>

<html>
  <head>
    <sx:head />
  </head>
  <body>
    <s:url id="cityList" action="AutocompleteField" method="getCities" />
    <sx:autocompleter name="city" theme="ajax" href="%{cityList}" size="24" />
  </body>
</html>

For any of the Dojo plug-in features that you use, you will need to include the <sx:head /> tag, which includes the relevant JavaScript tags into your page’s head tag.  Then you can see that the autocompleter’s name attribute aligns with the city field in our Action and the url’s method attribute aligns with our Action’s getCities method.  Now, when you visit your new page and start typing in the text box, you should see the field autocompleting.  There are some other cool built-in Dojo tags that you should look at as well like the datetimepicker, which provides a really nice calendar.

Share and Enjoy:
  • Add to favorites
  • HackerNews
  • DZone
  • Reddit
  • del.icio.us
  • StumbleUpon
  • Slashdot
  • Digg
  • Google Bookmarks
  • Facebook

Tags: , , ,

27 Comments »

  1. Saurabh said,

    October 30, 2008 at 10:26 pm

    hi
    I have used this code. i put struts 2.1.2 jar .I have include struts2-dojo-plugin-2.1.2.jar and jsonplugin-0.30.jar in my WEB-INF/lib directory. but in xml it is not supporting theme in

  2. Michele Pilloni said,

    November 11, 2008 at 7:13 am

    Hi I have the same problem, I followed carefully your instructions but it doesn’t seem able to recongnize the attribute theme in autocompleter tag:
    “Attribute theme invalid for tag autocompleter according to TLD”

    Any Idea? thanks

  3. TheSialz said,

    November 27, 2008 at 5:18 am

    hi
    I have a question about the root parameter,when my action has two methods,the first method wants to return attribute1′s JOSN,and the second wants to return attribute2′s JSON,how should I do? thanks

  4. Ben said,

    November 27, 2008 at 10:32 am

    TheSialz,
    I don’t think I understand your problem. That sounds like it is working properly to me. You can use one method to do an autocomplete on one field and the other method to autocomplete the other field.
    What are you expecting to have happen?

    -Ben

  5. sohran said,

    November 30, 2008 at 8:30 pm

    Hi
    How can i use dojo TextBox control to retrieve data from struts2 instead of Field Name?
    I think it should be something like
    but it doesn’t work.

  6. julloa said,

    May 27, 2009 at 10:00 am

    hi ben, now that dojo is deprecated. do u still recommend it?

    based in ur experienced, what is the best practice 2 struts2-ajax support-

  7. Ben said,

    May 27, 2009 at 6:59 pm

    Hi Julloa,
    It is only the Dojo plug-in that is deprecated, not Dojo itself. You may be better off using the libraries directly instead of the plug-in. There are many JS libraries available and the choice of which to use isn’t much related to using Struts 2. Rather, I’d base your choice on other factors such as adoption, size/latency, and the organization you’re working with.

  8. julloa said,

    May 27, 2009 at 10:26 pm

    HI:

    HOW I CAN USE AJAX TAGS IN ORDER TO POPULATE 3 DROPDOWN (COUNTRY, DEPARMENT, DISTRICT).
    TEH OBJECTIVE IS TO LOAD ONLY THIS 3 CONTROLERS AND NOT ALL THE JSP PAGE(USER REGISTARTION.JSP).

    CAN U POINT A SHOR EXAMPLE OF THE DOJO – JSP CODE ?

  9. ilayaraja said,

    July 10, 2009 at 10:34 pm

    i have problem in filling the autocompleter in struts 2 using ajax and javascript please someone help me

  10. jfuentes said,

    July 29, 2009 at 10:14 am

    Hi people, i have a problem when I try to build an autocompleter from an ajax page, this is, another jsp where I declare the autocompleter, but the tag is not completely parse or something, i’ve checked the resulting code with firebug and there too much left than in the working autocompleter code in the main page. This has been a real nightmare for me to get struts2 to work with ajax in IE6 and Firefox, but even more in IE6 where the tags they just dont want to work. Due to this i decided to learn and use standard plain and simple ajax, i have been fighting a while with OGNL expresions and but when finally i can shout Victory, i found that autocompleters arent there :S, only the text field, this is part of the code:

    here is where i want to put the content obtained via AJAX passing through the its action and loading dynamic data, everything’s fina so far, this is what i want to show:

    planes.jsp:

    Rif

    Ci

    :

    the code above was working in the main page.jsp, but when i moved it to planes.jsp it now shows olvy the text box.

    Can you suggest me any clue to show my ac declared in AJAX’s external jsps?? Or lead me to where to ask.

    Thank you very much

  11. jfuentes said,

    July 29, 2009 at 10:15 am

    Sorry, the page deleted the code :S

  12. Arindam said,

    August 11, 2009 at 11:19 am

    Hi all I am also trying the same with strut 2.1.6…
    It is not working at all. Please can you share some info…

  13. ssm said,

    September 3, 2009 at 11:57 am

    I do not think Struts 2 comes with result type called json. I think we will have to write a custom result handle and define it in the config file to achieve the goal. Correct me if I am wrong.

  14. Ben said,

    September 3, 2009 at 12:45 pm

    ssm, this example uses the Struts 2 JSON plugin referenced at the beginning of the post

  15. Sunflower said,

    October 16, 2009 at 2:13 am

    Hi!!!

    That great!!!

    So, May u tell me how to using autocomplete with object list?

    I have class as bellow:
    Employee {
    String code;
    String name;
    }

    And how to using autocomplete with List and search following name of employee?

    Thanks a lot!!!

  16. Sunflower said,

    October 16, 2009 at 2:17 am

    List (Employee) instead of Map(String, String)

  17. Muhammad Waqar Baig said,

    December 11, 2009 at 4:49 am

    Very well written, simple but comprehensive article to guide newbies like me introducing many concepts in the way. Highly commendable effort. Took me a couple of days to get all of it working on Struts 2.1.6 (except for the DAO part which I omitted on purpose). Want to provide a little heads-up for people attempting this on newer versions of struts2 to save them from some possible frustration.

    0. As pointed out by Benjamin, this example uses the jsonplugin.jar instead of the new json-lib (using which might require another tutorial).
    1. Omit (theme=”ajax”) from autocompleter tag in the .jsp file. It is no longer required.
    2. Add (loadOnTextChange=”true”) to the tag. The documentation for autocompleter says that this attribute is ‘true’ by default but my experience and experimentation has shown otherwise.
    3. Move (method=”getCities”) from the autocompleter tag in the .jsp file to action definition in struts.xml.
    4. Also, since 2.0.9, key:value pair order has been reversed and value comes first now, so change the (json.put(Id, CityName)) statement to (json.put(CityName, Id)).

    With this working now, I’ll look into adapting to json-lib which is a part of struts2 now.

    Again, thanks for the wonderful article.

    Have fun.

  18. Muhammad Waqar Baig said,

    December 11, 2009 at 4:58 am

    Oh another thing:

    5. Add (preload=”false”) to the autocompleter tag since it is true by default and causes the action to be carried out once on page load only.

    I’ve checked and you’ll need to carry out points 2. & 5. to get it to work fully.

  19. Ben said,

    December 11, 2009 at 2:47 pm

    Thanks Muhammad. I really appreciate you sharing this knowledge.

  20. Muhammad Waqar Baig said,

    December 15, 2009 at 3:51 am

    You’re most welcome. Just trying to give something back.

  21. Anusha said,

    December 17, 2009 at 10:45 pm

    My query is similar to that of julloa

    I want to load classes based on the selection of department & then subclasses based on class selection. Can someone please mail me a smaple code to do this?

  22. Gilbert Grape said,

    January 18, 2010 at 6:08 am

    as am starter in Ajax(with Struts), please help me with loading a select box, based on the radio button selected, can any body send the sample code to do this..?

  23. Muhammad Waqar Baig said,

    January 25, 2010 at 8:39 am

    Anusha: Gilbert:
    You would require a little knowledge of Dojo ‘Topics’ and AJAX enabled struts tags (like div etc). Rest is pretty simple.
    For a demo, you can follow the example given at:

    http://javachamp.blogspot.com/2008/06/struts-2-ajax-drop-down-example.html.

    Like this tutorial, that example was also made in Struts 2.0.x and needs some fixing to work with Struts 2.1.4+ libraries. Fortunately, someone has commented on the example given steps in making the example up-to-date. Should get you up and running in no time. I got that example working for me with Struts 2.1.6 (just in case any one needs a working code).

    Regards.

  24. Delph said,

    January 27, 2010 at 1:20 am

    Hi,
    I’m newwbie and I have a question.
    The default package in struts.xml already extends struts-default, so how can I extends json-default too??

    Thanks

  25. Ben said,

    January 27, 2010 at 2:25 am

    Delph, you cannot directly extend from two packages. Extending from json-default should be sufficient in this example. If I remember correctly, json-default extends from struts-default.

  26. Suresh said,

    June 8, 2010 at 12:07 pm

    Hi-

    Thanks for the detailed tutorial on Dojo Autocompleter.
    I have one requirement that need to capture the “mouseout” event on the autocompleter component. I have been searching for this, I couldn’t find any.

    Explanation:
    Once user enters the text that is not there in the list, I need to handle couple of other things as soon as user tabs out of the component.

    Please help me if anyone have ideas.

    Thanks in advance,
    Suresh

  27. Rajeev said,

    September 1, 2010 at 10:57 am

    I want to disable autocompleter combobox if no item is there in autocompleter.
    Can anyone help me out.

    Disable autocompleter combobox not autocompleter.

    Thanks
    In advance.
    Rajeev Kumar

RSS feed for comments on this post · TrackBack URL

Leave a Comment