Thursday 31 March 2011

Struts2 JQuery AjaxFORMS-4

Here comes some button set examples. It is so simple that it can not be explained. The AJAX-JSON call has to be pondered a bit.

The AJAX submit activates the jsonsample action. the data structures that are defined in the jsonsample and updated in the execute method can be accessed at AjaxForms10.jsp's
...
<sj:checkboxlist
...
list="languageList"
...
So, when the JsonSample.java works the list of the checkbox is set.

struts.xml has the below entry for jsonsample:
...
<action name="jsonsample" class="ARS.JsonSample" method="execute">
<result type="json"></result>
</action>
...

The full code is below:

AjaxForms10.jsp
---------------
<%--
Buttonset / Checkboxes

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
Buttonset that was populated from a List with String values.
<s:form id="form" action="echo" theme="xhtml">
<sj:checkboxlist
id="checkboxbuttonset"
tooltip="Choose your Friends"
label="Friends"
list="{'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}"
name="echo"/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>
<br/>
Buttonset that was populated from AJAX JSON Result.
<s:form id="form2" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample"/>
<sj:checkboxlist
href="%{remoteurl}"
id="remoteCheckboxlist"
name="echo"
list="languageList"
label="Language"
/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/></body>
</html>

JsonSample.java
---------------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package ARS;

import com.opensymphony.xwork2.Action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class JsonSample extends ActionSupport{

private static final long serialVersionUID = -2223948287805083119L;
private List<String> languageList;
private List<ListValue> languageObjList;
private Map<String, String> languageMap;

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

languageList = new ArrayList<String>();
languageObjList = new ArrayList<ListValue>();
languageMap = new HashMap<String, String>();

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

languageMap.put("J", "Java");
languageMap.put("P", "PHP");
languageMap.put("C", "C++");

languageObjList.add(new ListValue("J", "Java"));
languageObjList.add(new ListValue("P", "PHP"));
languageObjList.add(new ListValue("C", "C++"));

return SUCCESS;
}

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

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

public Map<String, String> getLanguageMap()
{
return languageMap;
}

public List<ListValue> getLanguageObjList()
{
return languageObjList;
}

public class ListValue {
private String myKey;
private String myValue;

public ListValue(String myKey, String myValue) {
super();
this.myKey = myKey;
this.myValue = myValue;
}

public String getMyKey()
{
return myKey;
}

public void setMyKey(String myKey)
{
this.myKey = myKey;
}

public String getMyValue()
{
return myValue;
}

public void setMyValue(String myValue)
{
this.myValue = myValue;
}
}
}

Almost the same...

AjaxForms11.jsp
---------------
<%--
Buttonset / Radio Buttons

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<strong>Result Div :</strong>
<div id="formResult" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<strong>Buttonset that was populated from a List with String values.</strong>
<s:form id="form" action="echo" theme="simple">
<label for="echo">Choose your Friend: </label>
<sj:radio
id="radiobuttonset"
list="{'Patrick', 'Jason', 'Jay', 'Toby', 'Rene'}"
name="echo"
onChangeTopics="submitForm1"
/>
<br/>
<sj:submit
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitForm1"
cssStyle="display:none;"
/>
</s:form>
<br/>
<strong>Buttonset that was populated from AJAX JSON Result with onChangeTopic.</strong>
<s:form id="form2" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample"/>
<sj:radio
href="%{remoteurl}"
id="remoteRadiobuttons"
name="echo"
list="languageMap"
label="Language"
onChangeTopics="submitForm2"
/>
<sj:submit
id="form2button"
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitForm2"
cssStyle="display:none;"
/>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</html>

AJAX select examples.

AjaxForms12.jsp
---------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formSelectOne" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a String List</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo"
name="echo"
list="languageList"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result1"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div 1 :</strong>
<div id="result1" class="result ui-widget-content ui-corner-all">Submit form above.</div>

<s:form id="formSelectTwo" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a Map</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo2"
name="echo"
list="languageMap"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result2"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..." style="display:none"
/>
</div>
</fieldset>
</s:form>

<strong>Result Div 2 :</strong>
<div id="result2" class="result ui-widget-content ui-corner-all">Submit form above.</div>

<s:form id="formSelectThree" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form populated by a List with Objects</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="jsonsample"/>
<sj:select
href="%{remoteurl}"
id="echo3"
name="echo"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-button">
<sj:submit
targets="result3"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div 3 :</strong>
<div id="result3" class="result ui-widget-content ui-corner-all">Submit form above.</div>
</body>
</html>

This example uses jsonsample2. There is a slight difference with the previous one here. The difference comes because of the levels. The second select has to be set according to the first selection. This is reflected in the JsonSample2.java code.

AjaxForms13.jsp
---------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
Reload example with two select boxes.
<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="jsonsample2"/>
<sj:select
href="%{remoteurl}"
id="language"
onChangeTopics="reloadsecondlist"
name="language"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
/>
</div>
<div class="type-text">
<label for="echo">Framework: </label>
<s:url id="remoteurl" action="jsonsample2"/>
<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>
<br/>
Reload example with one select box and an buttonset.
<s:form id="formSelectCheckBox" action="echo" theme="xhtml">
<s:url id="remoteurl" action="jsonsample2"/>
<sj:select
href="%{remoteurl}"
id="languageSelect"
onChangeTopics="reloadcheckboxes"
name="language"
list="languageObjList"
listKey="myKey"
listValue="myValue"
emptyOption="true"
headerKey="-1"
headerValue="Please Select a Language"
label="Language"
required="true"
/>
<s:url id="remoteurl" action="jsonsample2"/>
<sj:checkboxlist
href="%{remoteurl}"
id="frameworkCheckboxes"
formIds="formSelectCheckBox"
reloadTopics="reloadcheckboxes"
name="echo"
list="reloadList"
label="Framework"
required="true"
onChangeTopics="submitCheckboxForm"
/>
<sj:submit
id="submitFormSelectCheckBox"
listenTopics="submitCheckboxForm"
targets="result"
value="AJAX Submit"
indicator="indicator2"
cssStyle="display : none;"
/>
</s:form>
<img id="indicator2"
src="images/indicator.gif"
alt="Loading..."
style="display:none"
/>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">Submit a form.</div>
</body>
</html>

JsonSample2.java
----------------
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package ARS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;


public class JsonSample2 extends ActionSupport {

private static final long serialVersionUID = -2223948287805083119L;
private static final Log log = LogFactory.getLog(JsonSample2.class);
private List<String> languageList;
private List<ListValue> languageObjList;
private Map<String, String> languageMap;
private List<String> reloadList;
private String language;

public String execute()
{

log.info("build json lists language : " + language);

languageList = new ArrayList<String>();
languageObjList = new ArrayList<ListValue>();
languageMap = new HashMap<String, String>();

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

languageMap.put("J", "Java");
languageMap.put("P", "PHP");
languageMap.put("C", "C#");

languageObjList.add(new ListValue("J", "Java"));
languageObjList.add(new ListValue("P", "PHP"));
languageObjList.add(new ListValue("C", "C#"));

reloadList = new ArrayList<String>();
if (language != null && language.equalsIgnoreCase("J"))
{
reloadList.add("Struts2");
reloadList.add("MyFaces");
reloadList.add("Tapestry");
}
else if (language != null && language.equalsIgnoreCase("P"))
{
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 Map<String, String> getLanguageMap()
{
return languageMap;
}

public List<ListValue> getLanguageObjList()
{
return languageObjList;
}

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

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

ListValue.java
--------------
/**
*
*/
package ARS;

public class ListValue {
private String myKey;
private String myValue;

public ListValue(String myKey, String myValue) {
super();
this.myKey = myKey;
this.myValue = myValue;
}

public String getMyKey()
{
return myKey;
}

public void setMyKey(String myKey)
{
this.myKey = myKey;
}

public String getMyValue()
{
return myValue;
}

public void setMyValue(String myValue)
{
this.myValue = myValue;
}
}

Struts2 JQuery AjaxFORMS-3

There is a text area in this example. You first write something into the text area and then you push the submit button. The AJAX call copies this text into the result area.

1. The text area takes its default value from the
...
<s:url id="remoteurl" action="ajax1"/>
...

in the struts.xml:
...
<action name="ajax1">
<result>/Ajax1.jsp</result>
</action>
...

Ajax1.jsp:
----------
testARS
(it is composed of only a single word text)

The submit button targets:
...
<sj:submit
targets="result"
...
the result area is at the bottom:
...
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
...

The submit button trigs the action echo:
...
<s:form id="formTextarea" action="echo" theme="simple" cssClass="yform">
...

in the struts.xml:
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
The code for the action echo lies in the echo.java, listed below under the
AjaxForms7.jsp's full code:

AjaxForms7.jsp
--------------
<%--
AJAX Textarea


--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>

<s:form id="formTextarea" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="remoteurl" action="ajax1"/>
<sj:textarea
href="%{remoteurl}"
id="echo"
name="echo"
rows="10"
cols="80"
effect="highlight"
effectDuration="1500"
loadingText="Loading content of textarea ..."
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
effect="slide"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>
<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

Echo.java
---------
package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;

public class Echo extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Echo.class);

private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

The result of the ecgo action is directed to echo.jsp:

echo.jsp
--------
<%@ taglib prefix="s" uri="/struts-tags"%>
<p>Echo : <s:property value="echo" escape="%{escape}"/></p>

echo.jsp puts "Echo :" and then the value of the echo request variable
(echo field on the JSP). The output of the echo.jsp is targeted to the result field on the AjaxForms7.jsp

AjaxForms8.jsp has not much new, only the text area is resizable.

AjaxForms8.jsp
--------------
<%--
AJAX Text Area / Resizable
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formTextareaResize" action="simpleecho" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<sj:textarea
resizable="true"
resizableGhost="true"
resizableHelper="ui-state-highlight"
id="echo"
name="echo"
rows="4"
cols="80"
onChangeTopics="submitThisForm"
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit"
indicator="indicator"
button="true"
listenTopics="submitThisForm"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..." style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

AjaxForms8.jsp has not much new, only this time it is a text field that is resizable.

AjaxForms9.jsp
--------------
<%--
AJAX Textfield / Resizable

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<s:form id="formTextfieldResize" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:url id="urlsimpleecho" action="simpleecho">
<s:param name="echo">remote content for textfield!</s:param>
</s:url>
<sj:textfield
href="%{urlsimpleecho}"
resizable="true"
resizableGhost="true"
resizableHelper="ui-state-highlight"
resizableMaxHeight="30"
effect="blind"
effectDuration="1500"
effectOptions="{
mode: 'show'
}"
id="echo"
name="echo"
loadingText="Loading content of textfield ..."
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
effect="highlight"
effectDuration="1500"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<img id="indicator"
src="images/indicator.gif"
alt="Loading..."
style="display:none"/>
</div>
</fieldset>
</s:form>

<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">
Enter some text in the Textarea above.
</div>
</body>
</html>

Struts2 JQuery AjaxFORMS-2

AjaxForms5.jsp is a form example with validation. This example does not work in the struts2-jquery-showcase-2.5.0 version. There is a fix note from Herr Geppert on the internet about this. Some javascript has been changed at struts2-jquery-showcase-2.5.3 version. You have to add the utils.js and validation.js references also as seen below.

There is a difficulty about struts2-jquery-showcase-2.5.3. It does not run when compiled. The showcase related with the grid works though. So I copied the lib from the grid showcase of the same version. It worked.

The form activates the login action at the AJAX submit event. The AJAX submit event targets 'result' div with pulsate effect. There are two text fields, loginuser and loginpassword. These are handled at Login.java

Error processing can be done both in the Login.java or with xml validation.

AjaxForms5.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript" src="${pageContext.request.contextPath}/struts/utils.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/struts/xhtml/validation.js"></script>
</head>
<body>
<strong>Result Div :</strong>
<div id="result" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<s:form id="formValidate" action="login" theme="xhtml">
<s:textfield
id="loginuser"
name="loginuser"
label="User"
required="true"
/>
<s:textfield
id="loginpassword"
name="loginpassword"
label="Password (test)"
required="true"
/>
<sj:submit
targets="result"
button="true"
validate="true"
effect="pulsate"
value="Submit"
indicator="indicator"
/>
<input type="hidden" id="struts.enableJSONValidation" name="struts.enableJSONValidation" value="true" />
</s:form>
</body>
</html>

Login.java
----------
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.opensymphony.xwork2.ActionSupport;

public class Login extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Login.class);

private String loginuser;
private String loginpassword;
private String echo;

public String execute() throws Exception
{
echo = "Welcome " + loginuser;
log.info(echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public String getLoginuser()
{
return loginuser;
}

public void setLoginuser(String loginuser)
{
this.loginuser = loginuser;
}

public String getLoginpassword()
{
return loginpassword;
}

public void setLoginpassword(String loginpassword)
{
this.loginpassword = loginpassword;
}
// public void validate(){
//
// if ( loginuser.length() == 0 ){
// addFieldError( "loginuser", "loginuser is required." );
// }
//
// if ( loginpassword.length() == 0 ){
// addFieldError( "loginpassword", "loginpassword is required." );
// }
// }
}


Login-validation.xml
--------------------
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldname">loginuser</param>
<message>loginuser is required.</message>
</validator>
<validator type="requiredstring">
<param name="fieldname">loginpassword</param>
<message>loginpassword is required.</message>
</validator>
</validators>

AjaxForms6.jsp is a custom Validation example. It still uses some js substructure though. The example works without problem.

AjaxForms6.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript">
$(document).ready( function() {
$.subscribe('removeErrors', function(event,data) {
$('.errorLabel').html('').removeClass('errorLabel');
$('#formerrors').html('');
});
});

function customeValidation(form, errors) {

//List for errors
var list = $('#formerrors');

//Handle non field errors
if (errors.errors) {
$.each(errors.errors, function(index, value) {
list.append(''+value+'\n');
});
}

//Handle field errors
if (errors.fieldErrors) {
$.each(errors.fieldErrors, function(index, value) {
var elem = $('#'+index+'Error');
if(elem)
{
elem.html(value[0]);
elem.addClass('errorLabel');
}
});
}
}
</script>
</head>
<body>
<div id="result" class="result ui-widget-content ui-corner-all">Submit form bellow.</div>

<ul id="formerrors" class="errorMessage"></ul>
<s:form id="formValidateCustom" action="login" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Validation</legend>
<div class="type-text">
<label for="echo">User: <span id="loginuserError"></span></label>
<s:textfield
id="loginuser"
name="loginuser"
/>
</div>
<div class="type-text">
<label for="echo">Password: <span id="loginpasswordError"></span></label>
<s:textfield
id="loginpassword"
name="loginpassword"
/>
</div>
<div class="type-button">
<sj:submit
targets="result"
button="true"
validate="true"
validateFunction="customeValidation"
onBeforeTopics="removeErrors"
onSuccessTopics="removeErrors"
value="Submit"
indicator="indicator"
/>
</div>
</fieldset>
</s:form>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

Struts2 JQuery AjaxFORMS-1

I have taken these examples from Herr GEPPERT's showcase for Struts2-JQuery applications. My intention was to try whether they can work individually for specific purposes. The problem is you can not run struts2-jquery-showcase-2.5.3 as it is provided. There are missing files in the lib folder. But the same site provides a grid showcase which works. So, I copied the whole lib from there on to the original struts2-jquery-showcase-2.5.3 lib. It works now.

After fixing the lib problem, I returned back to the original problem I had. The examples for validation did not work healthily on struts2-jquery-showcase-2.5.0 which I had chosen to be 'safe'. So, I tried the new lib with my old problem, it worked. (I had seen Herr Geppert's note on a fix about this matter). There is also another small fix I had to do, which I will explain when I come to that matter.








web.xml
-------

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Basic_Struts2_Ant</display-name>
<welcome-file-list>
<welcome-file>/test.action</welcome-file>
</welcome-file-list>


<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

struts.xml
----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<constant name="struts.devMode" value="true" />

<package name="basicstruts2" extends="struts-default, json-default">
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
<action name="simpleecho" class="ARS.SimpleEcho" method="execute">
<result name="success">/simpleecho.jsp</result>
</action>
<action name="ajax1">
<result>/Ajax1.jsp</result>
</action>
<action name="jsonsample" class="ARS.JsonSample" method="execute">
<result type="json"></result>
</action>
<action name="jsonsample2" class="ARS.JsonSample2" method="execute">
<result type="json"></result>
</action>
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>
</action>
<action name="login" class="ARS.Login" method="execute">
<interceptor-ref name="jsonValidationWorkflowStack"/>
<result name = "success">/simpleecho.jsp</result>
</action>
</package>
</struts>

AjaxForms0.jsp uses an AJAX call that targets the div formResult.
There is a field named echo of which value is copied by the
action echo to the result field.
AjaxForms0.jsp
--------------
<%--
form example from the AJAX command section
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
<s:form id="form" action="echo" theme="xhtml">
Echo: <s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</s:form>

<sj:a
id="ajaxformlink"
formIds="form"
targets="formResult"
indicator="indicator"
button="true"
buttonIcon="ui-icon-gear"
>
Submit form here
</sj:a>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

The echo action trigs the echo.java of which result is fed to the result file echo.jsp. Echo.jsp is then targeted to the result field on the jsp.


Echo.java
---------
package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;

public class Echo extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Echo.class);

private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

Echo.jsp
--------
<%@ taglib prefix="s" uri="/struts-tags"%>
<p>Echo : <s:property value="echo" escape="%{escape}"/></p>


This is a simple repetition in Herr Geppert's examples. simpleecho is not simpler than echo I guess.

AjaxForms1.jsp
--------------
<%--
AJAX Forms

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
<s:form id="form" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
id="formSubmit1"
targets="formResult"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
<s:url id="simpleecho" value="/simpleecho.action"/>
<sj:submit
id="formSubmit2"
href="%{simpleecho}"
targets="formResult"
value="AJAX Submit 2"
indicator="indicator"
button="true"
/>
</div>
</fieldset>
</s:form>
</body>
</html>

SimpleEcho.java
---------------
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package ARS;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

public class SimpleEcho extends ActionSupport {

private static final long serialVersionUID = 6999864671102333041L;
private String echo;
private boolean escape = true;

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

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

Addition of effects etc cosmetic changes.

AjaxForms2.jsp
--------------
<%--
AJAX Forms with Effects

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="result"></div>
<s:form id="formEffect" action="echo" theme="xhtml">
<s:textfield id="echo" name="echo" label="Echo" value="Hello World!!!"/><br/>
<sj:submit
targets="result"
effect="slide"
effectMode="blind"
onEffectCompleteTopics="hideTarget"
value="AJAX Submit"
indicator="indicator"
button="true"
/>
</s:form>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/> </body>

</html>

AjaxForms3.jsp
--------------
<%--
AJAX Forms with Outside Button

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="result">formResult</div>
<s:form id="formOutside" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Button outside</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</div>
</fieldset>
</s:form>

<sj:submit
formIds="formOutside"
targets="result"
effect="pulsate"
value="Submit outside the Form"
indicator="indicator"
button="true"
/>
</body>
</html>

The events are interesting. It is pretty straight forward, you create the JSP and it works.

AjaxForms4.jsp
--------------
<%--
AJAX Forms with Events

--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script type="text/javascript" charset="utf-8">
$.subscribe('beforeForm', function(event,data) {
var fData = event.originalEvent.formData;
alert('About to submit: \n\n' + fData[0].value + ' to target '+event.originalEvent.options.target+' with timeout '+event.originalEvent.options.timeout );
var form = event.originalEvent.form[0];
if (form.echo.value.length < 2) {
alert('Please enter a value with min 2 characters');
event.originalEvent.options.submit = false;
}
});
$.subscribe('completeForm', function(event,data) {
alert('status: ' + event.originalEvent.status + '\n\nresponseText: \n' + event.originalEvent.request.responseText +
'\n\nThe output div should have already been updated with the responseText.');
});
$.subscribe('errorStateForm', function(event,data) {
alert('status: ' + event.originalEvent.status + '\n\nrequest status: ' +event.originalEvent.request.status);
});
</script>
</head>
<body>
<div id="result">formResult</div>
<s:form id="formevent" action="echo" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit"
timeout="2500"
indicator="indicator"
onBeforeTopics="beforeForm"
onCompleteTopics="completeForm"
onErrorTopics="errorState"
button="true"
/>
</div>
</fieldset>
</s:form>

<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>

<s:form id="formeventerror" action="file-does-not-exist.html" theme="simple" cssClass="yform">
<fieldset>
<legend>AJAX Form with Error Result</legend>
<div class="type-text">
<label for="echo">Echo: </label>
<s:textfield id="echo" name="echo" value="Hello World!!!"/>
</div>
<div class="type-button">
<sj:submit
targets="result"
value="AJAX Submit with Error"
timeout="2500"
indicator="indicator"
onBeforeTopics="beforeForm"
onCompleteTopics="completeForm"
onErrorTopics="errorState"
button="true"
/>
</div>
</fieldset>
</s:form>
</body>
</html>

Friday 25 March 2011

Struts2 - Jquery AJAX tutorial3

The AJAX with JSON example required more if not much to understand.
Let's begin from the easiest point.

The div named "result" is targeted by the AJAX call to put the
output. It is located in the body part of the AjaxTest6.JSP .
...

<div id="result" class="result ui-widget-content ui-corner-all">Click on the link below.</div>
...



The AJAX call is located in the body part of the AjaxTest6.jsp .
...
<sj:a id="ajaxjsonlink"
href="%{jsonurl}"
dataType="json"
onSuccessTopics="handleJsonResult"
indicator="indicator"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action with JSON Rsult
</sj:a>
...

It uses the jsonurl which is set to
...
<s:url id="jsonurl" action="jsonlanguages"/>
...
So the action trigged by the AJAX call lies at the struts.xml with the label "jsonlanguages":

...
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>

</action>
...

The struts entry fro jsonlanguages at the struts.xml points to the class address as
jsonlanguages.java at the ARS library. IMPORTANT: It also gives a hint about how the result should be returned. The result should be based on the parameter "languages" not the default result definition. I will further elaborate on this below.

jsonlanguages.java uses a static string array of:
...
private static String[] staticLanguages =
{
"Actionscript (Flash)",
"ABAP Objects",
"Ada",
"Aleph",
"AppleScript",
"Beta",
"BlitzMax",
//...
"Zonnon"
};

and later on it copies this string into languages array:
in the execute method (the method that works as action default).
...
private String[] languages = Jsonlanguages.staticLanguages;

public String execute() throws Exception
{
ArrayList<String> tmp = new ArrayList<String>();
for (int i = 0; i < staticLanguages.length; i++)
{
tmp.add(staticLanguages[i]);
}
languages = tmp.toArray(new String[ tmp.size()]);

return SUCCESS;
}
...

The execute method returns SUCCESS. The difficulty is: By default, the jsonlanguages action returns the staticLanguages if we say:
...
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"/>

</action>
...

In order to return the languages we must indicate it as base to the parameter:
...
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>

</action>
...


This is done somewhat different by Herr GEPPERT as he has chosen to do things in the
convention fashion globally.

Here is the full working code.

AjaxTest6.jsp
-------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
<script>
$.subscribe('handleJsonResult', function(event,data) {
$('#result').html("<ul id='languagesList'></ul>");
var list = $('#languagesList');
$.each(event.originalEvent.data, function(index, value) {
list.append('<li>'+value+'</li>\n');
});
});
</script>
</head>
<body>

<div id="result" class="result ui-widget-content ui-corner-all">Click on the link below.</div>
<s:url id="jsonurl" action="jsonlanguages"/>

<sj:a id="ajaxjsonlink"
href="%{jsonurl}"
dataType="json"
onSuccessTopics="handleJsonResult"
indicator="indicator"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action with JSON Rsult
</sj:a>
<img id="indicator" src="./images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

struts.xml
-----------
...
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>

</action>
...


jsonlanguages.java
------------------
package ARS;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import com.opensymphony.xwork2.ActionSupport;

public class Jsonlanguages extends ActionSupport {

private static final long serialVersionUID = -3066791113091431706L;
private static String[] staticLanguages =
{
"Actionscript (Flash)",
"ABAP Objects",
"Ada",
"Aleph",
"AppleScript",
"Beta",
"BlitzMax",
// ...
// "XOTcl",
// ...
"Zonnon"
};
private String[] languages = Jsonlanguages.staticLanguages;

public String execute() throws Exception
{
ArrayList<String> tmp = new ArrayList<String>();
for (int i = 0; i < staticLanguages.length; i++)
{
tmp.add(staticLanguages[i]);
}
languages = tmp.toArray(new String[ tmp.size()]);

return SUCCESS;
}

public String[] getLanguages()
{
return languages;
}
}

The AJAX call trigs "handleJsonResult" via:
...
onSuccessTopics="handleJsonResult"
...

HandleJsonResult simply buids up a list;
first creates the ist named "languagesList" and then
adds each value in the "event.originalEvent.data" using the
each iterator.

$.subscribe('handleJsonResult', function(event,data) {
$('#result').html("<ul id='languagesList'></ul>");
var list = $('#languagesList');
$.each(event.originalEvent.data, function(index, value) {
list.append('<li>'+value+'</li>\n');
});
});
</script>

This list is placed into the "targets" area of tha AJAX call, namely the div named "result".

Kind regards. Enjoy!

Ali R+

Struts2 - Jquery AJAX tutorial2

AjaxTest3.jsp is an example of form AJAX action.
AjaxTest3.jsp
-------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="formResult">formResult</div>
<s:form id="form" action="echo" theme="xhtml">
Echo: <s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</s:form>

<sj:a
id="ajaxformlink"
formIds="form"
targets="formResult"
indicator="indicator"
button="true"
buttonIcon="ui-icon-gear"
>
Submit form here
</sj:a>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
</body>
</html>

The action echo is trigged when the form is submitted.
The echo action is defined at the struts.xml as

...
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
...

It's source is at the ARS lib's echo.jsp member.
/ARS/echo.jsp
-------------
package ARS;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionSupport;

public class Echo extends ActionSupport {

private static final long serialVersionUID = 7968544374444173511L;
private static final Log log = LogFactory.getLog(Echo.class);

private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}

public String getEcho()
{
return echo;
}

public void setEcho(String echo)
{
this.echo = echo;
}

public boolean isEscape()
{
return escape;
}

public void setEscape(boolean escape)
{
this.escape = escape;
}
}

Now, let's concentrate on the form of AjaxTest3.jsp:
...
<s:form id="form" action="echo" theme="xhtml">
Echo: <s:textfield id="echo" name="echo" value="Hello World!!!"/><br/>
</s:form>
...

This form has a textfield named echo with a default value.
If we look at the ARS.echo once again:

public class Echo extends ActionSupport {
...
private String echo;
private boolean escape = true;

public String execute() throws Exception
{

log.info("Echo : " + echo);

return SUCCESS;
}
...

The execute method takes this default value and adds "Echo :" to its
front and uses its setter and getters to change this value.

struts.xml has:
...
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
It returns echo.jsp...

echo.jsp
--------
<%@ taglib prefix="s" uri="/struts-tags"%>
<p>Echo : <s:property value="echo" escape="%{escape}"/></p>

Now, it is clearer how it takes the echo and returns it back to
AjaxTest3 which targets this output to
...
targets="formResult"
...

namely the div named formResult.

AjaxTest4.jsp uses AJAX calls with events. The events are triggered
by the:
...
onClickTopics="beforeLink"
onCompleteTopics="completeLink"
onErrorTopics="errorStateLink"
...
handlers.

The events are defined in the subscribing section in the
script part at the beginning. Namely:
...
<script type="text/javascript" charset="utf-8">
//$(document).ready(function() {
$.subscribe('beforeLink', function(event,data) {
alert('Before request ');
$('#result').html('Loading ...');
});
...

I have added file-does-not-exist1.html so that you can rename
and play with it.
The complete code follows:

AjaxTest4.jsp
-------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>

<script type="text/javascript" charset="utf-8">
//$(document).ready(function() {
$.subscribe('beforeLink', function(event,data) {
alert('Before request ');
$('#result').html('Loading ...');
});
$.subscribe('completeLink', function(event,data) {
$('#result').append('<br/><br/><strong>Completed request '+event.originalEvent.request.statusText+' completed with '+event.originalEvent.status+ '.</strong><br/>Status: '+event.originalEvent.request.status);
});
$.subscribe('errorStateLink', function(event,data) {
$('#result').html('<br/><br/><strong>Error request '+event.originalEvent.request.statusText+' completed with '+event.originalEvent.status+ '.</strong><br/>Status: '+event.originalEvent.request.status);
});
//});
</script>
</head>
<body>
<s:url id="ajax" value="/ajax1.action"/>
<div id="result" name="result">result</div>
<div id="result2" name="result2">result</div>
<sj:a
id="ajaxlink"
href="%{ajax}"
indicator="indicator"
targets="result"
onClickTopics="beforeLink"
onCompleteTopics="completeLink"
effect="pulsate"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action
</sj:a>
<img id="indicator" src="images/indicator.gif" alt="Loading..." style="display:none"/>
<br/>
<br/>
<sj:a
id="ajaxlink2"
href="file-does-not-exist.html"
indicator="indicator2"
targets="result"
onClickTopics="beforeLink"
onCompleteTopics="completeLink"
onErrorTopics="errorStateLink"
effect="pulsate"
effectDuration="1500"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Error Action
</sj:a>
<img id="indicator2" src="images/indicator.gif" alt="Loading..." style="display:none"/>

</body>
</html>

I added bounce effect to the highlight effect example for economy.
The AJAX function's effects can be used for highlight:
...
effect="highlight"
effectOptions="{ color : '#222222' }"
effectDuration="3000"
...

and bounce:
...
effect="bounce"
effectDuration="2200"
...

The full code follows:

AjaxTest5.jsp
-------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="result">formResult</div>
<s:url id="ajax" value="/ajax1.action"/>

<sj:a
id="ajaxlink"
href="%{ajax}"
targets="result"
effect="highlight"
effectOptions="{ color : '#222222' }"
effectDuration="3000"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action
</sj:a>
<s:url id="ajax2" value="/ajax1.action"/>

<sj:a
id="ajaxlink2"
href="%{ajax}"
indicator="indicator"
targets="result"
effect="bounce"
effectDuration="2200"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action
</sj:a>

</body>
</html>

Struts2 - Jquery AJAX tutorial1

This is a simplified, easy to understand version of AJAX events section from the STRUTS2 JQUERY PLUGIN SHOWCASE-2.5.0 of Johannes Geppert Hosted by weinfreund.de. The difference is GEPPERT has provided all the examples in the frameworks of a showcase using STRUTS2-convention, velocity, YAML, Maven and others.

My approach is to minimize the external connections, make each example independent and break the big pieces to smaller ones. Each of the pieces I provide will work alone and I will provide complete and working examples. I made a few additions when it is unavoidable.

Herr GEPPERT's showcase can easily be compiled and run without any problem. It was great fun to analyze and break down his work to smaller pieces. His work is very well written and logically documented, easy to understand but it is complex and it must be well deserved, a piece of art.

1- First things first. Create a Web application.
2- Create a lib and put everything in the showcases lib here. Put them into the CLASSPATH. I did not change the css and themes references to button and div definitions of Herr GEPPERT.
3- I put all the AJAX examples in a single application's WEB lib.
4- Of course I used the Struts.xml for all the actions because of 3.
5- Web.xml is different from Herr GEPPERT's. He uses convention and I use the classic STRUTS2.

Here are :

web.xml
---------
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Basic_Struts2_Ant</display-name>
<welcome-file-list>
<welcome-file>/test.action</welcome-file>
</welcome-file-list>


<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

struts.xml
----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<constant name="struts.devMode" value="true" />

<package name="basicstruts2" extends="struts-default, json-default">

<action name="index">
<result>/index.jsp</result>
</action>
<action name="AjaxTest">
<result>/data_server.jsp</result>
</action>
<action name="myremoteactionone">
<result>/data_server.jsp</result>
</action>
<action name="myremoteactiontwo">
<result>/data_server.jsp</result>
</action>
<action name="myremoteactionthree">
<result>/data_server.jsp</result>
</action>
<action name="myremact1">
<result>/index.jsp</result>
</action>
<action name="myremact2">
<result>/index.jsp</result>
</action>
<action name="myremact3">
<result>/index.jsp</result>
</action>
<action name="myremoteaction">
<result>/data_server.jsp</result>
</action>
<action name="ajax1">
<result>/data_server1.jsp</result>
</action>
<action name="ajax2">
<result>/data_server2.jsp</result>
</action>
<action name="ajax3">
<result>/data_server3.jsp</result>
</action>
<action name="ajax4">
<result>/data_server4.jsp</result>
</action>
<action name="echo" class="ARS.Echo" method="execute">
<result name="success">/echo.jsp</result>
</action>
<action name="jsonlanguages" class="ARS.Jsonlanguages" method="execute">
<result type="json"><param name="root">languages</param></result>

</action>
</package>

</struts>

I used a very simple data server JSP file.

data_server.jsp
---------------
<%--
Document : data_server
Created on : 19.Mar.2011, 21:10:39
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%
out.println("Hello world!");
%

Later I moved to Herr GEPPERT's approach. Namely just a few words as data in the JSP.
All four of them are the same. You can change and play with them.

data_server1.jsp
data_server2.jsp
data_server3.jsp
data_server4.jsp
----------------
test ARS

You have to right click on AjaxTest.jsp and then RUN this file to test our first example.

The first AJAX example targets a div namely div1. The related action is AjaxTest.action which can be tracked at the struts.xml to data_server.jsp which
returns "Hello World!". This phrase is written to the target div1 area.

Please note the use of the struts URL tag.

AjaxTest.jsp
------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<div id="div1">Div 1</div>
<s:url id="ajaxTest" value="/AjaxTest.action"/>
<sj:a id="link1" href="%{ajaxTest}" targets="div1"> Update Content </sj:a>
<br>
<br>
<s:url id="ajax" value="ajax1.action"/>

<sj:a id="ajaxlink"
href="%{ajax}"
targets="result"
indicator="indicator"
button="true"
buttonIcon="ui-icon-refresh"
>
Run AJAX Action
</sj:a>
<br>
<br>
<s:url id="ajax2" value="ajax1.action"/>
<sj:a id="ajaxlink2"
href="%{ajax2}"
targets="div1"
indicator="indicator2"
button="true"
buttonIcon="ui-icon-refresh"
>
Run AJAX Action2
</sj:a>



</body>
</html>

The second example AjaxTest2.jsp

AjaxTest2.jsp
--------------
<%--
Document : testAJAX
Created on : 15.Mar.2011, 20:08:02
Author : Ali Riza SARAL
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<sj:head/>
</head>
<body>
<strong>Result Div 1 :</strong>
<div id="result1" class="result ui-widget-content ui-corner-all">Click on the link bellow.</div>
<strong>Result Div 2 :</strong>
<div id="result2" class="result ui-widget-content ui-corner-all">Click on the link bellow.</div>

<s:url id="ajax" value="/ajax3.action"/>
<sj:a
id="ajaxlink"
href="%{ajax}"
targets="result1,result2"
button="true"
buttonIcon="ui-icon-gear"
>
Run AJAX Action
</sj:a>


</body>
</html>

Saturday 19 March 2011

Simple DAO Tutorial - 5

This DAO is a new version of the original one that
you can find at:
http://tekne-techne.blogspot.com/2011/01/simple-dao-tutorial-1.html

I have used this original DAO's MySQL implementation files
in the Simple CRUD with JQuery and many other examples at my blog.

The problem in the original DAO was it reorganised the DB as soon as
a record was deleted. This was caused by a wrong design
decision that each record should have a sequential id with no
ids missing in between them.

I removed this requirement in this new version of DAO with:

public Person readNextRec() throws PersonDAOSysException {
...
stmt = conn.prepareStatement("select id, firstName, lastName, "
+ " hobby from personTab where id > ? ORDER BY ID ASC LIMIT 1");
...
This is true for only HSQL and MySQL DBs. The vector 'DB' is left as
it was.

To read an in depth analysis of this package please refer to
http://tekne-techne.blogspot.com/2011/01/simple-dao-tutorial-1.html

To correct speed problems at the delete function of Simple CRUD with JQuery
you may use PersonDAOMySQLDBImpl.java of nbDAObasicARSv1.0.

I will provide a new version as such for Simple CRUD with JQuery
in the near future. Also a new master - detail on the same JSP
will follow.

Once again this for only training purposes, it is not meant for
any other.

You can download the source files from sourceforge:
http://sourceforge.net/projects/crudjquery/files/

Thursday 17 March 2011

Crud with JQuery Master-Detail 7

The data table at personList.jsp uses PersonServer.jsp.
PersonServer.jsp is a translation of PHP source provided
by Monseur Allan Jardine at
http://www.datatables.net/examples

some more explanation:
http://tekne-techne.blogspot.com/2011/02/jquery-server-processing-with-jsp-java.html



PersonServer.jsp
----------------
<%--
Document : person_server.jsp
Created on : 04.?ub.2011, 17:53:53
Author : Ali Riza SARAL
--%>

<%@page import="java.sql.Connection"%>
<%@page import="atg.taglib.json.util.*"%>
<%@page import= "java.util.*"%>
<%@page import= "java.sql.*"%>
<%@page import= "org.apache.commons.lang.*"%>


<%
class Utilities {

Utilities() {
};

String escape_string(String input) {
return StringEscapeUtils.escapeHtml(input);
}
}
%>

<%
System.out.println("test arsssssssssssssssssssssss");
Utilities util = new Utilities();
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Easy set variables
*/

/* Array of database columns which should be read and sent back to DataTables. Use a space where
* you want to insert a non-database field (for example a counter or static image)
*/
String[] aColumns = {"id", "firstname", "lastname", "hobby"};

/* Indexed column (used for fast and accurate table cardinality) */
String sIndexColumn = "id";

/* DB table to use */
String sTable = "persontab";
/* Database connection information */
String user = "root";
String password = "3391309";
String db = "persondao";
String server = "localhost";

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* If you just want to use the basic configuration for DataTables with PHP server-side, there is
* no need to edit below this line
*/

/*
* MySQL connection
*/

Connection conn = null;

try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection("jdbc:mysql://localhost/" + db,
user, password);

if (!conn.isClosed()) {
System.out.println("Successfully connected to "
+ "MySQL server using TCP/IP...");
}

} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
} finally {
// try {
// if (conn != null) {
// //conn.close();
// }
// } catch (SQLException e) {
// }
}

/*
* Paging
*/
String sLimit = "";
if (request.getParameter("iDisplayStart") != null
&& request.getParameter("iDisplayLength") != "-1") {
sLimit = "LIMIT " + util.escape_string(request.getParameter("iDisplayStart")) +
", " + util.escape_string(request.getParameter("iDisplayLength"));
}

/*
* Ordering
*/
String sOrder = "";

if (request.getParameter("iSortCol_0") != null) {
sOrder = "ORDER BY ";

for (int i = 0; i < Integer.valueOf(request.getParameter("iSortingCols")); i++) {
if (request.getParameter("bSortable_" + Integer.valueOf(request.getParameter("iSortCol_" + String.valueOf(i)))).equals("true")) {
sOrder += aColumns[Integer.valueOf(request.getParameter("iSortCol_" + String.valueOf(i)))] + " "
+ util.escape_string(request.getParameter("sSortDir_" + String.valueOf(i))) + ", ";
}
}

sOrder = sOrder.substring(0, sOrder.length()-2);
if (sOrder.equals("ORDER BY")) {
sOrder = "";
}
sOrder += " ";
}



/*
* Filtering
* NOTE this does not match the built-in DataTables filtering which does it
* word by word on any field. It's possible to do here, but concerned about efficiency
* on very large tables, and MySQL's regex functionality is very limited
*/
String sWhere = "";
System.out.println("sSearch="+ request.getParameter("sSearch"));

if (request.getParameter("sSearch") != "") {
sWhere = "WHERE (";
for (int i = 0; i < aColumns.length; i++) {
sWhere += aColumns[i] + " LIKE '%" + util.escape_string(request.getParameter("sSearch")) + "%' OR ";
}
sWhere = sWhere.substring(0, sWhere.length()-3);
sWhere += ')';
}

/* Individual column filtering */

for (int i = 0; i < aColumns.length; i++) {
if (request.getParameter("bSearchable_" + String.valueOf(i)) == "true"
&& request.getParameter("sSearch_" + String.valueOf(i)) != "") {
if (sWhere == "") {
sWhere = "WHERE ";
} else {
sWhere += " AND ";
}
sWhere += aColumns[i] + " LIKE '%" + util.escape_string(request.getParameter("sSearch_" + String.valueOf(i))) + "%' ";
}
}

/*
* SQL queries
* Get data to display
*/
String strColumnNames = "";

for (int i=0;i < aColumns.length;i++){
strColumnNames = strColumnNames + ", "+ aColumns[i];
}
strColumnNames = strColumnNames.substring(1);

String sQuery = "SELECT "
+ strColumnNames
+ " FROM " + sTable
+ " "
+ sWhere
+ sOrder
+ sLimit;

System.out.println("sQuery="+sQuery);


Statement s = conn.createStatement();
s.executeQuery(sQuery);

/* Data set length after filtering */
ResultSet rs = s.getResultSet();
int count = 0;
while (rs.next()) {
int idCol = rs.getInt("id");
System.out.println("id = " + idCol);
++count;
}
int iFilteredTotal = count;
rs.close();
s.close();
System.out.println("Selected count="+iFilteredTotal);

/* Total data set length */
s = conn.createStatement();
String sQuery2 = " SELECT COUNT(*) AS rowcount FROM " + sTable;
rs = s.executeQuery(sQuery2);
rs.next();
int iTotal = rs.getInt("rowcount");
rs.close();
s.close();
System.out.println("Total count="+iTotal);

/*
* Output
*/
String output = "{" +
"\"sEcho\" : "+ request.getParameter("sEcho")+ ", " +
"\"iTotalRecords\" : " + String.valueOf(iTotal) + ", " +
"\"iTotalDisplayRecords\" : " + String.valueOf(iFilteredTotal) + ", " +
// "\"iDisplayLength\" : " + "10" + ", " +
// "\"iDisplayStart\" : " + "10" + ", " +
"\"aaData\" : [" + "";

Object[][] aaData= new Object[iFilteredTotal][4];

s = conn.createStatement();
s.executeQuery(sQuery);
rs = s.getResultSet();

int rowNum=0;
while ( rs.next() )
{
System.out.println("rowNum="+ rowNum);
//if (rowNum > 3) break;
Object[] aRow = {0,"","",""};
Object[] row = {0,"","",""};

for ( int i=0 ; i<aColumns.length ; i++ )
{
System.out.println("i="+ i +" colVal="+ rs.getString( aColumns[i]));
if ((i == 0)&& (aColumns[i] != " ")){
row[i] = rs.getInt( aColumns[i]);
}
else{
row[i] = rs.getString( aColumns[i]);
}
}
aaData[rowNum] = row;
System.out.println("rowNum("+rowNum +") row[0]="+row[0].toString());
rowNum++;
}
rs.close();
s.close();

String valRow = " [ ";
for (int rowN = 0; rowN < iFilteredTotal; rowN++) {
//System.out.println("rowN="+rowN);
for (int colN = 0; colN < aColumns.length; colN++) {
//System.out.println(" colN="+colN);
if (aColumns[colN] == "id" )
valRow = valRow + " " + aaData[rowN][colN].toString() + " , ";
else if ( aColumns[colN] != " " )
valRow = valRow + "\"" + aaData[rowN][colN].toString() + "\" , ";
}
valRow = valRow.substring(0, valRow.length()-2);
valRow = valRow + " ], ";
//System.out.println("valRow="+valRow);
output = output + valRow;
valRow = " [ ";
}
System.out.println("output="+output);
output = output.substring(0, output.length()-2);
output = output + " ] }";

out.print(output);
%>


The util package has:
Escape.java
-----------
package util;

import org.apache.commons.lang.*;

public class Escape {
public static String html(String input) {
return StringEscapeUtils.escapeHtml(input);
}

public static String javaScript(String input) {
return StringEscapeUtils.escapeJavaScript(input);
}

public static String lineBreakToBr(String input) {
return input.replaceAll("\\n", "<br />");
}

public static String paragraphBreakToBrs(String input) {
return input.replaceAll("\\n\\s*\\n", "<br /><br />");
}
}

Crud with JQuery Master-Detail 6

When the list button is pressed the listServlet is NOT called.
Instead
...
$(function() {
$("input#List").click(function() {
window.open("personList.jsp");
//window.close();
window.open('close.html', '_self');
})
})
...

works in the JQmultiAJAXCalls.js.

It simply opens the personList.jsp.
It also closes the previous (index.jsp) windows.
window.open('close.html', '_self'); is used to disable the
comirmation message at the window close event.

personList.jsp is a JQuery data tables example customized for
this app's purpose. The js source part at the beginning
serves for data pipelining, namely it feeds tha data as it
gets necessary. This helps not to overload the data table.
I had to make slight changes so that the given example (JQuery
standard providence) could work according to my needs.


Please notice that there is a click function defined by me.
This first resets all the rows then extracts the current id
from the current row. It hen makes an AJAX call to the
selectList servlet. SelectListServlet gets the currentId from
the aoData and sets the current id at the DAO. Then it dispatches
the index.jsp.

The source follows:

personList.jsp
--------------

<%--
Document : personList
Created on : 24.Sub.2011, 18:23:21
Author : Ali Riza SARAL
--%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" type="image/ico" href="DataTables-1.7.5/media/images/favicon.ico" />

<title>DataTables example</title>
<style type="text/css" title="currentStyle">
@import "DataTables-1.7.5/media/css/demo_page.css";
@import "DataTables-1.7.5/media/css/demo_table.css";
</style>
<script type="text/javascript" language="javascript" src="DataTables-1.7.5/media/js/jquery.js"></script>
<script type="text/javascript" language="javascript" src="DataTables-1.7.5/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8">
var oCache = {
iCacheLower: -1
};

function fnSetKey( aoData, sKey, mValue )
{
for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
{
if ( aoData[i].name == sKey )
{
aoData[i].value = mValue;
}
}
}

function fnGetKey( aoData, sKey )
{
for ( var i=0, iLen=aoData.length ; i<iLen ; i++ )
{
if ( aoData[i].name == sKey )
{
return aoData[i].value;
}
}
return null;
}

function fnDataTablesPipeline ( sSource, aoData, fnCallback ) {
//alert("fnDataTablesPipeline");
var iPipe = 2; /* Ajust the pipe size */

var bNeedServer = false;
var sEcho = fnGetKey(aoData, "sEcho");
var iRequestStart = fnGetKey(aoData, "iDisplayStart");
var iRequestLength = fnGetKey(aoData, "iDisplayLength");
var iRequestEnd = iRequestStart + iRequestLength;
//alert("iRequestStart="+iRequestStart+"iRequestLength="+iRequestLength);



oCache.iDisplayStart = iRequestStart;

/* outside pipeline? */
if ( oCache.iCacheLower < 0 || iRequestStart < oCache.iCacheLower || iRequestEnd + iRequestLength*iPipe > oCache.iCacheUpper )
{
bNeedServer = true;
}
//alert(bNeedServer);
/* sorting etc changed? */
if ( oCache.lastRequest && !bNeedServer )
{
for( var i=0, iLen=aoData.length ; i<iLen ; i++ )
{
if ( aoData[i].name != "iDisplayStart" && aoData[i].name != "iDisplayLength" && aoData[i].name != "sEcho" )
{
if ( aoData[i].value != oCache.lastRequest[i].value )
{
bNeedServer = true;
break;
}
}
}
}

/* Store the request for checking next time around */
oCache.lastRequest = aoData.slice();

if ( bNeedServer )
{
if ( iRequestStart < oCache.iCacheLower )
{
iRequestStart = iRequestStart - (iRequestLength*(iPipe-1));
if ( iRequestStart < 0 )
{
iRequestStart = 0;
}
}

oCache.iCacheLower = iRequestStart;
oCache.iCacheUpper = iRequestStart + (iRequestLength * iPipe);
oCache.iDisplayLength = fnGetKey( aoData, "iDisplayLength" );
fnSetKey( aoData, "iDisplayStart", iRequestStart );
fnSetKey( aoData, "iDisplayLength", iRequestLength*iPipe );
//alert("oCache.iCacheLower="+oCache.iCacheLower+"oCache.iCacheUpper="+oCache.iCacheUpper);

$.getJSON( sSource, aoData, function (json) {
/* Callback processing */
oCache.lastJson = jQuery.extend(true, {}, json);

if ( oCache.iCacheLower != oCache.iDisplayStart )
{
json.aaData.splice( 0, oCache.iDisplayStart-oCache.iCacheLower );
}
json.aaData.splice( oCache.iDisplayLength, json.aaData.length );
jsonARS = json;

// if (oCache.iCacheUpper+ oCache.iDisplayLength < json.iTotalRecords)
// json.iTotalDisplayRecords=oCache.iCacheUpper+oCache.iDisplayLength;
if ((oCache.iDisplayStart+ oCache.iDisplayLength < json.iTotalRecords) &&
(oCache.iCacheUpper+ oCache.iDisplayLength < json.iTotalRecords))
json.iTotalDisplayRecords=oCache.iCacheUpper+oCache.iDisplayLength;
else
json.iTotalDisplayRecords = json.iTotalRecords;
fnCallback(json)
} );
}
else
{
json = jQuery.extend(true, {}, oCache.lastJson);
json.sEcho = sEcho; /* Update the echo for each response */
json.aaData.splice( 0, iRequestStart-oCache.iCacheLower );
json.aaData.splice( iRequestLength, json.aaData.length );
jsonARS = json;
fnCallback(json);
return;
}
}
var curRow = 1;
$(document).ready(function() {
oTable = $('#example').dataTable( {
"bProcessing": true,
"bServerSide": true,
// "sPaginationType": "full_numbers",
"sPaginationType": "two_button",
"aaSorting": [[0, 'desc'], [1, 'desc']],

"sAjaxSource": "./person_server.jsp",
"fnServerData": fnDataTablesPipeline,
"fnDrawCallback": function ( oSettings ) {
$('#example tbody tr').each( function () {

$(this).click( function () {
$('#example tbody tr').each( function () {
$(this).removeClass('row_selected');
});
$(this).addClass('row_selected');
var iPos = oTable.fnGetPosition( this );
var aData = oTable.fnGetData( iPos );
var iId = aData[0];
curRow = iId;
//alert(iId);
var aoData = [];
aoData.push( { "name": "id", "value": curRow } );
$.ajax({
type:"POST",
url: "./selectlist",
contentType: "application/x-www-form-urlencoded",
// dataType: "JSON",
data: aoData
// success: function(data) {
// var jsonData = $.parseJSON(data);
// $("input#id").val(jsonData.id)
// $("input#name").val(jsonData.name)
// $("input#last").val(jsonData.last)
// $("input#hobby").val(jsonData.hobby)
// }
});
window.open("index.jsp");
window.close();
} );
} );
}
} );
} );


</script>
</head>
<body id="dt_example">
<div id="container">
<div class="full_width big">
<i>Ali Riza SARAL's</i> Persons List
</div>
<H1>Please click on one of the persons</H1>
<DIV id=dynamic>
<TABLE id=example class=display border=0 cellSpacing=0 cellPadding=0>
<THEAD>
<TR>
<TH width="20%">Id</TH>
<TH width="25%">Name</TH>
<TH width="25%">Last Name</TH>
<TH width="25%">Hobby</TH></TR></THEAD>
<TBODY>
<TR>
<TD class=dataTables_empty colSpan=5>Loading data from server
</TD>
</TR>
</TBODY>
</TABLE>
</DIV>
</div>
</body>
</html>

SelectListServlet.java
----------------------
package servletPackage;
/**
*
* @author Ali Riza SARAL
*/
import java.io.*;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.*;
import mainPackage.*;
import daoPackage.*;

import util.Escape;

public class selectListServlet extends HttpServlet {

public void init()
throws ServletException {
System.out.println("ARSmsg: selectListServlet began to work");
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//PrintWriter out = response.getWriter();

PersonDAOMySQLDBImpl personDAO;
Person person = new Person();
HttpSession session = request.getSession();

String id = request.getParameter("id");
int currentRow = Integer.valueOf(id);
System.out.println("currentRow==================" + currentRow);

try {
personDAO = (PersonDAOMySQLDBImpl) session.getAttribute("personDAOsess");

personDAO.setPersonCurrentId(currentRow);
session.removeAttribute("personDAOsess");
session.setAttribute("personDAOsess", personDAO);
System.out.println(personDAO.getPersonCurrentId());

}
catch (Error e) {
System.out.println(e.getMessage());
}
finally {
//out.close();
}
//window.open("index.jsp");
RequestDispatcher view = getServletContext().getRequestDispatcher("/index.jsp");
view.forward(request,response);
}
}