call struts action from javascript?

Hi all

I'm having problem already discussed here quite a lot, but I have idea to solve it different way. And need to know is it possible or I'm doing mission impossible here :(

I have JSP with 2 drop down lilsts, where the second is populated according to selected value from first - that's basically my problem.

Is it possible to somehow only call my struts action which will return all needed values using javascript and onchange event handler?

I dont have any experience with javascript, and I'm trying to avoid it as much as possible at the moment.

Thanks in advance

[611 byte] By [djordjewa] at [2007-11-27 2:39:54]
# 1

You can do using onChange event.

1. Call the javascript function on 'onChange' event on dropdown one.

2. In your javascript function do the following:

<script type="text/javascript">

function myFunction(){

document.myForm.action = 'action.do';

document.myForm.submit();

}

</script>

3. Once your javascript is executed and your form is submitted; you are in your action class, where you can fetch the corresponding data, populate the second dropdown and redirect to the same page.

A better approach for this problem could be to use AJAX, but again it involves a lot of javaScript implementation.

SirG

SirGenerala at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2
Thanks SirI'm going to try this now, might be back with few more questions if you dont mind, I'm complete beginner in javascript
djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

Problems, as I expected :(

This is part of my JSP code:

<td>

<html:select onchange="populate()" property="selectedCol">

<html:optionsCollection property="colorsList" label="col.color" value="col.color"/>

</html:select>

</td>

<script language="javascript" type="text/javascript">

<!--

function populate(){

document.NOTSUREWHATGOESHERE.action = 'myApp/loadShowProduct.do';

document.NOTSUREWHATGOESHERE.submit();

}

//-->

</script>

Could anyone please clear this a bit to me? I'm not that lazy, but dont have time to go on javascript in details right now.

djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

well as far your requirement is concern if at all you are planning to implement AJAX try to use the below link which might be of some help...

http://www.it-eye.nl/weblog/2005/12/13/ajax-in-struts-implementing-dependend-select-boxes/

However,I somehow feel there are few loopholes in the author's approach...

i advice to use XmlHttpRequest.reponseXML property there.

However, i've mentioned a sample code snippet for you reference.

XML Response Pattern :

======================

<? xml version="1.1" ?>

<dropdown>

<option>

<val>CUSTOMIZED_VALUE</val>

<text>CUSTOMIZED_VALUE</text>

</option>

.........

.........

.........

.........

</dropdown>

Sample.jsp:

===========

<%@page language="java" %>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Automatic Drop-Down Updation</title>

<script language="javascript">

// Global Variable for XmlHttp Request Object

var xmlhttp

// Timer Variables

var c = 0

var t

/* A function which calls a servlet named AjaxServlet to get XmlData using XmlHttpObject */

function refreshCombo(txt){

xmlhttp = null

// code for initializing XmlHttpRequest Object On Browsers like Mozilla, etc.

if (window.XMLHttpRequest){

xmlhttp = new XMLHttpRequest()

}

// code for initializing XmlHttpRequest Object On Browsers like IE

else if (window.ActiveXObject) {

xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")

}

if (xmlhttp != null){

// Setting the Action url to get XmlData

url = "dropdown.do?count="+txt;

// Course of Action That Should be Made if their is a change in XmlHttpRequest Object ReadyState NOTE : it is 4 when it has got request from CGI

xmlhttp.onreadystatechange = getResponseAction;

// Open the Request by passing Type of Request & CGI URL

xmlhttp.open("GET",url,true);

// Sending URL Encoded Data

xmlhttp.send(null);

}

else{

// Only Broswers like IE 5.0,Mozilla & all other browser which support XML data Supports AJAX Technology

// In the Below case it looks as if the browser is not compatiable

alert("Your browser does not support XMLHTTP.")

}

}

/* Used for verifing right ReadyState & Status of XmlHttpRequest Object returns true if it is verified */

function verifyReadyState(obj){

// As Said above if XmlHttp.ReadyState == 4 then the Page Has got Response from WebServer

if(obj.readyState == 4){

// Similarly if XmlHttp.status == 200 it means that we have got a Valid response from the WebServer

if(obj.status == 200){

return true

}

else{

alert("Problem retrieving XML data")

}

}

}

/* Action that has to take place after getting reponse */

function getResponseAction(){

// Verifying State & Status

if(verifyReadyState(xmlhttp) == true){

// Building a DOM parser from Response Object

var response = xmlhttp.responseXML.documentElement

// Deleting all the Present Elements in the Drop-Down Box

drRemove()

// Checking for the Root Node Tag

var x = response.getElementsByTagName("option")

var val

var tex

var optn

for(var i = 0;i < x.length; i++){

optn = document.createElement("OPTION")

var er

// Checking for the tag which holds the value of the Drop-Down combo element

val = x[i].getElementsByTagName("val")

{

try{

// Assigning the value to a Drop-Down Set Element

optn.value = val[0].firstChild.data

} catch(er){

}

}

// Checking for the tag which holds the Text of the Drop-Down combo element

tex = x[i].getElementsByTagName("text")

{

try{

// Assigning the Text to a Drop-Down Set Element

optn.text = tex[0].firstChild.data

} catch(er){

}

}

// Adding the Set Element to the Drop-Down

document.SampleForm.SampleCombo.options.add(optn)

}

}

}

/* Function removes all the elements in the Drop-Down */

function drRemove(){

var x = document.SampleForm.SampleCombo

for(var i = document.SampleForm.SampleCombo.length - 1 ; i >= 0 ; i--){

x.remove(i)

}

}

</script>

</head>

<body onload="syncCount()">

<pre> <h1>Refresh Drop-Down <div id='txt'> </div> </h1></pre>

<form name="SampleForm">

<!-- Drop Down which has country list -->

<select name="x" onchange="refreshCombo(this.value)">

<option value="1">United States</option>

<option value="2">United Kingdom</option>

<option value="3">United Arab Emriates</option>

................

................

</select>

<!-- Drop Down which is dependent on Country Drop down get list of states -->

<select name="SampleCombo">

<option value="-1">Pick One</option>

</select>

</form>

</body>

</html>

struts-config.xml:

==================

<action-mappings>

<action path="/dropdown" type="com.controlleraction.AjaxActionClass">

<forward name="error" path="/error.jsp"/>

</action>

</action-mappings>

AjaxActionClass.java:

=====================

package com.controlleraction;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionErrors;

import org.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

import org.apache.struts.action.ActionMapping;

public class AjaxActionClass extends DispatchAction {

public ActionForward execute( ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {

String req = new String("");

try{

req = request.getParameter("count");

} catch(Exception exp){

}

if(!req.equals("")){

response.setContentType("text/xml");

response.setHeader("Pragma","no-cache");

response.setHeader("Cache-Control","no-cache,post-check=0,pre-check=0");

PrintWriter out = response.getWriter();

/*a sample bean where we trying to call a service from Model*/

com.Biz.XmlBean xml = new XmlBean();

String buffer = xml.getXmlData(req);

if(xml.close() == true && buffer.equals("") == false)

out.write(buffer);

return(null);

} else {

return new ActionForward("error");

}

}

}

XmlBean.java:

=============

/*

* XmlBean.java

*

*/

import java.sql.*;

import java.util.*;

import java.io.*;

/**

*

* @author RaHuL

*/

public class XmlBean {

private Connection con = null;

private PreparedStatement pstmt = null;

private ResultSet rs = null;

// Setting CLASSURL path to TYPE I Driver

private String CLASSURL = "sun.jdbc.odbc.JdbcOdbcDriver";

/* Specifing CONNECTION PATH to a DSN named TestDsn

* Please Make Sure you create a DSN Named TestDsn to your database which holds EMP table

*/

private String CONNECTIONURL = "jdbc:odbc:TestDsn";

boolean IS_ESTABLISHED = false;

/** Creates a new instance of XmlBean and also establishes DB Connections */

public XmlBean() {

try{

Class.forName(CLASSURL);

con = DriverManager.getConnection(CONNECTIONURL,"admin","");

IS_ESTABLISHED = true;

} catch(SQLException sqe){

sqe.printStackTrace();

} catch(Exception exp){

exp.printStackTrace();

}

}

/* Generates XmlData For the Business Logic Specified */

public String getXmlData(String req){

String XmlBuffer = new String("");

if(IS_ESTABLISHED == true){

try{

pstmt = con.prepareStatement("SELECT stateid,statename FROM STATE_TABLE where countryid = ?");

pstmt.setString(1,req);

rs = pstmt.executeQuery();

if(rs != null){

XmlBuffer = XmlBuffer + "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>";

XmlBuffer = XmlBuffer + "<!-- Edited by Rahul Sharma -->";

// Root Node

XmlBuffer = XmlBuffer + "<dropdown>";

while(rs.next()){

String value = rs.getString(1);

String text = rs.getString(2);

// Sub-root Node

XmlBuffer = XmlBuffer + "<option>";

// node which holds value of drop-down combo

XmlBuffer = XmlBuffer + "<val>"+value+"</val>";

// node which holds text for drop-down combo

XmlBuffer = XmlBuffer + "<text>"+text+"</text>";

XmlBuffer = XmlBuffer + "</option>";

}

XmlBuffer = XmlBuffer + "</dropdown>";

}

}catch(SQLException sqe){

sqe.printStackTrace();

} catch(Exception exp){

exp.printStackTrace();

}

}

return(XmlBuffer);

}

/* Closes the DB Connection Conmpletely */

public boolean close(){

if(IS_ESTABLISHED == true){

try{

pstmt.close();

con.close();

return(true);

} catch(SQLException sqe){

sqe.printStackTrace();

} catch(Exception exp){

exp.printStackTrace();

}

}

return(false);

}

}

NOTE: I understand i'm not completely coded things as per proper coding standards.please execuse me for that as this example was just given to enable user to learn how XmlHttpRquest,reponseXML

can be used for better purposes instead of devising manual parsing.

where i've used XmlHttpResponse pattern to be in XML. you may make use of other practices like JSON & so on depending on your requirement..

and and if you are more instrested in integrating Struts with AJAX using few frameworks & customized tag based support please go though the below link.

http://struts.sourceforge.net/ajaxtags/index.html

Hope that might help :)

REGARDS,

RaHuL

RahulSharnaa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
uff, I'll have something to work on I guessthanksbtw, could anyone give me a small comment on piece of code I posted in my previous post?
djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

I'll try to explain my idea little bit closer.

What I've managed to work out so far is following:

1.when jsp page is loaded for the first time (before any choice is made in select box), dropdown1 list is loaded of course,

2.dropdown2 list is loaded for first option from dropdown1 list.

3.This is all done in my action class, which populates dropdown1 list, and as requested value from dropdown1 list is null initially, I thought that maybe populating dropdown2 list for with values corresponding to first option from dropdown1 list automatically is not that bad idea.

4. "all I need" now is to call my action class when dropdown1 list selection is changed - requested value from 3. wont be null anymore, and it should be easy to reload my page with corresponding values.

Once again, is this possible to do this way?

Message was edited by:

djordjew

djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

After trying this

<td>

<html:select styleId="firstBox" onchange="populate()" property="selectedCol">

<html:optionsCollection property="colorsList" label="col.color" value="col.color"/>

</html:select>

</td>

<script language="javascript" type="text/javascript">

<!--

function populate(){

firstBox=document.getElementById("firstBox");

document.firstBox.action="loadShowProduct.do";

document.firstBox.submit();

}

//-->

</script>

I'm getting following error:

'document.firstBox' is null or not an object

Any idea what is happening?

Message was edited by:

djordjew

djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

> After trying this

>

> > <td>

> <html:select styleId="firstBox" onchange="populate()"

> property="selectedCol">

>

>

> <html:optionsCollection property="colorsList"

> label="col.color" value="col.color"/>

>

> <script language="javascript" type="text/javascript">

>

> <!--

>

> yId("firstBox");

> document.firstBox.action="loadShowProduct.do";

> document.firstBox.submit();

> }

> //-->

> /script>

>

> I'm getting following error:

>

> 'document.firstBox' is null or not an

> object

My friend action is a property for HTML form not for a form element like a select box

therefore

<html:form styleId="firstForm">

................................

................................

<td>

<html:select styleId="firstBox" onchange="populate()"

property="selectedCol">

<html:optionsCollection property="colorsList"

label="col.color" value="col.color"/>

</html:select>

</td>

...........................

...........................

</html:form>

<script language="javascript" type="text/javascript">

function populate(){

firstBox = document.getElementById("firstForm");

firstBox.action = "loadShowProduct.do";

firstBox.submit();

}

</script>

should help you

REGARDS,

RaHuL

RahulSharnaa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9
thanks mate, this helped
djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10
heh wat abt the duke stars you assigned... ?You may assign it to one or distribute it accordingly...N makes sure you assign those to the once whove helped.
RahulSharnaa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11
of courseI thought I've already done that though
djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 12
Is your problem solved? Action is associated with a html form and not for a particular component.SirG
SirGenerala at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 13
yes, thanks guys
djordjewa at 2007-7-12 3:02:17 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...