user2545863
user2545863

Reputation: 87

Struts2: sx:autocompleter not working

i have a sx:autocompleter tag in welcome.jsp as shown below. Although, the autocompleter action is getting invoked, the result is not rendering properly and autocomplete is not working.(i have included struts2-dojo-plugin-2.3.8.jar in WEB-INF/lib.)

(DEBUG output in browser shows following message.

DEBUG:  please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints

Details at end of question.)

Following is my code.

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%> 
................................
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
<sx:head debug="true"/>
</head>
<body>
<s:form action="sub">
.........
<s:url var="fruitsurl" action="fruits"></s:url>
<sx:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}" list="fruitsList"></sx:autocompleter>
..........
<s:submit></s:submit>
</s:form>
</body>
</html> 

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
....................
<struts>

    <package name="some-default" extends="struts-default">

    <action name="fruits" class="mypack.FruitsAction" method="display">
         <result name="success">welcome.jsp</result>
    </action>

    <action name="sub" class="mypack.SubmitAction">
        <result name="success">/success.jsp</result>
    </action>   
    </package>
</struts>

FruitsAction.java

package mypack;

import java.util.ArrayList;
import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

public class FruitsAction extends ActionSupport{
    private List fruitsList;

    public List getFruitsList() {
        return fruitsList;
    }

    public void setFruitsList(List fruitsList) {
        this.fruitsList = fruitsList;
    }

    public String display() throws Exception {

        fruitsList = new ArrayList();

        fruitsList.add("apples");
        fruitsList.add("oranges");
        fruitsList.add("mangoes");

        return SUCCESS;
    }


}

i have set debug="true" in sx:head and the following DEBUG output is shown in browser when welcome.jsp is invoked.

DEBUG:  please consider using a mimetype of text/json-comment-filtered to avoid potential security issues with JSON endpoints
DEBUG:  [SyntaxError: Syntax error]
DEBUG:<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title><script language="JavaScript" type="text/javascript">
    // Dojo configuration    djConfig = {        isDebug: true,
        bindEncoding: "UTF-8"
          ,baseRelativePath: "/Suburbs/struts/dojo/"
          ,baseScriptUri: "/Suburbs/struts/dojo/"         ,parseWidgets : false
            };</script>  <script language="JavaScript" type="text/javascript"
        src="/Suburbs/struts/dojo/struts_dojo.js"></script>
<script language="JavaScript" type="text/javascript"
        src="/Suburbs/struts/ajax/dojoRequire.js"></script>
<script language="JavaScript" type="text/javascript">
    dojo.hostenv.writeIncludes(true);</script>     
<link rel="stylesheet" href="/Suburbs/struts/xhtml/styles.css" type="text/css"/>
<script language="JavaScript" src="/Suburbs/struts/utils.js" type="text/javascript"></script>
<script language="JavaScript" src="/Suburbs/struts/xhtml/validation.js"   type="text/javascript"></script>
<script language="JavaScript" src="/Suburbs/struts/css_xhtml/validation.js" type="text/javascript"></script>
</head><body>
<form id="sub" name="sub" action="/Suburbs/sub.action" method="post">
<table class="wwFormTable"><tr>
    <td class="tdLabel"><label for="sub_autocompleter1" class="label">Fruits:</label></td>
    <td
>  <input dojoType="struts:ComboBox"  dataUrl="/Suburbs/fruits.action" id="sub_autocompleter1" name="autocompleter1" keyName="autocompleter1Key" visibleDownArrow="true" />
    <option value="apples">apples</option>
    <option value="oranges">oranges</option>
    <option value="mangoes">mangoes</option>  </select></td></tr>
<script language="JavaScript" type="text/javascript">djConfig.searchIds.push("sub_autocompleter1");</script>
<tr>
    <td colspan="2"><div align="right"><input type="submit" id="sub_0" value="Submit"/>
</div></td></tr></table></form></body></html>

please guide me as to what could be wrong with the code.

thanks,

Upvotes: 0

Views: 3869

Answers (3)

user2545863
user2545863

Reputation: 87

Follwing is the solution using jquery plugin instead of dojo plugin. (Replaced dojo plugin with struts2-jquery-plugin-3.6.0.jar in WEB-INF/lib in Eclipse.)

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%> 
<%@taglib uri="/struts-tags" prefix="s"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%> 
..................
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title> 
<sj:head jqueryui="true"/>
</head>
<body>
<s:form action="sub">
.......................
<s:url var="fruitsurl"  namespace="/autocompleter" action="getfruits"></s:url>
<sj:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}"></sj:autocompleter>
......................
<s:submit></s:submit>
</s:form>
</body>
</html>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
................
<struts>

    <package name="autocompleter" namespace="/autocompleter" extends="json-default">
    <action name="getfruits" class="mypack.FruitsAction">
         <result type="json" name="success">
            <param name="root">fruitNames</param>
         </result>
    </action>
    </package>

    <package name="some-default" extends="struts-default">  
    <action name="sub" class="mypack.SubmitAction">
        <result name="success">/success.jsp</result>
    </action>   
    </package>
</struts>

FruitsAction.java

package mypack;

import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class FruitsAction extends ActionSupport{
    private String term;

    List<String> fruitList=new ArrayList<String>();
    private String[] fruitNames;

    @Override
    public String execute() throws Exception {

        fruitList.add("apples");
        fruitList.add("mangoes");
        fruitList.add("pears");
        fruitList.add("grapes");

        if (StringUtils.isNotBlank(term)){
            ArrayList<String> subList=new ArrayList<String>();
            for (int i=0;i<fruitList.size();i++){
                if (StringUtils.startsWithIgnoreCase(fruitList.get(i), term)){
                    subList.add(fruitList.get(i));
                }
            }
            fruitNames=subList.toArray(new String[subList.size()]);
        }else{
            fruitNames=null;
        }

        return SUCCESS;
    }


    public String[] getFruitNames() {
        return fruitNames;
    }

    public void setTerm(String term) {
        this.term = term;
    }

}

in FruitsAction.java, the string 'term' is what we type into the autocompleter. the action gets invoked everytime we type in a new letter.

i referred the following urls for the above solution.

http://code.google.com/p/struts2-jquery/wiki/AutocompleterTag

http://www.coderanch.com/t/537518/Struts/struts-jquery-autocompleter

Upvotes: 0

user2545863
user2545863

Reputation: 87

Thanks to Dave Newton, i have below solution to my issue.

i modified the code to use JSON along with autocompleter and included struts2-json-plugin-2.3.8.jar in WEB-INF/lib.

providing modified code below:

welcome.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@taglib uri="/struts-tags" prefix="s"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%> 
...........
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
<sx:head/>
</head>
<body>
<s:form action="sub">
.......................
<s:url var="fruitsurl"  namespace="/autocompleter" action="getfruits"></s:url>
<sx:autocompleter label="Fruits" name="autocompleter1" href="%{fruitsurl}"></sx:autocompleter>
.......................
<s:submit></s:submit>
</s:form>
</body>
</html>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
............
<struts>

    <package name="autocompleter" namespace="/autocompleter" extends="json-default">
    <action name="getfruits" class="mypack.FruitsAction">
         <result type="json">
            <param name="root">fruits</param>
         </result>
    </action>
    </package>

    <package name="some-default" extends="struts-default">  
    <action name="sub" class="mypack.SubmitAction">
        <result name="success">/success.jsp</result>
    </action>   
    </package>
</struts>

FruitsAction.java

package mypack;

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

import com.opensymphony.xwork2.ActionSupport;

public class FruitsAction extends ActionSupport{
    Map<String,String> fruits;

    public Map<String, String> getFruits() {
        fruits=new HashMap<String,String>();

        fruits.put("apples", "ap");
        fruits.put("oranges", "or");
        fruits.put("mangoes", "ma");
        return fruits;
    }

    public void setFruits(Map<String, String> fruits) {
        this.fruits = fruits;
    }   

}

Upvotes: 0

Dave Newton
Dave Newton

Reputation: 160321

Your action needs to return JSON, as described on the Ajax and JavaScript Recipes page. (Link to previous version due to a wiki export issue). Nutshell: use the JSON plugin.

<action name="fruits" class="mypack.FruitsAction" method="display">
     <result type="json">
         <param name="root">fruits</param>
     </result>
</action>

Note that I'm explicitly setting the "root" element to your list of fruits. I'm also eliminating the redundancy in the name of the list of fruits; it's a list of fruits–its name should be fruits.

Lastly, the Dojo plugin has been deprecated for at least a couple of years now, for a variety of reasons. I'd strongly consider using something like the Struts 2 jQuery Plugin or simply using raw Dojo if you have a need for Dojo explicitly.

Upvotes: 2

Related Questions