Struts & DynaForms

C

Claire

I'm new to Struts and although I have managed to successfully managed
to pre-populate a form with values, my problem is when the user
changes any form values and I try to get hold of these in the action
that processes the form - well I only get the original form values
that I prepopulated the form with.

If anyone can see where I may be going wrong I would greatly
appreciate the feedback. I have checked that my form bean is session
scoped and also I define an array in the struts-config.xml - but don't
define the size, the prepolulate action deals with setting this bit.

Any help greatly appreciated!

Many Thanks, Claire

-----------------
struts-config.xml
-----------------

<form-bean name="stockForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="rows" type="app.Stock.StockRow[]"/>
<form-property name="action" type="java.lang.String"/>
</form-bean>

<forward name="stock" path="/Stock.do"/>

<action path="/Stock"
type="app.Stock.PreloadAction"
name="stockForm"
scope="session"
validate="false">
<forward name="success"
path="/pages/Stock/stockManagement.jsp"/>
</action>

<action path="/UpdateStock"
type="app.Stock.StockAction"
name="stockForm"
scope="session"
validate="false">
<forward name="success"
path="/pages/Welcome.jsp"/>
<forward name="addrow"
</action>

-----------------
StockRow.java
-----------------

public class StockRow
{
private String code = "";
private String name = "";
private String depot = "";
private String depotId = "";
private String rrp = "";
private String price = "";
private String activeDate = "";
private String inactiveDate = "";
private String currentStock = "";
private String newStock = "";

public String getCode() { return (this.code);}
public String getName() { return (this.name);}
public String getDepot() { return (this.depot);}
public String getDepotId() { return (this.depotId);}
public String getRrp() { return (this.rrp);}
public String getPrice() { return (this.price);}
public String getActiveDate() { return (this.activeDate);}
public String getInactiveDate() { return (this.inactiveDate);}
public String getCurrentStock() { return (this.currentStock);}
public String getNewStock() { return (this.newStock);}

public void setCode (String code) {this.code=code;}
public void setName (String name) {this.name=name;}
public void setDepot (String depot) {this.depot=depot;}
public void setDepotId (String depotId) {this.depotId=depotId;}
public void setRrp (String rrp) {this.rrp=rrp;}
public void setPrice (String price) {this.price=price;}
public void setActiveDate (String activeDate)
{this.activeDate=activeDate;}
public void setInactiveDate (String inactiveDate)
{this.inactiveDate=inactiveDate;}
public void setCurrentStock (String currentStock)
{this.currentStock=currentStock;}
public void setNewStock (String newStock) {this.newStock=newStock;}
}

-------------------
PreloadAction.java
-------------------

public class PreloadAction extends Action
{

public ActionForward execute (ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
DynaValidatorForm df = (DynaValidatorForm) form;

// get hold of the user currently logged on
HttpSession session = request.getSession( );
ActionForm aForm = (ActionForm)
session.getAttribute(Data.USER_KEY);
String sLoggedOn = ((LogonForm) aForm).getUsername();

// pass in the user that is logged on to a look up function
// this will return an array of StockRows
StockRow[] rows = Lookup.preloadStock(sLoggedOn);
df.set("rows", rows);
df.set("action", Data.SUBMIT);

return mapping.findForward(Data.SUCCESS);
}
}

--------------------
stockManagement.jsp
--------------------

<%@ page language="java"
import="java.util.*,utilities.*,database.*,org.apache.struts.action.*,app.*"
%>

<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<%
// the values for the dropdown of username to select from
ActionForm form = (ActionForm) session.getAttribute(Data.USER_KEY);
String sLoggedOn = ((LogonForm) form).getUsername();
String sWhere;
Date date = new Date();
String sDate = Utilities.formatDateDatabase(date);

// provide a list of titles that are currently active titles

sWhere = Table.C_TBP_TITLE_ACTIVE_DATE + " <= " + sDate
+ " AND nvl(" + Table.C_TBP_TITLE_INACTIVE_DATE + ", " + sDate + ") >=
" + sDate;
ArrayList codes = Lookup.DoLookup(Data.LOOKUP_ACTIVE_CODES,
Data.ONE_STRING, sWhere);
pageContext.setAttribute("codes", codes);

// provide a dropdown of depots that belong to the user logged on
sWhere = Table.C_DEPOT_USERNAME + " = '" + sLoggedOn + "'";
ArrayList depots = Lookup.DoLookup(Data.LOOKUP_USER_DEPOT,
Data.INT_THEN_STRING, sWhere);
pageContext.setAttribute("depots", depots);

%>

<jsp:include page="../page_top.jsp" />

<td width="644" class="menusub">
<html:errors/>
<html:form action="/UpdateStock" focus="firstname">

<table width="300" border="0" cellspacing="0"
cellpadding="3">
<tr>
<td align="left" valign="top" bgcolor="#6699CC"
class="menuhead" width="100%" colspan="9">
Stock Management</td>
</tr>
<tr>
<td width="10" class="formfieldhead">Code</td>
<td width="30" class="formfieldhead">Name</td>
<td width="30" class="formfieldhead">Depot</td>
<td width="6" class="formfieldhead">RRP</td>
<td width="6" class="formfieldhead">Price</td>
<td width="20" class="formfieldhead">Active
Date</td>
<td width="30" class="formfieldhead">Current
Stock</td>
<td width="30" class="formfieldhead">Stock to
Add</td>
<td width="5">&nbsp;</td>
</tr>

<logic:present name="stockForm">
<logic:iterate id="row" name="stockForm"
property="rows">
<tr>

<td width="10">

<logic:notEmpty name="row" property="code">
<html:text name="row" property="code"
size="6" readonly="true"/></td>
</logic:notEmpty>

<logic:empty name="row" property="code">
<html:select name="row" property="code">
<html:eek:ptions collection="codes"
property="value" labelProperty="label" />
</html:select>
</logic:empty>

</td>

<td width="30">

<logic:notEmpty name="row" property="name">
<html:text name="row" property="name"
size="20" readonly="true"/>
</logic:notEmpty>

<logic:empty name="row" property="name">
&nbsp
</logic:empty>

</td>

<td width="30">

<logic:notEmpty name="row" property="depotId">
<html:select name="row" property="depotId"
disabled="true">
<html:eek:ptions collection="depots"
property="value" labelProperty="label"/>
</html:select>
</logic:notEmpty>

<logic:empty name="row" property="depotId">
<html:select name="row" property="depotId">
<html:eek:ptions collection="depots"
property="value" labelProperty="label"/>
</html:select>
</logic:empty>

</td>

<td width="6">

<logic:notEmpty name="row" property="rrp">
<html:text name="row" property="rrp"
size="6" readonly="true"/>
</logic:notEmpty>

<logic:empty name="row" property="rrp">
&nbsp
</logic:empty>

</td>

<td width="6">

<logic:notEmpty name="row" property="price">
<html:text name="row" property="price"
size="6" readonly="true"/>
</logic:notEmpty>

<logic:empty name="row" property="price">
&nbsp
</logic:empty>

</td>

<td width="20">

<logic:notEmpty name="row"
property="activeDate">
<html:text name="row" property="activeDate"
size="10" readonly="true"/>
</logic:notEmpty>

<logic:empty name="row" property="activeDate">
<html:text name="row" property="activeDate"
size="10"/>
</logic:empty>

</td>

<td width="30">

<logic:notEmpty name="row"
property="currentStock">
<html:text name="row"
property="currentStock" size="5"/>
</logic:notEmpty>

<logic:empty name="row"
property="currentStock">
&nbsp
</logic:empty>

</td>

<td width="30"><html:text name="row"
property="newStock" size="5"/></td>

<td width="5">&nbsp;</td>

</tr>
</logic:iterate>
</logic:present>
<tr>
<td align="right" colspan="2">
<html:submit
value="Update Stock"
onclick="action.value='SUBMIT'"
style="padding: 1px 1px 1px 1px; font-weight:
bold; font-size: 10px; background: #6699CC; color: #FFFFFF;"/>
</td>
<td align="left" colspan="7">
<html:submit
value="Add Row"
onclick="action.value='ADDROW'"
style="padding: 1px 1px 1px 1px; font-weight:
bold; font-size: 10px; background: #6699CC; color: #FFFFFF;"/>
</td>
</tr>
</table>

<logic:present name="stockForm">
<input type="hidden"
name="action"
value="<bean:write name="stockForm"
property="action"/>">
</logic:present>

</html:form>
</td>

<jsp:include page="../page_bottom.jsp" />

-----------------
StockAction.java
-----------------

public class StockAction extends Action
{

public void updates (StockRow[] stock)
{
// Loop through each row of stock.
// If any new stock is to be added (there will be a value in
newStock form property),
// add this amount to our stock level
StockRow sr;
int i, iDepotId, iCurrentStock, iNewStock;
String sTitleId;

for (i = 0; i < stock.length-1; i++)
{
sr = stock;

System.out.println ("Row " + i);

System.out.println (" Code: " + sr.getCode());
System.out.println (" Current Stock: " + sr.getCurrentStock());
System.out.println (" New Stock: " + sr.getNewStock());

if (Integer.parseInt (sr.getNewStock()) > 0)
{

// add the new stock to our stock level
iCurrentStock = Integer.parseInt (sr.getCurrentStock())
+ Integer.parseInt (sr.getNewStock());

System.out.println (" New Stock Level: " + iCurrentStock);

// and update the database with this information
sTitleId = sr.getCode();
// get the depotId of the row
iDepotId = Integer.parseInt (sr.getDepotId());
// get the title code of the row
DepotTitles dt = new DepotTitles(sTitleId, iDepotId);
// create an instance of this object
dt.Update(Table.C_DEPOT_TITLES_PRODUCT_AMOUNT,
String.valueOf(iCurrentStock));// update the stock level
}
}

}

/**
* Action to process the Stock Page
*/
public ActionForward execute (ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
DbQueries dbq = new DbQueries();
String sWhere;
ArrayList stockRows;
HashMap stockRow;

DynaValidatorForm df = (DynaValidatorForm) form;
StockRow[] stock = (StockRow[]) df.get("rows");
String action = (String) df.get("action");

System.out.println ("stock action");
Lookup.display(stock);

HttpSession session = request.getSession();
ActionForm aForm = (ActionForm)
session.getAttribute(Data.USER_KEY);
String sLoggedOn = ((LogonForm) aForm).getUsername();

updates(stock);

if (action.equals(Data.ADDROW))
{
System.out.println("ADDROW - Add Row");

StockRow[] rows = Lookup.preloadStock(sLoggedOn);
df.set("rows", rows);
df.set("action", Data.SUBMIT);

return (mapping.findForward("addrow"));
}
else
{
System.out.println("SUBMIT - Update Stock");
return (mapping.findForward(Data.SUCCESS));
}
}
}
 
M

Matt Parker

Claire said:
I'm new to Struts and although I have managed to successfully managed
to pre-populate a form with values, my problem is when the user
changes any form values and I try to get hold of these in the action
that processes the form - well I only get the original form values
that I prepopulated the form with.

If anyone can see where I may be going wrong I would greatly
appreciate the feedback. I have checked that my form bean is session
scoped and also I define an array in the struts-config.xml - but don't
define the size, the prepolulate action deals with setting this bit.

Any help greatly appreciated!

Many Thanks, Claire

<snip>

It's difficult to tell since I can't run your code (please post working
examples of your problem rather than snippets of code that don't compile),
but my gut instinct is that this is a scope problem. Make sure that your
dynaforms always exist in the same scope and that they're accessed within
that scope.

Regards,

Matt
 
S

Sudsy

Claire wrote:
<snip>

From your JSP:
<logic:notEmpty name="row" property="code">
<html:text name="row" property="code"
size="6" readonly="true"/></td>
</logic:notEmpty>

<logic:empty name="row" property="code">
<html:select name="row" property="code">
<html:eek:ptions collection="codes"
property="value" labelProperty="label" />
</html:select>
</logic:empty>

From the documentation for html:text tag:

name
The attribute name of the bean whose properties are consulted when
rendering the current value of this input field. If not specified, the
bean associated with the form tag we are nested within is utilized. [RT
Expr]

property
Name of this input field, and the name of the corresponding bean
property if value is not specified. The corresponding bean property (if
any) must be of type String. [Required] [RT Expr]

I don't see a form-property tag for code nor do I see you trying to
retrieve a value in your StockAction class.

A much better approach would be to just specify that the form has
session scope and drop the name attribute.
 
C

Claire

Thanks for both of your postings.

Matt:

I didn't include all of the code as I retrieve an ArrayList of
Hashmaps for the rows I want to populate from a database - so people
wouldn't be able to compile and reproduce the problem anyway just due
to this.

Also, I have declared in the struts-config.xml that both of the forms
are session scoped - in both of my actions that use the formBean
stockForm, they have their scope="session". Do I need to do something
else to define the form a sessionj scoped then, anything I need to add
to the form-bean definition?


Sudsey:

I don't quite understand all of your comments . . .

I have got a form property tag defined, in stockManagement.jsp:


<html:form action="/UpdateStock" focus="firstname">

My stockBean is defined as:

<form-property name="rows" type="app.Stock.StockRow[]"/>
<form-property name="action" type="java.lang.String"/>

rows being an array of StockRow objects . . . each StockRow object
having the String properties: code, name, depot, depotId, rrp, price,
activeDate, inactiveDate, currentStock & newStock.

In order to iterate through my array of StockRows, I use the iterator:

<logic:iterate id="row" name="stockForm" property="rows">

so each StockRow object will be individually referred to as row as the
array is iterated through.

Therefore, what do you mean then by 'dropping the name attribute'? Do
you mean where I say name="row" - which I need to refer to the
StockRow object as I iterate through the rows property of the bean.

I do refer to my stockForm in the StockAction class, in the execute I
retrieve my array of StockRows:

DynaValidatorForm df = (DynaValidatorForm) form;
StockRow[] stock = (StockRow[]) df.get("rows");

then in the update method, I do display data from the form in the
updates method which has the array of StockRows (stock) passed through
to it:

StockRow sr;

for (i = 0; i < stock.length-1; i++)
{
sr = stock;
System.out.println ("Row " + i);
System.out.println (" Code: " + sr.getCode());
System.out.println (" Current Stock: " + sr.getCurrentStock());
System.out.println (" New Stock: " + sr.getNewStock());

So I don't quite understand what you're saying?

Many Thanks :)

Claire
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top