Announcement Announcement Module
Collapse
No announcement yet.
Populating forms based on drop down list Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Populating forms based on drop down list

    Hi, i have the following JSP form

    Code:
    <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
    <%@ taglib uri="http://www.springframework.org/tags" prefix="Spring" %>
    
    <html>
    <head>
    <title>
    Object Form
    </title>
    </head>
    
    <body bgcolor="#ffffff">	
    <form method="post">	
    <table border="1">	      
    <tr>
      <td>ProfileId</td>
      <td>
    	<select name="profileId">
    		<c:forEach var="postProfile" items="${postProfileList}">
    		<option value="<c:out value="${postProfile.profileId}" />">
    			IDNO<c:out value="${postProfile.profileId}" />
    		</option>
    		</c:forEach>
    	</select>
      </td>
    </tr>			 	
    <tr>
    	<td>PostProfilestatus</td>
    	<td>
    		<Spring:bind path="postprofiles.postProfilestatus">
    			<input type="text" name="postProfilestatus"  value="${status.value}" />
    		</Spring:bind>
    	</td>
    </tr>
    <tr>
    	<td>Musterings</td>
    	<td>
    		<Spring:bind path="postprofiles.musterings">
    			<input type="text" name="musterings"  value="${status.value}" />
    		</Spring:bind>
    	</td>
    </tr>	      		
    <tr>
    	<td>Ranks</td> 
    	<td>
    		<Spring:bind path="postprofiles.ranks">
    			<input type="text" name="ranks"  value="${status.value}" />
    		</Spring:bind>
    	</td>
    </tr>	  	    		
    <tr>
    	<td>UnitCode</td> 
    	<td>
    		<Spring:bind path="postprofiles.unitCode">
    			<input type="text" name="unitCode"  value="${status.value}" />
    		</Spring:bind>
    	</td>
    </tr>	  	    
    <tr>
    	<td>Statusreason</td>   
    	<td>
    		<Spring:bind path="postprofiles.statusreason">
    			<input type="text" name="statusreason"  value="${status.value}" />
    		</Spring:bind>
    	</td>
    </tr>		
    <tr>
    	<td>CrtDat</td>
    	<td>
    		<Spring:bind path="postprofiles.crtDat">
    			<input type="text" name="crtdat" size="20" value="${status.value}"/>
    		</Spring:bind>
    	</td>
    </tr>			
    <tr>
    	<td>CrtId</td>
    	<td>
    		<Spring:bind path="postprofiles.crtId">
    			<input type="text" name="crtid" size="20" value="${status.value}"/>
    		</Spring:bind>
    	</td>
    </tr>			
    <tr>
    	<td>ChgDat</td>
    	<td>
    		<Spring:bind path="postprofiles.chgDat">
    			<input type="text" name="chgdat" size="20" value="${status.value}"/>
    		</Spring:bind>
    	</td>
    </tr>			
    <tr>
    	<td>ChgId</td>
    	<td>
    		<Spring:bind path="postprofiles.chgId">
    			<input type="text" name="chgid"  value="${status.value}"/>
    		</Spring:bind>
    	</td>
    </tr>			      
    <tr>
    	<td><input type="submit" name="delete" value="Delete"/></td>
    	<td><input type="submit" name="update" value="Update"/></td>
    </tr>				
    <tr>
    	<td colspan="2"><input type="submit" name="add" value="+ Add +"/></td>
    </tr>		      
    </table>    	
    </form>
    </body>
    </html>
    Here's is its controller class

    Code:
    package com.jobpost.controller;
    
    import java.util.Map;
    import java.util.List;
    import java.util.HashMap;
    
    import com.jobpost.postprofile.*;
    import com.jobpost.service.PostProfileService;
    
    import org.apache.commons.logging.*;
    import org.springframework.web.servlet.*;
    import org.springframework.web.servlet.mvc.*;
    import org.springframework.web.servlet.view.*;
    import javax.servlet.http.*;
    import javax.servlet.ServletException;
    import org.springframework.validation.BindException;
    
    public class PostProfileFormController extends SimpleFormController {
    
        protected final Log logger = LogFactory.getLog(getClass());
        private PostProfileService pps;
    
        public PostProfileService getpps() {
    
            return pps;
        }
    
        public void setpps(PostProfileService pps) {
    
            this.pps = pps;
        }
    
    	protected Map<String, List<PostProfiles>> referenceData(HttpServletRequest request) throws ServletException {
    		List<PostProfiles> pplist = pps.getAllPostProfiles();
    		Map<String, List<PostProfiles>>  model = new HashMap<String, List<PostProfiles>>();
    		model.put("postProfileList", pplist);
    		return model;
    	}
    	
        protected Object formBackingObject(HttpServletRequest request) throws
                ServletException {
            String id = request.getParameter("profileId");
            logger.debug(" ********** Profile ID is = " + id + "************");
            if (null != id && !id.equals("")) {
                return pps.findPostProfilesById(Long.parseLong(id));
            }
            return new PostProfiles();
        }
    }
    The program has a drop down list profileId and it successfully load all the profile Id's on the dropdown menu ... But! i need help in doing the following

    1. After the user select the ID from the dropdown, it should populate the form with the new data associated with that profile ID

    2. How do i spring bind this profileId value selected by the user to the object's postProfile.profileId?

  • #2
    1. For dynamic select choices I would use AJAX. DWR integrates with Spring really well.

    2. Use Spring form select (and option) tag(s).
    http://static.springframework.org/sp...orm.tld.select

    In some cases it quite handy to create some custom property editors to map the user data with backend command object's property.
    I think you can find some examples from this forum and from the Net.

    Comment


    • #3
      Hi,
      Also remember to use LinkedHashMap for dropdown maps.
      The linked hash map keeps the order of the inserted elements.

      Code:
      Map<String, List<PostProfiles>>  model = new LinkedHashMap<String, List<PostProfiles>>();
      /Erik

      Comment


      • #4
        Originally posted by Erik.Lund.Jensen View Post
        Hi,
        Also remember to use LinkedHashMap for dropdown maps.
        The linked hash map keeps the order of the inserted elements.

        Code:
        Map<String, List<PostProfiles>>  model = new LinkedHashMap<String, List<PostProfiles>>();
        /Erik
        Hi Erik, could you help here please ... I'm quite new on spring and wouldn't like to go through AJAX as yet as this will be too much to handle. I'm sure i should be able to handle this with simpleFormController ... below is my function

        Code:
        protected Object formBackingObject(HttpServletRequest request) throws
        		ServletException {
        	
        	/**
        	 * Read from the profileID field parameter
        	 */
        	
        	String id = request.getParameter("profileId");		
        	if ( id != null && !id.equals("") && isFormSubmission(request))	
        	{
        		return pps.findPostProfilesById(Long.parseLong(id));			
        		
        	}	
        	
        	/**
        	 * Read from the URL parameter
        	 */
        	
        	String pid = request.getParameter("id");
        	//logger.debug("** PID is :"+pid+" **");
        	if (null != pid && !pid.equals("")) {
        		return pps.findPostProfilesById(Long.parseLong(pid));
        	}
        	
        	return new PostProfiles();
        }
        as you can see there's two IDs one from URL (id) and the other from the dropdown (profileId) ... This doesn't seem to work ... i used log4j to check if the first if statement is executed, and yes it does execute but the form doesn't populate. On the log4j logger i noticed there an error (but no exception thrown)
        which states ... binding errors: 2, but no further info ???[EDIT] I think this error is coming from processFormSubmission method[/EDIT]

        Is this the right place to do this?

        Comment


        • #5
          Is it really that complex to populate the same formView after a refresh or press of button with data loaded from the database based on the selected dropdown option? All i need is...

          1. Which of the methods should i be doing this (as you can see above i tried this on formBackingObject by checking isFormSubmission)
          2. What code should ensure this will be done successfully...

          As i have submitted my code, i really have tried my best .. I even tried setting the bindOnNewForm to true but no luck

          Please some1 help me!!!

          Comment


          • #6
            1) For some reason it looks to complex
            2) Your jsp is wrong, with your current jsp there is no binding going to happen ever.
            3) Instead of bind tags use form tags, this also saves you from 2
            4) Use a form:errors tag to display validation/error messages.

            It looks like you don't have the basics yet, I suggest the reference guide and the sample applications those should give you more clarity.

            Why didn't you make it a 2 (3) step process.

            Start by selecting an existing one, then either delete or update it (delete simply deleting it, update showing an update page with fields filled out) or by pressing an Add/New buttong (again showing the update page but an empty one).

            Would reduce your complexity.

            If you can use annotations it would be a easier to implement then your current solution.

            Code:
            <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
            <%@ taglib uri="http://www.springframework.org/tags.form" prefix="form" %>
            <html>
            <head>
            <title>Object Form</title>
            </head>
            
            <body bgcolor="#ffffff">	
            <form:form method="post" modelAttribute="postprofiles">	
            <table border="1">	      
            <tr>
              <td>ProfileId</td>
              <td>         
            	<select name="profileId">
            		<c:forEach var="postProfile" items="${postProfileList}">
            		<option value="<c:out value="${postProfile.profileId}" />">
            			IDNO<c:out value="${postProfile.profileId}" />
            		</option>
            		</c:forEach>
            	</select>
              </td>
            </tr>			 	
            <tr>
            	<td>PostProfilestatus</td>
            	<td>
                <form:input path="postProfilestatus" />
                <form:errors path="postProfilestatus" />
            	</td>
            </tr>
            <tr>
            	<td>Musterings</td>
            	<td>
                <form:input path="musterings" />
                <form:errors path="musterings" />
            	</td>
            </tr>	      		
            <tr>
            	<td>Ranks</td> 
            	<td>
                <form:input path="ranks" />
                <form:errors path="ranks" />
            	</td>
            </tr>	  	    		
            <tr>
            	<td>UnitCode</td> 
            	<td>
                <form:input path="unitCode" />
                <form:errors path="unitCode" />
            	</td>
            </tr>	  	    
            <tr>
            	<td>Statusreason</td>   
            	<td>
                <form:input path="statusreason" />
                <form:errors path="statusreason" />
            	</td>
            </tr>		
            <tr>
            	<td>CrtDat</td>
            	<td>
                <form:input path="crtDat" />
                <form:errors path="crtDat" />
            	</td>
            </tr>			
            <tr>
            	<td>CrtId</td>
            	<td>
                <form:input path="crtId"/>
                <form:errors path="crtId"/>	
              </td>
            </tr>			
            <tr>
            	<td>ChgDat</td>
            	<td>
                <form:input path="chgDat" />
                <form:errors path="chgDat" />
            	</td>
            </tr>			
            <tr>
            	<td>ChgId</td>
            	<td>
                <form:input path="chgid" />
                <form:errors path="chgid" />	
              </td>
            </tr>			      
            <tr>
            	<td><input type="submit" name="delete" value="Delete"/></td>
            	<td><input type="submit" name="update" value="Update"/></td>
            </tr>				
            <tr>
            	<td colspan="2"><input type="submit" name="add" value="+ Add +"/></td>
            </tr>		      
            </table>    	
            </form:form>
            </body>
            </html>
            Annotated controller
            Code:
            @Controller
            @RequestMapping(/yourmapping here)
            public class PostProfileFormController {
            
              protected final Log logger = LogFactory.getLog(getClass());
                
              @Autowired  
              private PostProfileService pps;
            
              @ModelAttribute("postProfileList")
              public List<PostProfiles> referenceData() {
                return pps.getAllPostProfiles();
              }
            
              @RequestMapping(method=RequestMethod.GET)
              public String setup(@RequestParam(value="id", required=false) Long id, Model model) {
                if (id != null) {
                  model.addAttribute("postprofiles", pps.findPostProfilesById(id));
                } else {
                  model.addAttribute("postprofiles", new PostProfiles());
                }
                return "which view to show";
              }
            
              @RequestMapping(params={"delete"})
              public String delete(@RequestParam(value="profileId") Long id) {
                //delete based on id
                return "which view to show";
              }
            
              @RequestMapping(params={"update"})
              public String update(@ModelAttribute("postprofiles") PostProfiles postProfile, BindingResult result) {
                if (result.hasErrors() ) {
                  //when errors show initial view again
                  return "which view to show";
                }
                // update
                //reshow view
                return "which view to show"
              }
            
              @RequestMapping(params={"add"})
              public String update(@ModelAttribute("postprofiles") PostProfiles postProfile, BindingResult result) {
                if (result.hasErrors() ) {
                  //when errors show initial view again
                  return "which view to show";
                }
                // add to database
                //reshow view
                return "which view to show"
              }
              
            
            }
            Last edited by Marten Deinum; Nov 11th, 2008, 01:41 AM.

            Comment


            • #7
              Originally posted by Marten Deinum View Post
              1) For some reason it looks to complex
              2) Your jsp is wrong, with your current jsp there is no binding going to happen ever.
              3) Instead of bind tags use form tags, this also saves you from 2
              4) Use a form:errors tag to display validation/error messages.
              Oops! looks like i replied on the old posting because i have updated the code yesterday already...

              Marten, Could you kindly comment rather on the new code i had since yesterday below .. still getting the same problem ... Your help gives me hope!! Thanx

              Here's my JSP
              Code:
              <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
              <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
              
              <html>
              	<head>
              	  <title>
              	    Object Form
              	  </title>
              	</head>
              	
              	<body bgcolor="#ffffff">	
              		<form:form commandName = "postprofiles">	
              		    <table border="1">	      
              				<tr>
              				  <td>ProfileId</td>
              				  <td>
              					<select name="profileId">
              						<option value="">-- Select ID from List --</option>
              					    <c:forEach var="postProfile" items="${postProfileList}">
              					    <option value='<c:out value="${postProfile.profileId}"/>'
              					    	<c:if test="$status.value == postProfile.profileId">selected</c:if>>
              					        <c:out value="${postProfile.profileId}" />
              					    </option>
              					    </c:forEach>
              					</select>
              				</td>					
              				</tr>			 	
              				<tr>
              					<td>PostProfilestatus</td>
              					<td>
              						<form:input path="postProfilestatus" />
              					</td>
              				</tr>
              				<tr>
              					<td>Musterings</td>
              					<td>
              						<form:input path="musterings" />
              					</td>
              				</tr>	      		
              				<tr>
              					<td>Ranks</td> 
              					<td>
              						<form:input path="ranks"/>
              					</td>
              				</tr>	  	    		
              				<tr>
              					<td>UnitCode</td> 
              					<td>
              						<form:input path="unitCode"/>
              					</td>
              				</tr>	  	    
              			 	<tr>
              					<td>Statusreason</td>   
              					<td>
              						<form:input path="statusreason"/>
              					</td>
              				</tr>		
              				<tr>
              					<td>CrtDat</td>
              					<td>
              						<form:input path="crtDat"/>
              					</td>
              				</tr>			
              				<tr>
              					<td>CrtId</td>
              					<td>
              						<form:input path="crtId"/>
              					</td>
              				</tr>			
              				<tr>
              					<td>ChgDat</td>
              					<td>
              						<form:input path="chgDat"/>
              					</td>
              				</tr>			
              				<tr>
              					<td>ChgId</td>
              					<td>
              						<form:input path="chgId"/>
              					</td>
              				</tr>			      
              				<tr>
              					<td><input type="submit" name="delete" value="Delete"/></td>
              					<td><input type="submit" name="update" value="Update"/></td>
              				</tr>				
              				<tr>
              					<td colspan="2"><input type="submit" name="add" value="+ Add +"/>
              					<input type="submit" name="reload" value="+ Reload +"/></td>
              				</tr>		      
              			</table>    	
              		</form:form>
              	</body>
              </html>
              My Controller
              Code:
              public class PostProfileFormController extends SimpleFormController {
              
                  protected final Log logger = LogFactory.getLog(getClass());
                  private PostProfileService pps;
              	
                  /**
                   * Gets the injected service
                   * @return PostProfileService instance
                   */
                  
                  public PostProfileService getpps() {
                      return pps;
                  }
              
                  /**
                   * Injector setpps
                   * To Inject PostProfileService to the Controller Class ...(IoC/DI) concept
                   */
              
                  public void setpps(PostProfileService pps) {
                      this.pps = pps;
                  }
                  
                  /**
                   *  OnSubmit Method
                   *  
                   *  Handles form POSTs. 	
                   *  Taks : Updates persistent objects with form data from user using command object,
                   *  and on success forwards to SuccessForms or formView on error
                   */
                  public ModelAndView onSubmit(HttpServletRequest request,
                                               HttpServletResponse response, Object cmd,
                                               BindException errors) throws Exception {
                      logger.debug(
                              "Entering PostProfileFormController handleRequest method ....");
                      
                      PostProfiles postProfiles = (PostProfiles) cmd;
              				
                      /**
                       * Respond to button presses and populate database using the service object (business logic ... CRUD)
                       */
                      if (null != request.getParameter("delete")) {
                          System.out.println("[Delete] button pressed ... ");
                          pps.removePostProfiles(postProfiles);		
                      } else if (null != request.getParameter("update")) {
                          pps.updatePostProfiles(postProfiles);
                          System.out.println("[Update] button pressed ... ");
                      } else if (null != request.getParameter("add")) {
                          pps.insertPostProfiles(postProfiles);
                          System.out.println("[Add] button pressed ... ");
                      }
              
                      /**
                       * Forward to SuccessView ... 
                       */
              		return new ModelAndView(new RedirectView(getSuccessView()));
                  }
                  
                
              	protected Map<String, List<PostProfiles>> referenceData(HttpServletRequest request) throws ServletException {
              		List<PostProfiles> pplist = pps.getAllPostProfiles();
              		Map<String, List<PostProfiles>>  model = new LinkedHashMap<String, List<PostProfiles>>();
              		model.put("postProfileList", pplist);
              			
              		return model;
              	}
              	
              	protected Object formBackingObject(HttpServletRequest request) throws
                          ServletException {
              
              		String pid = request.getParameter("id");
              		logger.debug("** PID is :"+pid+" **");
              		
                      if (null != pid && !pid.equals("")) {
              			return pps.findPostProfilesById(Long.parseLong(pid));
                      }
                      
                      return new PostProfiles();
                  }
              
              }
              My Action-Servlet

              Code:
              <?xml version="1.0" encoding="UTF-8"?>
              <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
              
              <beans>
              
                <!-- Fixed VIEW/CONTROLLER properties -->
                
                <!-- Setting the views (JSP/JSTL, etc) -->
                <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
                  <property name="prefix"><value>/jsp/</value></property>
                  <property name="suffix"><value>.jsp</value></property>
                </bean>
                 
                <!-- *** Custom Controller Objects *** -->
                
                <!--  To Display the Objects (List View URL) -->
                <bean id="ppController" class="com.jobpost.controller.PostProfileController">
                  <property name="postProfileService"><ref bean="postProfileService"/> </property>
                </bean>
              
                <!--  To Edit the Objects (Form Edit/View URL)-->
                <bean id="ppFormController" class="com.jobpost.controller.PostProfileFormController">
                  <property name="sessionForm"><value>false</value></property>
                  <property name="bindOnNewForm"><value>true</value></property>	
              	<property name="commandName"><value>postprofiles</value></property>
                  <property name="commandClass"><value>com.jobpost.postprofile.PostProfiles</value></property>
                  <property name="formView"><value>PostProfileForm</value></property> <!-- Interesting, you cannot add the suffix here, it will append the .jsp -->
                  <property name="successView"><value>index.html</value></property> <!-- you MUST add the suffix here, otherwise it won't append the suffix itself -->
              
                  <property name="pps"><ref bean="postProfileService"/></property>
                </bean>
              
                <!-- URLs mapped to their respective controller objcects, see above -->
                <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                  <property name="mappings">
                    <props>
                      <prop key="/index.html">ppController</prop>     
                      <prop key="/PostProfileForm.html">ppFormController</prop>
                    </props>
                  </property>
                </bean>
              
              </beans>
              Please not that i have set sessionForm to false that backingFormObject is forcefully called when i press the reload button, but no luck yet...

              Oh! also, why does the drop-down list not receiving the selected ID from the URL parameter? this id comes from a different jsp file (through GET)

              Comment


              • #8
                Well your select is obviously never going to be selected, neither is there anything going to be selected in your controller.

                In your select you are doing a status.value, what is status here?!!! Also in your controller you check id, your select is named profileId. So that is never going to match.

                Also your controller has a big flaw.

                Your flaw:
                If some starts updating an instance, then selects a different one from the drop down, presses update then the newly selected one is going to have the new fields bound instead of the one that was initially edited (hence my 2 step approach).

                I would either make it a 2 step approach or at least create 2 independ forms.

                Comment


                • #9
                  Originally posted by Marten Deinum View Post
                  Well your select is obviously never going to be selected, neither is there anything going to be selected in your controller.

                  In your select you are doing a status.value, what is status here?!!! Also in your controller you check id, your select is named profileId. So that is never going to match.

                  Also your controller has a big flaw.

                  Your flaw:
                  If some starts updating an instance, then selects a different one from the drop down, presses update then the newly selected one is going to have the new fields bound instead of the one that was initially edited (hence my 2 step approach).

                  I would either make it a 2 step approach or at least create 2 independ forms.
                  I actually just added the if statement because i was trying to make it work, i can just remove it again ...

                  Marten, am really new on Spring MVC and have read quite a lot to read and learn as it is. I understand the concept but as a beginner i need support on applying what i've learned. The challenge i have is my team is using struts framework and i have to convince them that spring is the way to go. The first achievement is to get this small application to run by getting data from database, use dropdown list to allow selection of IDs, then populate the form with the data fetched from database based on ID.

                  You are now introducing me to annotated controllers, which i appreciate but there's too many new things and haven' got any working well ... Can i somehow use the 2 step approach still using my code? Then maybe later i can learn to use annotated controll .. I will for now update my JSp to have validations ...

                  Thanx

                  Comment


                  • #10
                    Originally posted by Marten Deinum View Post
                    Well your select is obviously never going to be selected, neither is there anything going to be selected in your controller.

                    In your select you are doing a status.value, what is status here?!!! Also in your controller you check id, your select is named profileId. So that is never going to match.
                    Here's my select

                    Code:
                    <select name="profileId">
                    	<option value="">-- Select ID from List --</option>
                    	<c:forEach var="postProfile" items="${postProfileList}">
                    	<option value='<c:out value="${postProfile.profileId}"/>'>
                    	<c:out value="${postProfile.profileId}" />
                    	</option>
                    	</c:forEach>
                    </select>
                    By using request.getparameter("profileId"); i do get the selected value ... But this field always shows "-- Select ID from List --" ... Even after the first loading of the form. I expect it to show the ID which is passed through the parameters when the form is created for the first time ...
                    Last edited by SonxSprn7; Nov 11th, 2008, 02:36 AM.

                    Comment

                    Working...
                    X