• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2001
  • Last Modified:

Select box custom tag

I'm using struts and having trouble determining how to do the following:

use the struts tag-lib to populate a select box with name/id pairs from a table in my database. I want to avoid scriptlets if at all possible.

Thanks!
0
chambers777
Asked:
chambers777
  • 7
  • 6
1 Solution
 
kennethxuCommented:
you need to
1. define a bean with property id and name,
2. in you action class, read from database and polulate a collection of said beans.
3. make the colloection availabe to the request scope by either putting directly or set as formbean attribute.
4. in jsp page use <html:select> nested with <html:options> or <html:optionsCollection> depend on how you pass the collection from action class to jsp.

an example of <html:options>:

<html:options collection="myCollection" labelProperty="name" property="id"/>

FYI: http://jakarta.apache.org/struts/userGuide/struts-html.html

let me know if you have more specific question during implementation.
0
 
chambers777Author Commented:
Kennethxu... I'm afraid I'm going to need a bit of direction (which I absolutely appreciate as always :-))

1) I've established my bean:
//*********************************************
public class IssueTypeBean {

      private int id;

      private String name;

      public void setId (int id) {
            this.id = id;
      }

      public int getId () {
            return id;
      }

      public void setName (String name) {
            this.name = name;
      }

      public String getName () {
            return name;
      }

}

//*********************************************
2) I've established a DAO to return an array:
//*********************************************

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.sql.SQLException;
import java.util.List;
import java.sql.PreparedStatement;
import com.safeway.lcham02.IssueTypeBean;
public class IssueTypeDAO {

      private Connection connection;

      public void setConnection (Connection connection) {
            this.connection = connection;
      }

      public Connection getConnection () {
            return connection;
      }

      public IssueTypeBean[] findAll () throws SQLException {
            /* Do not modify this comment. It's needed for DAO generator to work correctly.
            To modify this method, right click it in outline and select Edit as DAO method
             @dbSQL{"SELECT * FROM issue_type ORDER BY issue_type_id ASC",
            "multiSelect",
            [],
            "com.safeway.lcham02.IssueType",
            ["id","int","ISSUE_TYPE_ID",
            "name","String","ISSUE_TYPE_NM"]} */

            PreparedStatement st = connection.prepareStatement ("SELECT * FROM issue_type ORDER BY issue_type_id ASC");
            ResultSet rs = null;

            try {

                  rs = st.executeQuery ();
                  List list = new ArrayList ();

                  while (rs.next ()) {

                        IssueTypeBean bean = new IssueTypeBean ();

                        bean.setId (rs.getInt("ISSUE_TYPE_ID"));
                        bean.setName (rs.getString("ISSUE_TYPE_NM"));
                        list.add (bean);

                  }

                  return (IssueTypeBean[]) list.toArray (new IssueTypeBean[0]);

            } finally {

                  if (rs != null)
                        rs.close ();

                  st.close ();

            }
      }

}

//*********************************************
Am I on the right track here?
Here is where I am confused: "in you action class, read from database and polulate a collection of said beans."
My action class looks like this:
//*********************************************

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResources;
/**
 * Implementation of <strong>Action</strong> that validates a registration form.
 *
 * @author David Wintefeldt
*/
public final class IssueAction extends Action {

      /**
       * Commons Logging instance.
      */
      //  private Log log = LogFactory.getFactory().getInstance(this.getClass().getName());

      /**
       * Process the specified HTTP request, and create the corresponding HTTP
       * response (or forward to another web component that will create it).
       * Return an <code>ActionForward</code> instance describing where and how
       * control should be forwarded, or <code>null</code> if the response has
       * already been completed.
       *
       * @param mapping The ActionMapping used to select this instance
       * @param form The optional ActionForm bean for this request (if any)
       * @param request The HTTP request we are processing
       * @param response The HTTP response we are creating
       *
       * @return Action to forward to
       * @exception Exception if an input/output error or servlet exception occurs
       */
      public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {

            // Extract attributes we will need
            HttpSession session = request.getSession();
            Locale locale = getLocale(request);
            MessageResources messages = getResources(request);
            IssueForm issueForm = (IssueForm) form;
            String action = request.getParameter("action");

            // Was this transaction cancelled?
            if (isCancelled(request)) {
                  // if (log.isissueFormEnabled()) {
                  //    log.issueForm(" " + mapping.getAttribute() + " - Registration transaction was cancelled");
                  // }

                  removeFormBean(mapping, request);

                  return (mapping.findForward("success"));
            }

            return mapping.findForward("success");
      }

      /**
       * Convenience method for removing the obsolete form bean.
       *
       * @param mapping The ActionMapping used to select this instance
       * @param request The HTTP request we are processing
      */
      protected void removeFormBean(
            ActionMapping mapping,
            HttpServletRequest request) {
            // Remove the obsolete form bean
            if (mapping.getAttribute() != null) {
                  if ("request".equals(mapping.getScope())) {
                        request.removeAttribute(mapping.getAttribute());
                  } else {
                        HttpSession session = request.getSession();
                        session.removeAttribute(mapping.getAttribute());
                  }
            }
      }

}

//*********************************************
//*********************************************
Where do I populate it (I know how, but, where) and how do I make it available within the request scope?
Thanks so much!
LC
0
 
kennethxuCommented:
you need to call the DAO in your action class to get the array. you can put it in the request scope as:

IssueTypeBean[] issueTypes = dao.findAll();
request.setAttribute( "myIssueTypes", issueTypes );

or if you can define a issueTypes property in your issueForm, and call
issueForm.setIssueTypes( issueTypes );
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
chambers777Author Commented:
forgive me for being a bit dense today. But here is my action class:

/*
 * Created on Mar 29, 2004
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package com.safeway.lcham02;

/**
 * @author lcham02
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Struts", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * issueFormrmation on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.sql.*;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.MessageResources;
/**
 * Implementation of <strong>Action</strong> that validates a registration form.
 *
 * @author David Wintefeldt
*/
public final class IssueAction extends Action {

      /**
       * Commons Logging instance.
      */
      //  private Log log = LogFactory.getFactory().getInstance(this.getClass().getName());

      /**
       * Process the specified HTTP request, and create the corresponding HTTP
       * response (or forward to another web component that will create it).
       * Return an <code>ActionForward</code> instance describing where and how
       * control should be forwarded, or <code>null</code> if the response has
       * already been completed.
       *
       * @param mapping The ActionMapping used to select this instance
       * @param form The optional ActionForm bean for this request (if any)
       * @param request The HTTP request we are processing
       * @param response The HTTP response we are creating
       *
       * @return Action to forward to
       * @exception Exception if an input/output error or servlet exception occurs
       */
      public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {

            // Extract attributes we will need
            HttpSession session = request.getSession();
            Locale locale = getLocale(request);
            MessageResources messages = getResources(request);
            IssueForm issueForm = (IssueForm) form;
            String action = request.getParameter("action");
            
            
            Driver meds_driver = (Driver)Class.forName("COM.ibm.db2.jdbc.net.DB2Driver").newInstance();
            Connection dbConnection = DriverManager.getConnection( "jdbc:db2://sliudv36.safeway.com:61342/meds","bp00mk", "mktg2003");
            
            IssueTypeDAO dao = new IssueTypeDAO();
            dao.setConnection(dbConnection);
            IssueTypeBean[] issueTypes = dao.findAll();
            request.setAttribute("myIssueTypes", issueTypes);

            
            
      

            // Was this transaction cancelled?
            if (isCancelled(request)) {
                  // if (log.isissueFormEnabled()) {
                  //    log.issueForm(" " + mapping.getAttribute() + " - Registration transaction was cancelled");
                  // }

                  removeFormBean(mapping, request);

                  return (mapping.findForward("success"));
            }

            return mapping.findForward("success");
      }

      /**
       * Convenience method for removing the obsolete form bean.
       *
       * @param mapping The ActionMapping used to select this instance
       * @param request The HTTP request we are processing
      */
      protected void removeFormBean(
            ActionMapping mapping,
            HttpServletRequest request) {
            // Remove the obsolete form bean
            if (mapping.getAttribute() != null) {
                  if ("request".equals(mapping.getScope())) {
                        request.removeAttribute(mapping.getAttribute());
                  } else {
                        HttpSession session = request.getSession();
                        session.removeAttribute(mapping.getAttribute());
                  }
            }
      }

}


//********************
and then in my JSP:
//********************
                                                            
<html:select property="issue_types">
       <html:options name="myIssueTypes" labelProperty="name" property="id"/>
</html:select>


but I get this:
org.apache.jasper.JasperException: Cannot find bean under name myIssueTypes

0
 
kennethxuCommented:
that is strange. are you using redirect forward?
try to replace above code with this in jsp page: <%=request.getAttribute( "myIssueTypes" )%>
and see what you get. if you get null, then try to put the array in session scope:
session.setAttribute( ....
0
 
chambers777Author Commented:
I've tried both and both fail w/ same message.

I am a bit confused. Isn't the Action Class processed only when submitting the form? Therefore, my bean wouldn't be inserted into the request until after it was submitted?
0
 
kennethxuCommented:
did you try to replace above <html:select .... </html:select> with this in jsp page: <%=request.getAttribute( "myIssueTypes" )%>
and see what you get?


>> Isn't the Action Class processed only when submitting the form?
no, action class is process when you access the xyz.do
0
 
chambers777Author Commented:
>>did you try to replace
I did, and it returns null....


>>no, action class is process when you access the xyz.do
But I'm not accessing the *.do mapping until this form is processed.
0
 
kennethxuCommented:
>> But I'm not accessing the *.do mapping until this form is processed.
oh, that's the problem. if that is the case, then you'll have to move the code form Action class to jsp page.

but as you said you don't want scriptlet in you jsp page, you should consider to let user starts from *.do in the first place, that's what we usually do in a struts application.
0
 
chambers777Author Commented:
>>let user starts from *.do
How would I do that?


What about writing my own custom tag to create the variable?
0
 
kennethxuCommented:
>> How would I do that?
I think you must gvie the url to the jsp page to the user or put it in another page as a link. it is as simple as change that to your *.do.

>> What about writing my own custom tag to create the variable?
you can for sure do that, but I think it is overkilled and the struts framework is designed for you to prepared objects required by the jsp page in the action class.

As you know MVC, user should come to controller(C-action), controller prepare for data model (M-the bean array) and then display the view (V-jsp page). Now you are going to the view directly, that is where the problem occurs.
0
 
chambers777Author Commented:
You'll have to excuse my complete ignorance on struts. (I do understand the logic, but not the implementation, yet :))

If I let the user start at the *.do, I will need two ActionMappings, correct? One to display the form (start.do) and one to validate and submit it (validate.do)?

Suppose that the the form is submitted invalid and must be redisplayed... will I need to prepare my beans in the validate.do again, or will they still be available?

0
 
kennethxuCommented:
well, there are options. as I said, if you would let user start from the jsp page. then you need the get the list in the jsp page.

I would let user starts from the *same* action class, e.g. register.do
you don't do any validation if the request com in as GET or you can always check if the submit button is clicked.
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 7
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now