title: Populating one select menu based on another select menu using AJAX in Struts2
body: <p>I'm trying to use AJAX at very first time in Struts2. Therefore, I do not have precise idea about it.</p>
  
  <p>There are two <code>&lt;s:select&gt;</code>s, one holds a list of countries which is loaded on page load and another holds a list of states that corresponds to the country selected from the country menu.</p>
  
  <p>Therefore, the state menu should be initialized on the <code>onchange</code> JavaScript event triggered by the country menu.</p>
  
  <p>The incomplete version of such a JavaScript function is as follows.</p>
  
  <pre><code>var timeout;
  var request;
  
  function getStates(countryId)
  {
      if(!request)
      {
          if(countryId===""||countryId===null||countryId===undefined||isNaN(countryId))
          {
              $('#stateList').html("Write an empty &lt;select&gt;");
              alert("Please select an appropriate option.");
              return;
          }
  
          request = $.ajax({
              datatype:"json",
              type: "GET",
              contentType: "application/json",
              url: "PopulateStateList.action?countryId="+countryId,
              success: function(response)
              {
                  if(typeof response==='object'&amp;&amp;response instanceof Array) //Array or something else.
                  {
                      $('#stateList').html(writeResponseSomeWay);
                      $('#temp').remove();
                  }
              },
              complete: function()
              {
                  timeout = request = null;
              },
              error: function(request, status, error)
              {
                  if(status!=="timeout"&amp;&amp;status!=="abort")
                  {
                      alert(status+" : "+error);
                  }
              }
          });
          timeout = setTimeout(function() {
              if(request)
              {
                  request.abort();
                  alert("The request has been timed out.");
              }
          }, 300000); //5 minutes
      }
  }
  </code></pre>
  
  <p><code>&lt;s:select&gt;</code> for country:</p>
  
  <pre><code>&lt;s:select id="country" 
            onchange="getStates(this.value);" 
            name="entity.state.countryId" 
            list="countries" value="entity.state.country.countryId" 
            listKey="countryId" listValue="countryName" 
            headerKey="" headerValue="Select" 
            listTitle="countryName"/&gt;
  </code></pre>
  
  <p><code>&lt;s:select&gt;</code> for state:</p>
  
  <pre><code>&lt;s:select id="state" 
            name="entity.stateId" 
            list="stateTables" value="entity.state.stateId" 
            listKey="stateId" listValue="stateName" 
            headerKey="" headerValue="Select" 
            listTitle="stateName"/&gt;
  </code></pre>
  
  <p>The above JavaScript/jQuery function sends an AJAX request to <code>PopulateStateList.action</code> which is mapped to a method in an action class as follows.</p>
  
  <pre><code>List&lt;StateTable&gt;stateTables=new ArrayList&lt;StateTable&gt;(); //Getter only.
  
  @Action(value = "PopulateStateList",
          results = {
              @Result(name=ActionSupport.SUCCESS, location="City.jsp"),
              @Result(name = ActionSupport.INPUT, location = "City.jsp")},
          interceptorRefs={@InterceptorRef(value="modelParamsPrepareParamsStack", params={"params.acceptParamNames", "countryId", "validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "getStateList"})})
  public String getStateList() throws Exception
  {
      System.out.println("countryId = "+countryId);
      stateTables=springService.findStatesByCountryId(countryId);
      return ActionSupport.SUCCESS;
  }
  </code></pre>
  
  <p>This method is invoked, when a country is selected in its menu and the <code>countryId</code> supplied as a query-string parameter is retrieved but how to return/map this list, <code>stateTables</code> to initialize/populate <code>&lt;s:select&gt;</code> of state menu?</p>
  
  <hr>
  
  <p>I have earlier used JSON with Jackson and Gson in Spring MVC. Using Gson, for example, a JSON response could simply be mapped like as follows (using a Servlet for the sake of simplicity).</p>
  
  <pre><code>import com.google.gson.Gson;
  import com.google.gson.reflect.TypeToken;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.lang.reflect.Type;
  import java.util.HashMap;
  import java.util.Map;
  import javax.servlet.ServletException;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  @WebServlet(name = "AjaxMapServlet", urlPatterns = {"/AjaxMapServlet"})
  public class AjaxMapServlet extends HttpServlet
  {
      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
      {
          Map&lt;String, String&gt;map=new HashMap&lt;String, String&gt;();
          map.put("1", "India");
          map.put("2", "America");
          map.put("3", "England");
          map.put("4", "Japan");
          map.put("5", "Germany");
  
          Type type=new TypeToken&lt;Map&lt;String, String&gt;&gt;(){}.getType();
          Gson gson=new Gson();
          String jsonString=gson.toJson(map, type);
          response.setContentType("application/json");
          response.setCharacterEncoding("UTF-8");
          response.getWriter().write(jsonString);
      }
  }
  </code></pre>
  
  <p>and in JSP, this <code>Map</code> could be written as follows.</p>
  
  <pre><code>$('#btnMap').click(function() {
      $.get('/TestMVC/AjaxMapServlet', function(responseJson) {
              var $select = $('#mapSelect');
              $select.find('option').remove();
              $('&lt;option&gt;').val("-1").text("Select").appendTo($select)
              $.each(responseJson, function(key, value) {
              $('&lt;option&gt;').val(key).text(value).appendTo($select);
      });
      });
  })
  
  &lt;input type="button" id="btnMap" name="btnMap" value="Map"/&gt;&lt;br/&gt;
  &lt;select id="mapSelect" name="mapSelect"&gt;&lt;option&gt;Select&lt;/option&gt;&lt;/select&gt;
  </code></pre>
  
  <p><code>&lt;select&gt;</code> will be populated on pressing the given button, <code>btnMap</code>.</p>
  
  <p>What about Struts2? How to populate an <code>&lt;s:select&gt;</code> based on another <code>&lt;s:select&gt;</code>?</p>