One thing jumps out right off: your form bean is a DynaActionForm. It
needs to be an instance of ValidatorActionForm for validation to occur;
either DynaValidatorActionForm form or, probably, DynaValidatorForm.
If that doesn't work, I'd suggest adding a simple String-type property
to the form and see if you can get validation working for that first.
I've never used nested business objects in dyna forms like you are.
L.
Raghu Kanchustambham wrote:
Thanks Laurie for the detailed explanation.
I am still not able to get the validation working .. after spending
almost
a frustrating one week on it.
Can you help me by telling me what I am doing wrong here... everything
seems to be right.. just that it isnt working... :(
Bean definition and Action Mapping in struts-config.xml:
<form-bean name="studentEnrollmentForm" type="
org.apache.struts.action.DynaActionForm">
<form-property name="studentEnrollment" type="
com.tuningfork.student.businessobject.enrollment.StudentEnrollment" />
<form-property name="paymentDetails" type="
com.tuningfork.student.businessobject.enrollment.StudentPaymentDetail[]"
size="4"/>
</form-bean>
<action attribute="studentEnrollmentForm" name="studentEnrollmentForm"
path="/StudentEnrollmentPre" scope="request"
validate="false" type="
com.tuningfork.student.action.StudentEnrollmentAction"
parameter="operation">
<forward name="preCreateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=create"/>
<forward name="preUpdateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=update"/>
<forward name="viewSuccess" path="/student/StudentEnrollment.jsp"/>
</action>
<!-- for create and view -->
<action attribute="studentEnrollmentForm" name="studentEnrollmentForm"
path="/StudentEnrollment" scope="request"
validate="true" type="
com.tuningfork.student.action.StudentEnrollmentAction"
parameter="operation"
input="/StudentEnrollmentPre.do?operation=preCreate">
<forward name="preCreateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=create"/>
<forward name="viewSuccess" path="/student/StudentEnrollment.jsp"/>
<forward name="createSuccess" path="home"/>
</action>
-------------Snippet from validation.xml ------------
<form name="studentEnrollmentForm">
<field property="studentEnrollment.studentCode" depends="required">
<arg0 key="code needed"/>
</field>
<field property="studentEnrollment.joinDate" depends="required,date">
<var>
<var-name>datePattern</var-name>
<var-value>dd/MM/yy</var-value>
</var>
</field>
</form>
------------------------------
StudentEnrollment.jsp---------------------------------
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<%@ taglib uri="/WEB-INF/struts-layout.tld" prefix="layout" %>
<html>
<head>
<title>Student Enrollment</title>
<link rel="stylesheet" href='/tuningfork/strutsLayoutConfig/default.css'
type="text/css">
<script language="Javascript"
src="/tuningfork/strutsLayoutConfig/javascript.js"></script><script>var
imgsrc="/tuningfork/strutsLayoutConfig/images/"; var
scriptsrc="/tuningfork/strutsLayoutConfig/"; var langue="en"; var
contextPath="/tuningfork";</script>
<link rel="stylesheet" type="text/css" href="mystyle.css" />
<SCRIPT>function set(target) {document.forms
[0].operation.value=target;}</SCRIPT>
</head>
<body>
<layout:crumbs styleClass="CRUMBS" separator=">">
<layout:crumb key="crumbs.student.home" link="/home.jsp"/>
<layout:crumb key="crumbs.student.search"
link="/StudentSearch.do?operation=search"/>
<layout:crumb key="crumbs.student.enrollment"/>
</layout:crumbs>
<html:errors/>
<h2>Student Enrollment</h2>
<c:set var="operationVar">
<%= request.getParameter("nextOperation")%>
</c:set>
<c:set var="readOnlyForm"> false </c:set>
<c:if test="${operationVar=='null' || operationVar=='ok'}"> <!-- view
doesnt
have a Next operation -->
<c:set var="readOnlyForm"> true </c:set>
</c:if>
<html:form action="StudentEnrollment.do">
<input type="hidden" name="operation" value="${operationVar}" />
<layout:grid cols="2">
<layout:text
property="studentEnrollment.enquiry.id<http://studentEnrollment.enquiry.id>
<http://studentEnrollment.enquiry.id>"
key="Enquiry Id" size="5" readonly="true"/>
<layout:space/>
<layout:text property="studentEnrollment.studentCode" key="Student Code"
size="10" isRequired="true"/>
<layout:date key="Joining Date" property="studentEnrollment.joinDate"
layout="true" patternKey="dd/MM/yy" startYear="1970" isRequired="true"
maxlength="8" size="8"/>
<layout:select
property="studentEnrollment.course.id<http://studentEnrollment.course.id>
<http://studentEnrollment.course.id>"
key="Course">
<layout:options collection="courseList" property="id"
labelProperty="name"
sourceOf="studentEnrollment.batch.id <http://studentEnrollment.batch.id><
http://studentEnrollment.batch.id>"/>
</layout:select>
<layout:select
property="studentEnrollment.batch.id<http://studentEnrollment.batch.id>
<http://studentEnrollment.batch.id>"
key="Batch">
<layout:optionsDependent collection="batches" property="id"
labelProperty="name"
dependsFrom="studentEnrollment.course.id<http://studentEnrollment.course.id>
<http://studentEnrollment.course.id>
"/>
</layout:select>
<layout:text property="studentEnrollment.listPrice" key="List Price"
size="6"/>
<layout:text property="studentEnrollment.discount" key="Discount"
size="6"/>
</layout:grid>
<br/>
<layout:checkbox property="studentEnrollment.declarationFormFlag"
key="Signed Declaration Form?"/>
<br/>
<layout:checkbox property="studentEnrollment.photographFlag"
key="Submitted
Photographs? "/>
<br/>
<br/>
<br/>
<[EMAIL PROTECTED] file="StudentPaymentDetails.jsp"%>
<c:if test="${(operationVar=='create') || (operationVar=='update')}" >
<html:submit styleClass="formButton">${operationVar} </html:submit>
</c:if>
</html:form>
<html:javascript formName="studentEnrollmentForm"/>
</body>
</html>
--------------------
Note that I start with the StudentEnrollmentPre.do?operation=preCreate
(as
Laurie suggested splitting up the actions into ones which require
validation
and others which dont).
When I submit press the submit without filling the required form fields
(namely the student code and joining date), I expect the validation
should
kick in and be redirected based on the input parameter. But no such
behavior
is being observed ! :(
I am really clueless as to what is missing in here. Appologize for
posting
so much information here... but this was my last resort!
And what makes things complicated is that another similar set of
form/action/jsp classes seem to work with validation fine. And there
seems
to be no major difference in which the action mappings are defined for
this
set and the one which isnt working! :( I will post that also if you
think it
will help debug the issue.
Thanks again Laurie for the suggestions you have given so far. Even
though
this problem persists, it still made me learn quite a bit about the
validator framework. Hopefully you can spot the mistake in this too ! :)
Best Regards,
Raghu
On 11/17/05, Laurie Harper <[EMAIL PROTECTED]> wrote:
Raghu Kanchustambham wrote:
Thanks Laurie. It works with the way you suggested. But it makes a lot
of
things clumsy..
1. I need to have different action class mappings potentially for each
of
the CRUD operations... though all of them use the same dispatch action
class.
Well, only for each case you need to apply different validation criteria
for, but yes, you may need to have more than two mappings, depending on
your requirements. You might look at wildcard action path mappings to
help with this:
http://struts.apache.org/struts-doc-1.2.7/userGuide/building_controller.html#action_mapping_wildcards
I haven't really used dispatch actions, so there might be other options
I don't know about.
2. I still havent figured out a way where you need to pass some "state"
information as a part of the URL to an action... something like
StudentEnquiry.do?studentId=32 .... let us say that is the URL for the
input
parameter of the action mapping.. how do i dynamically get the number
"32"
there.
Not sure I understand what you're asking there but I think the answer is
that you need to add the parameter in your action before forwarding. If
the 'state' information is part of the request you're validating and
validation fails, you don't need to do anything since Struts will
forward to the input mapping using the same request, which already
contains your state information.
On this piece of actionform things are working.
Having said that ..something seems to go wrong with a similar piece of
action form.
I dont know what I am doing wrong .. can you please tell me what I am
doing
wrong in the following:
<action attribute="studentEnrollmentForm" name="studentEnrollmentForm"
path="/StudentEnrollment" scope="request" validate="true" type="
com.tuningfork.student.action.StudentEnrollmentAction"
parameter="operation"
input="/StudentEnrollmentPre.do?operation=preCreate&postTo=
StudentEnquiryUpdate.do">
<forward name="preCreateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=create"/>
<forward name="viewSuccess" path="/student/StudentEnrollment.jsp"/>
<forward name="createSuccess" path="home"/>
</action>
<action attribute="studentEnrollmentForm" name="studentEnrollmentForm"
path="/StudentEnrollmentPre" scope="request"
validate="false" type="
com.tuningfork.student.action.StudentEnrollmentAction"
parameter="operation">
<forward name="preCreateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=create"/>
<forward name="preUpdateSuccess"
path="/student/StudentEnrollment.jsp?nextOperation=update"/>
</action>
/StudentEnrollmentPre.do is the operation with validation set to false.
My quesiton: Is this good enuf for me to redirect to input parameter on
errors ?
Is setting validate="true" and input="/StudentEnrollmentPre.do" to turn
on
server side validation?
Yes, that looks right...
when javascript validation is enabled through the <html:javascript> ...
it
does client side validation and is able to figure out all the
clientside
required fields with a "popup".
However, I expect it to return back and show the form again from the
server
side if my validation fails. But after the client side validation
(which
it
successfully detects that required fields are missing with a pop-up)..
it
just proceeds as if no errors were there on the page.
In a nutshell the input tag is not being used
Since javascript side is working fine I think validation.xml has no
errors.
I will post it if you think you need to look at it too.
If client side validation fails the form is never submitted so the
server isn't involved. You need to enter valid data so client side
validation succeeds before a request will actually get sent to the
server.
On a side note, I have been chatting with one of the senior users of
struts.
His opinion is that Struts framework creates lot more problems than it
solves. What is your opinion on it? Atleast this thing is really taking
a
lot of my effort to get it going... but may be its too early for me to
comment on the validator framework as I am new to it.
If you meant to say that 'Struts Validator framework create more
problems...', I'd say it depends on your perspective. Some love it, some
hate it. It certainly can be a bit tricky to get to grips with, and it
only gets you so far; you'll still need to implement some types of
validation yourself in addition to what validator can do for you.
Personally, I use it for what it *can* do, and fall back to hand-coded
validation for what it can't. Others perfer to stick to doing everything
the same way. You'll have to make your own call on whether you want to
stick with it or not once you've got it working well enough to
understand the tradeoffs in your application.
L.
Thanks in advance.
Regards,
Raghu
On 11/14/05, Laurie Harper <[EMAIL PROTECTED]> wrote:
The easiest way is probably to split your action mapping out into two
mappings, one for the operations that should have validation applied
and
one for the setup operations that shouldn't. Set validate="false" on
the
mapping for the setup operations, and make it the input for the other
mapping which will have validate="true".
L.
Raghu Kanchustambham wrote:
Thanks Laurie for the suggestion.
Then set the 'input' attribute for your validating actions to
point
to
the pre-population action >>>> (so when validation fails, Struts
forwards to
preCreate, not directly to the JSP).
That explains why the request variables are getting wiped off! :-) I
realize I am pointing directly to the JSP page. I changed it now to
point to
preCreate.
However, I have only one action class for all these operations. I
just
have various operations/functions inside that action class to handle
them. I
use the dispatch action servlet and not the action servlet and
preCreate,
create etc are various parameterized function calls on this dispacth
action
class.
How would you achieve setting false and true on validations based on
each
operation in dispatch action?
I am posting some relevant portions of my struts-config.xml. The
minute
I
changed validate="true", I am getting an exception. And I think I can
explain it. It is validating before the user inputs anything.
Naturally
it
fails. Then it redirects to the same "input" page. Again fails
validation...
its just going into an endless loop. :(
Please suggest whats the best way to work around this?
<form-bean name="studentEnquiryForm" type="
org.apache.struts.validator.DynaValidatorForm">
<form-property name="studentEnquiry" type="
com.tuningfork.student.businessobject.enquiry.StudentEnquiry "/>
<form-property name="contactAddress" type="
com.tuningfork.student.businessobject.enquiry.StudentAddress"/>
<form-property name="permanentAddress" type="
com.tuningfork.student.businessobject.enquiry.StudentAddress "/>
<form-property name="educationDetails" type="
com.tuningfork.student.businessobject.enquiry.StudentEducationDetail
[]"
size="4"/>
<form-property name="workExperience" type="
com.tuningfork.student.businessobject.enquiry.StudentWorkExperience
"/>
<form-property name="enquiryCentreId" type="java.lang.Integer"/>
<form-property name="enquiryCourseId" type=" java.lang.Integer"/>
<form-property name="studentEnquiryId" type="java.lang.Integer"/>
<form-property name="newsPaperIds" type="int[]"/>
<form-property name="discoverySourceIds" type="int[]"/>
<form-property name="centreTimePreferences" type="
com.tuningfork.student.businessobject.enquiry.StudentCentreTimePreference
[]"
size="3"/>
<form-property name="studentEnquiryFilter" type="
com.tuningfork.student.businessobject.enquiry.StudentEnquiryFilter"/>
</form-bean>
<action attribute="studentEnquiryForm" name="studentEnquiryForm"
path="/StudentEnquiry" scope="request"
validate="false" type="
com.tuningfork.student.action.StudentEnquiryAction"
parameter="operation" input="/StudentEnquiry.do?operation=preCreate">
<forward name="preCreateSuccess"
path="/student/StudentEnquiry.jsp?nextOperation=create"/>
<forward name="preUpdateSuccess"
path="/student/StudentEnquiry.jsp?nextOperation=update"/>
<forward name="viewSuccess" path="/student/StudentEnquiry.jsp"/>
<forward name="createSuccess" path="home"/>
<forward name="initFilterForUpdateSuccess"
path="/student/StudentSearch.jsp?nextOperation=prepareListForUpdate"/>
<forward name="prepareListForUpdateSuccess"
path="/student/StudentSearch.jsp?nextOperation=prepareListForUpdate"/>
<forward name="updateSuccess"
path="/student/StudentEnquiry.jsp?nextOperation=update"/>
</action>
On 11/13/05, Laurie Harper <[EMAIL PROTECTED]> wrote:
The trick is to only include validation on the data processing
actions,
not on the pre-display actions ( i.e. use validate="false" on your
preCreate action mapping, and only put validate="true" on the action
you
submit the form to). Then set the 'input' attribute for your
validating
actions to point to the pre-population action (so when validation
fails,
Struts forwards to preCreate, not directly to the JSP).
You don't need to use session scope for anything if you don't want
to,
you just have to make sure that you always display your JSP via your
preCreate action.
If that doesn't make sense, post your action mappings from
struts-config.xml so we can see how you have things setup.
L.
Raghu Kanchustambham wrote:
I think I can explain it now.
I hit the action servlet first invoking preCreate function. This
function
populates various lists of beans needed for dropdowns and put these
lists in
the request object and forward to a JSP. The JSP reads these lists
and
displays the dropdowns. So far so good!
preCreate --->request object populated with lists ---> JSP reads
from
request for dropdown lists
Now... enter the Validation framework! I think it is hijacking this
series!
preCreate ---> request populated with lists ---> Validator
framework
--->
JSP
Now the jump from Validator framework to JSP means that all request
scope
objects (the lists) are lost! :(
How should I architect ? Should I make these lists session scope? I
somehow
dont like to make them session scope, because they are really
request
scope!
Can someone comment on my explanation / help me with a solution ??
Thanks much.
Regards,
Raghu
On 11/12/05, Martin Gainty <[EMAIL PROTECTED]> wrote:
I didnt see the contents E.G. <tag> </tag> for your c.tld ??
Martin-
----- Original Message -----
From: "Raghu Kanchustambham" <[EMAIL PROTECTED]>
To: "Struts Users Mailing List" < user@struts.apache.org>
Sent: Saturday, November 12, 2005 10:37 AM
Subject: Re: Fw: Validator framework introduces errors
Hi Martin,
I do something like:
request.setAttribute("centreList",DataAccessManager.getCentres());
before invoking the jsp.
The strange part is, the minute i remove validation.xml from the
validator
path, effectively removing the validation framework, every thing
works
just
fine! Just cant explain it ! :(
Thanks again in advance to anyone who can explain this!
Please find the StudentEnquiry.jsp attached.
----------------------------------------
<%@ page import="
com.tuningfork.student.businessobject.enquiry.StudentEducationDetail
"%>
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts- bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<%@ taglib uri="/WEB-INF/struts-layout.tld" prefix="layout" %>
<layout:html>
<head>
<title>Student Enquiry</title>
<link rel="stylesheet" type="text/css" href="../mystyle.css" />
<SCRIPT>function set(target) { document.forms
[0].operation.value=target;}</SCRIPT>
</head>
<body>
<h2>Student Enquiry</h2>
<html:errors/>
<c:set var="operationVar">
<%= request.getParameter("nextOperation")%>
</c:set>
<c:set var="readOnlyForm"> false </c:set>
<c:if test="${operationVar=='null' || operationVar=='ok'}"> <!--
view
doesnt
have a Next operation -->
<c:set var="readOnlyForm"> true </c:set>
</c:if>
<html:form action="StudentEnquiry.do"
onsubmit="validateStudentEnquiryForm(this);">
<input type="hidden" name="operation"
value="<%=request.getParameter("nextOperation")%>"
/>
<table width="100%">
<tr>
<td rowspan="2">
<[EMAIL PROTECTED] file="StudentDemographics.jsp"%>
</td>
<td>
<layout:grid cols="2">
<layout:select property="enquiryCentreId" size="${selectBoxSize}"
key="Enquiry Centre">
<layout:options collection ="centreList" property="id"
labelName="name"
/>
</layout:select>
<layout:select property="enquiryCourseId" size="${selectBoxSize}"
key="Enquiry Course">
<layout:optionsCollection name="courseList" value="id"
label="name"/>
</layout:select>
</layout:grid>
</td>
</tr>
<tr>
<td>
</td>
<td align="center">
<html:submit>${operationVar} </html:submit>
<html:cancel>cancel</html:cancel>
</td>
</tr>
</table>
</html:form>
</body>
</layout:html>
------------------------------------------------
On 11/12/05, Martin Gainty <[EMAIL PROTECTED]> wrote:
I did'nt see the (StudentEnquiry.jsp) jsp page which references
centreList
bean?
I also dont see the code for centreList bean?
Martin-
----- Original Message -----
From: "Raghu Kanchustambham" <[EMAIL PROTECTED]>
To: "Struts Users Mailing List" < user@struts.apache.org>
Sent: Saturday, November 12, 2005 9:40 AM
Subject: Validator framework introduces errors
Hi,
The minute I introduced Validator framework in my application
.....
it started giving me the following error when I accessed the JSP
....
centreList is used as a parameter for the dropdown. The minute I
remove
the
validation.xml from the path... the application runs fine again!
:(
very strange and i am not able to explain this behavior .. can
someone
help?
Thanks much in advance.
Regards,
Raghu
javax.servlet.jsp.JspException: Cannot find bean centreList in
any
scope
org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:938)
fr.improve.struts.taglib.layout.field.OptionsCollectionTag.doStartTag
(
OptionsCollectionTag.java:115)
org.apache.jsp.student.StudentEnquiry_jsp._jspx_meth_layout_optionsCollection_0
(StudentEnquiry_jsp.java:1088)
org.apache.jsp.student.StudentEnquiry_jsp._jspx_meth_layout_select_2
(StudentEnquiry_jsp.java:1062)
org.apache.jsp.student.StudentEnquiry_jsp._jspx_meth_layout_grid_1
(StudentEnquiry_jsp.java:1028)
org.apache.jsp.student.StudentEnquiry_jsp._jspService
(StudentEnquiry_jsp.java:258)
My validation.xml (very simple one):
<!DOCTYPE form-validation PUBLIC
"-//Apache Software Foundation//DTD Commons Validator Rules
Configuration 1.0//EN"
"http://jakarta.apache.org/commons/dtds/validator_1_0.dtd">
<form-validation>
<formset>
<form name="studentEnquiryForm">
<field property="studentEnquiry.firstName" depends="required">
<arg0 key=" firstName.mandatory"/>
</field>
</form>
</formset>
</form-validation>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]