2

i have a problem with ajax form validation. I'm using struts-core 2.3.1.2, struts-jquery-plugin 3.3.0 and struts-json-plugin.

The problem occurs if an ajax form will be submitted by an ajax request and validation fails. Cause then the whole form will be placed on the result element. Therefore you can activate ajax validation on the ajax sumbit button. http://code.google.com/p/struts2-jquery/wiki/Validation

Here are also outdated information: http://struts.apache.org/2.2.3.1/docs/ajax-validation.html

But the interceptor "jsonValidationWorkflowStack" is missing in struts-default.xml like written in post: jsonValidationWorkflowStack seems to be removed in Struts 2.3.1

It is sourced out to the struts-json-plugin in struts-plugin.xml. I don't know how i can use this directly but i build my own Stack in struts.xml:

<!-- Sample JSON validation stack  -->
<interceptor-stack name="jsonValidationWorkflowStack">
            <interceptor-ref name="basicStack"/>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel</param>
            </interceptor-ref>
            <interceptor-ref name="jsonValidation"/>
            <interceptor-ref name="workflow"/>
        </interceptor-stack> 
    </interceptors>
<action name="updateMySettings" method="execute" class="de.ra.daod.actions.MyAppSettingAction">
        <interceptor-ref name="jsonValidationWorkflowStack"/>
                    <!-- This is not beauty within ajax -->
        <result name="input">/WEB-INF/jsp/mysetting_ajax.jsp</result>
        <result name="success" type="stream">
            <param name="contentType">text/html</param>
            <param name="inputName">inputStream</param>
        </result>
    </action>

And my form looks like:

<s:head />
<sj:head />
    <!-- This files are needed for AJAX Validation of XHTML Forms -->
    <script src="${pageContext.request.contextPath}/struts/xhtml/validation.js" type="text/javascript"></script>

<s:form id="form" action="private/updateMySettings" theme="xhtml">
                <s:textfield id="screenRes" key="appSetting.screenResolution" label="Screen resolution" required="true" />
<s:select key="appSetting.screenDepth" label="Color depth" list="#{'8':'8','16':'16','24':'24'}" required="true" />
<sj:submit value="Update Settings" targets="status" validate="true"/>
            </s:form>

Unfortunately i get a javascript error if validation fails or not:

Uncaught TypeError: Object #<Object> has no method 'indexOf'
f.extend.ajax  jquery-1.7.1.min.js:4
b.fn.ajaxSubmit
a.struts2_jquery.validateForm  jquery.struts2-3.3.0.min.js:18
a.subscribeHandler.h.beforeSubmit  jquery.struts2-3.3.0.min.js:18
b.fn.ajaxSubmit
a.subscribeHandler.e  jquery.struts2-3.3.0.min.js:18
e.extend.each  jquery-1.7.1.min.js:2
a.subscribeHandler.e  jquery.struts2-3.3.0.min.js:18
f.event.dispatch  jquery-1.7.1.min.js:3
f.event.add.h.handle.i  jquery-1.7.1.min.js:3
f.event.trigger  jquery-1.7.1.min.js:3
f.fn.extend.trigger  jquery-1.7.1.min.js:3
e.extend.each  jquery-1.7.1.min.js:2
e.fn.e.each  jquery-1.7.1.min.js:2
f.fn.extend.trigger  jquery-1.7.1.min.js:3
d.fn.extend.publish  jquery.subscribe.min.js:16
e.extend.each  jquery-1.7.1.min.js:2
d.fn.extend.publish  jquery.subscribe.min.js:16
(anonymous function)  jquery.struts2-3.3.0.min.js:18
f.event.dispatch  jquery-1.7.1.min.js:3
f.event.add.h.handle.i  jquery-1.7.1.min.js:3

It seems that the json object from the response can't be handled and i don't know why cause i followed the old instructions. I assume the cause is the function StrutsUtils.getValidationErrors from struts/utils.js if this function is used with the json object but i'm not sure. Can anyone help ?

Community
  • 1
  • 1
Caphalor40k
  • 31
  • 1
  • 5
  • Nobody an idea ? It must be possible to validate ajax requests in struts 2.3.1.2 or not ? Due to the fact that jsonValidationWorkflowStack is not supported by newest struts version i added the plugin struts-json-plugin 2.3.1.2 where jsonValidationWorkflowStack is available but it exists only old guidance with above result. Can anyone help ? – Caphalor40k May 15 '12 at 07:51

2 Answers2

1

I guess stream result and ajax doesn't play well together. just remove the targets attribute. – jogep

I don't agree with you because the tenor of AJAX isn't load a new page but rather load pieces of whatever to the current page that is why i use an AJAX submit button. To notice the user of the action without reloading the page itself. The workaround is to clear the content of the status div element with javascript. I think that can be automated in struts2-jquery-plugin. This is my form which is embedded in tabbed pane.

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>

<s:if test="appSetting != null">
<h3>Application settings</h3>
<div id="status" class="welcome"></div> 
<table>
    <tr>
        <td>
            <s:form id="form" action="updateMySettings" theme="xhtml">
                <s:textfield id="screenRes" key="appSetting.screenResolution"
                    label="Screen resolution" required="true" />
                <s:select key="appSetting.screenDepth" label="Color depth"
                    list="#{'8':'8','16':'16','24':'24'}" required="true" />
                <sj:submit id="updateSetting" value="Update Settings" targets="status" validate="true" />
            </s:form>
        </td>
        <td valign="top">
            <button id="fullScreen">Use full screen</button>
            <button id="fullBrowser">Use full browser</button>
        </td>
    </tr>
</table>
<script>
$("#fullScreen").click(function() {
    scr_width = Math.max(screen.width,screen.height);
    scr_height = Math.min(screen.width,screen.height);
    $("#screenRes").val(scr_width + 'x' + scr_height);
});
$("#fullBrowser").click(function() {
    brw_width = Math.max(window.innerWidth, window.innerHeight);
    brw_height = Math.min(window.innerWidth, window.innerHeight);
    $("#screenRes").val(brw_width + 'x' + brw_height);
});
$("#updateSetting").click(function() {
    $("#status").empty();
})
</script>
</s:if>
<s:else>
<p>No settings available.</p>
</s:else>

It works very well.

Caphalor40k
  • 31
  • 1
  • 5
0

You are step in an solved Struts2 Issue. Upgrade to latest version 2.3.3 or 2.3.4 and your problem should be gone.

Johannes
  • 2,060
  • 3
  • 17
  • 27
  • Thank you very much, this solved my issue with the javascript error. It works good but not perfect because if I send the form without validation errors the streaming result will be placed on the target (div container) and then I send the form with validation errors and the content from this targets container don't remove so it can be confusing. I assume that the result from successful request will be deleted if we have validation errors? Thanks – Caphalor40k Jun 19 '12 at 07:28
  • I guess stream result and ajax doesn't play well together. just remove the targets attribute. – Johannes Jun 19 '12 at 21:13