You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Koen Jans <ko...@student.kuleuven.be> on 2005/11/29 20:20:03 UTC

How do you prepopulate your forms?

Suppose for instance you want to prepopulate a form where users
can edit their profile;

the way i do it is:
I have an action PrepareEditProfileAction that
a) gets the data from storage
b) creates a editProfileFormBean and puts the data in it
c) saves this editProfileFormBean in request-scope
d) forwards to the edit profile jsp page, which then
   displays the data from the editProfileFormBean in request scope..

so your struts-config.xml looks like:

<!-- prepopulate -->
<action path="/actions/prepareeditprofile"
  type="actions.PrepareEditProfileAction">
<forward name="success" path="/editprofileform.jsp" />
</action>

<action path="/actions/editprofile"
  type="actions.EditProfileAction"
  name="editProfileFormBean"
  scope="request"
  validate="true"
  input="/actions/prepareeditprofile.do">
<forward name="success" path="/success.jsp" />
</action>


Is this a common reproach?
I've seen people using the "input" attribute point to an prepopulate
action? 

Thanks for your time,
Koen


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How do you prepopulate your forms?

Posted by "Frank W. Zammetti" <fz...@omnytex.com>.
Lately I've been using the DependencyFilter in Java Web Parts for such
things...

http://javawebparts.sourceforge.net

...or more specifically:...

http://javawebparts.sourceforge.net/javadocs/javawebparts/filter/DependencyFilter.html

(Admittedly I need to clean up those docs a bit, but you'll get the gist
of it).

What I do is I have a helper class that calls through to my business
facade and gets whatever data I need and puts it in some DTO, which is
then "injected" into the appropriate scope (this is done by the
DependencyFilter via config file).  My Action can then grab the DTO and
populate the ActionForm.  This eliminates the need for setup Actions and
such.

As an example, let's say I have an ActionForm with fields:

String firstName;
String lastName;

...and likewise I have a PersonDTO:

public class PersonDTO {
  private String firstName;
  private String lastName;
  public void setFirstName(String fn) { firstName=fn; }
  public String getFirstName() { return firstName; }
  public void setLastName(String ln) { lastName=ln; }
  public String getLastName() { return lastName; }
}

The DependencyFilter has its own config file, and here's a simple example:

<dependencies>
  <dependency scope="request" name="MyProfile"
createForPaths="/editprofile.do">
    <className>my.app.PersonDTO</className>
    <initClass name="ProfileHelper" mathod="getProfile" />
  </dependency>
</dependencies>

Note that the createForPaths attribute is a comma-separated list which
supports wildcards, so you can use the same dependency in multiple places
with one config entry.

Finally, I have a class named ProfileHelper, something like so:

public class ProfileHelper {
  public void getProfile(PersonDTO p) {
    // Code to populate firstName and lastName in p from database
  }
}

So, what happens is:

(1) When a request comes in for /editProfile.do, the filter kicks in.
(2) The filter instantiates an instance of PersonDTO, as well as an
instance of ProfileHelpers.
(3) The PersonDTO is passed to the getProfile() method of the
ProfileHelpers class.
(4) getProfile() does whatever it needs to do to get the firstName and
lastName for the current user from the database and populate those fields
in the DTO.
(5) The PersonDTO instance, being specified as having request scope, is
now "injected" into the current request object as an attribute under the
key "MyProfile".
(6) Now, in my Action, I can get at the PersonDTO by calling:

  PersonDTO p = (PersonDTO)DependencyFilter.getDependency("MyProfile",
request);

Note that you don't need to specify the scope the bean is in... if you
change it later, the same call will still get it.

Usually there is some logic there in the Action to determine whether I
should do this or not (i.e., is this the first time /editProfile.do has
been called, or am I dealing with perhaps a form submission, in which case
I want to use the ActionForm as-is?).  But, if applicable, I just populate
the ActionForm from the PersonDTO at this point.

Note that you can do even better things if you put the ActionForm in
session scope because then the filter can in essence take the place of
Struts and create it, populate it, and stick it in session, and then you
can cut out a lot of this because you (and the filter) deal with the
ActionForm directly.  What you have is a nice, clean way to prepopulate an
ActionForm without having to have a bunch of prepopulation mappings and
Actions.

The DependencyFilter has a ton of options for initializing objects, as
well as a facility to give them a lifetime.  So, if you want to for
instance have an object in a users' session that is updating from the
database every 10 minutes, you can set a maxAge attribute on the
<dependency> element, and then with every request the age of the object is
checked.  If it exceeds maxAge, it is initialized again.  This can come in
*very* handy.

I've been meaning to put together a cookbook recipe for doing things like
this, but I haven't gotten around to it yet.

-- 
Frank W. Zammetti
Founder and Chief Software Architect
Omnytex Technologies
http://www.omnytex.com
AIM: fzammetti
Yahoo: fzammetti
MSN: fzammetti@hotmail.com

On Tue, November 29, 2005 2:20 pm, Koen Jans said:
> Suppose for instance you want to prepopulate a form where users
> can edit their profile;
>
> the way i do it is:
> I have an action PrepareEditProfileAction that
> a) gets the data from storage
> b) creates a editProfileFormBean and puts the data in it
> c) saves this editProfileFormBean in request-scope
> d) forwards to the edit profile jsp page, which then
>    displays the data from the editProfileFormBean in request scope..
>
> so your struts-config.xml looks like:
>
> <!-- prepopulate -->
> <action path="/actions/prepareeditprofile"
>   type="actions.PrepareEditProfileAction">
> <forward name="success" path="/editprofileform.jsp" />
> </action>
>
> <action path="/actions/editprofile"
>   type="actions.EditProfileAction"
>   name="editProfileFormBean"
>   scope="request"
>   validate="true"
>   input="/actions/prepareeditprofile.do">
> <forward name="success" path="/success.jsp" />
> </action>
>
>
> Is this a common reproach?
> I've seen people using the "input" attribute point to an prepopulate
> action?
>
> Thanks for your time,
> Koen
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How do you prepopulate a form bean with arguments from a hyperlink?

Posted by Brad Simonin <bs...@psl.nmsu.edu>.
Thank you very much.  

--Brad


On Tue, 2005-11-29 at 14:59, Michael Jouravlev wrote:
> On 11/29/05, bsimonin@psl.nmsu.edu <bs...@psl.nmsu.edu> wrote:
> >
> > If I were going to send arguments to a normal servlet from a hyperlink I would have the following:
> > http://servlet_name?employeeId=xxxxxx&account=xxxxxx
> >
> > I want to do the same thing for a struts application and then populate the form bean with those arguments but I can't think of how to do it.
> 
> Same thing. Use action name instead of servlet name. Don't forget to
> define a form and the properties, corresponding to request parameters.
> 
> Michael.
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
> For additional commands, e-mail: user-help@struts.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How do you prepopulate a form bean with arguments from a hyperlink?

Posted by Michael Jouravlev <jm...@gmail.com>.
On 11/29/05, bsimonin@psl.nmsu.edu <bs...@psl.nmsu.edu> wrote:
>
> If I were going to send arguments to a normal servlet from a hyperlink I would have the following:
> http://servlet_name?employeeId=xxxxxx&account=xxxxxx
>
> I want to do the same thing for a struts application and then populate the form bean with those arguments but I can't think of how to do it.

Same thing. Use action name instead of servlet name. Don't forget to
define a form and the properties, corresponding to request parameters.

Michael.

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


How do you prepopulate a form bean with arguments from a hyperlink?

Posted by bs...@psl.nmsu.edu.
If I were going to send arguments to a normal servlet from a hyperlink I would have the following:
http://servlet_name?employeeId=xxxxxx&account=xxxxxx

I want to do the same thing for a struts application and then populate the form bean with those arguments but I can't think of how to do it.

Thank you in advance,

--Brad.

 

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: How do you prepopulate your forms?

Posted by Joe Germuska <Jo...@Germuska.com>.
This is essentially the standard approach.  Your code leaves out the 
possibility that the form already exists (and that it may be in the 
session scope).  This may be practical for your cases, but might lead 
to confusion should someone change part of the flow in your 
application.

In Struts 1.3, there are actually a few places where this basic 
operation (check a scope for existing form, if not found, create it 
and place in scope, and return either pre-existing or new form) are 
done.  I haven't seen a path to encapsulate it into one single 
operation, although I haven't actually thought about it for quite a 
while; it could probably just be put into a static util method on 
some class, but I was sort of down on static util methods for a while.

Anyway, Struts does this for you in the CreateActionForm class.  This 
isn't appropriate to prepopulation, though.  If you want to do it 
yourself, there are two ways to get at it, but both involve newer 
features of Struts 1.3.

First, and probably best, would be to use the CopyFormToContext 
command as part of a chain of commands; it can actually do the lookup 
so that all you have to specify is the path of the destination action 
and it will look up the form name and scope, much as <html:form> 
does.  This provides for clean configuration.  You can make a chain 
which uses this command and then has a subsequent command retrieve 
the form from the context and do the population.

This behavior is also implemented in the ActionContextBase class, in 
the method findOrCreateActionForm(String formName, String scopeName). 
This method is not part of the ActionContext interface.  Perhaps it 
should be, but I thought it best to figure out a way to put this code 
in one place rather than three before adding it to the interface. 
Still, if you have an ActionContext instance which inherits from 
ActionContextBase then you can cast and use the method.  However, at 
this time a typical Struts Action class does not have a reference to 
an ActionContext object; we have not yet committed to changing the 
Action interface to receive one, and we haven't yet settled on a 
potential place to offer static access to a ThreadLocal which might 
store the ActionContext, although I'm using this basic pattern in a 
custom implementation of ActionContext and finding it workable, and 
there was some interest in having this last time it came up on the 
dev list.

>I've seen people using the "input" attribute point to an prepopulate
>action?

the "input" attribute is only used when form validation fails.  In 
some approaches, some page prep needs to happen here, although what I 
usually consider "prepopulation" (seeding with persistent values) is 
not relevant because the form should be refilled with whatever was 
submitted in the HTTP request.  However, if you have dynamic menus or 
other form elements, of course you need to arrange for those to be 
restored.

Hope this helps,
	Joe

-- 
Joe Germuska            
Joe@Germuska.com  
http://blog.germuska.com    
"Narrow minds are weapons made for mass destruction"  -The Ex

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org