0

I'm using struts2-jquery-plugin. Normally in my form, I need my first select to be populated from database by School Subjects and according to the chosen school subject I need to update the second select and populate it from database by the Teachers who teach that subject.

I found in the following link the sample code above, but I can't guess much how it works. They don't explain it. http://struts2-jquery.appspot.com/home.action# .

Am I forced to use JSON? Any explaination or a code to help me in my issue would be so appreciated.

<label>First Select:</label> 
<sj:select id="firstSelect" name="firstSelect" onChangeTopics="firstSelectChanged" src="firstSelect.action"/> 
<label>Second Select:</label> 
<sj:select id="secondSelect" reloadTopics="firstSelectChanged" src="secondSelect.action" elementIds="firstSelect"/>

Update

I tried this link http://struts.jgeppert.com/struts2-jquery-showcase/index.action ( the section Ajax Link > AJAX Select) suggested in this post by nmc but I get this error :

Struts Problem Report
Struts has detected an unhandled exception: 

Messages: •There is no Action mapped for namespace / and action name echo.



--------------------------------------------------------------------------------

Stacktraces
There is no Action mapped for namespace / and action name echo. - [unknown location] 
    com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:177)
    org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:61)
    org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:47)
    org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:458)
    org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)
    org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    java.lang.Thread.run(Unknown Source)

The java Action class :

package test.action;

import java.util.ArrayList;
import java.util.List;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

@ParentPackage( value = "showcase")
public class JsonSample extends ActionSupport {

      private static final long   serialVersionUID = -2223948287805083119L;
      private List<String>        languageList;
      private List<String>        reloadList;
      private String              language;

      @Actions( {
        @Action(value = "/jsonsample", results = {
          @Result(name = "success", type = "json")
        })
      })
      public String execute()
      {


        languageList = new ArrayList<String>();

        languageList.add("Java");
        languageList.add("PHP");
        languageList.add("C#");

        reloadList = new ArrayList<String>();
        if (language != null && language.equalsIgnoreCase("Java"))
        {
          reloadList.add("Struts2");
          reloadList.add("MyFaces");
          reloadList.add("Tapestry");
        }
        else if (language != null && language.equalsIgnoreCase("PHP"))
        {
          reloadList.add("CakePHP");
          reloadList.add("Symfony");
          reloadList.add("Zend");
        }
        else if (language != null && language.equalsIgnoreCase("C#"))
        {
          reloadList.add("NStruts");
          reloadList.add("ProMesh.NET");
          reloadList.add("Websharp");
        }

        return SUCCESS;
      }

      public String getJSON()
      {
        return execute();
      }

      public List<String> getLanguageList()
      {
        return languageList;
      }

      public List<String> getReloadList()
      {
        return reloadList;
      }

      public void setLanguage(String language)
      {
        this.language = language;
      }

    public String getLanguage() {
        return language;
    }

    public void setLanguageList(List<String> languageList) {
        this.languageList = languageList;
    }

    public void setReloadList(List<String> reloadList) {
        this.reloadList = reloadList;
    }

}   

The JSP page :

<s:form id="formSelectReload" action="echo" theme="simple" cssClass="yform">
        <fieldset>
            <legend>AJAX Form</legend>
            <div class="type-text">
                <label for="language">Language: </label>
                <s:url id="remoteurl" action="jsonsample"/> 
                <sj:select 
                    href="%{remoteurl}" 
                    id="language" 
                    onChangeTopics="reloadsecondlist" 
                    name="language" 
                    list="languageList" 
                    listKey="myKey" 
                    listValue="languageList" 
                    emptyOption="true" 
                    headerKey="-1" 
                    headerValue="Please Select a Language"
                />
            </div>
            <div class="type-text">
                <label for="echo">Framework: </label>
                <s:url id="remoteurl" action="jsonsample"/> 
                <sj:select 
                    href="%{remoteurl}" 
                    id="selectWithReloadTopic" 
                    formIds="formSelectReload" 
                    reloadTopics="reloadsecondlist" 
                    name="echo" 
                    list="reloadList" 
                    emptyOption="true" 
                    headerKey="-1" 
                    headerValue="Please Select a Framework"
                />
            </div>
            <div class="type-button">
                <sj:submit 
                    id="submitFormSelectReload"
                    targets="result" 
                    value="AJAX Submit" 
                    indicator="indicator" 
                    button="true"
                    />
                    <img id="indicator" 
                        src="images/indicator.gif" 
                        alt="Loading..." 
                        style="display:none"
                    />
            </div>
        </fieldset>
    </s:form>

When I deleted action="echo" from the form, I had no more error but as a result I've got kind of inclusion shown in the picture. When I click on Ajax Submit, instead of that I get the selected option in the result, I get the form in the result div. Thank you so much again.

enter image description here

Community
  • 1
  • 1
  • It's hard to tell what's wrong if I can't see your form code and your `struts.xml`? – nmc Aug 02 '12 at 01:25
  • Thank you. I've done an update, and so I added the form and the Action class. –  Aug 02 '12 at 01:42
  • While this is related to your original question, I think you've gotten away from it and may need to post a separate question... I also can't see how the screenshot you posted goes with the code you posted. But the form code you posted shows that the form should call an action named `echo`, while the action class you posted has no such action. So when you submit the form, struts can't find the action! – nmc Aug 02 '12 at 02:30
  • I read your post again and it looks like your code is form the Ajax **Doubleselect** example where as your screenshot is from the Ajax (single) select example. Note that the doubleselect example does not include the Java code/class for submitting the form, only for the list population. – nmc Aug 02 '12 at 02:41

1 Answers1

0

I think you'll find the example at http://struts.jgeppert.com/struts2-jquery-showcase/index.action more helpful as they also have the Java code. Look under Ajax Forms --> AJAX Select (Doubleselect).

The documentation also has some good code examples.

Some things to note:

The action must return JSON.

That is, the action that populates your select list as referred to in the href attribute of your <sj:select> tag has to return JSON as annotated in the example by:

@Actions({
    @Action(
    value="/jsonsample",
    results={
    @Result(name="success",type="json")
    })
})

There is also a way to specify this in struts.xml file. There should be plenty of examples of this here on Stackoverflow and around the internet.

Your second select should include formIds attribute

It specifies the form(s) whose field values should be serialized and sent with the request. This is how the action that populates your second list receives the value which is set in the first list.

nmc
  • 8,724
  • 5
  • 36
  • 68
  • Hi! Thank you a lot for the link, but I still have problems when I tried the select solution you suggested to me. Please look at the "update" in my question. Thank you again. –  Aug 01 '12 at 22:16