Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 32

Thread: Spring XT: doAjaxSubmit in a wizard form

  1. #21

    Default

    Here is my Controller

    Code:
    public class NewCustomerWizardController extends AbstractWizardFormController
    {
        private static final Log log = LogFactory.getLog(NewCustomerWizardController.class);
    
        public NewCustomerWizardController()
        {
            this.setAllowDirtyBack(true);
            this.setPages(new String[] { "newcustintro", "newcustprofile", "newcustcontacts", "newcustrefs", "newcustguar",
                    "newcustdocs" });
        }
    
       @Override
        protected ModelAndView processFinish(HttpServletRequest request, HttpServletResponse response, Object command,
            BindException errors) throws Exception
        {
            return new ModelAndView("redirect:custoverview.htm", "customerId", ((CustomerCommand)command).getId());
        }
    
        @Override
    
        protected ModelAndView processCancel(HttpServletRequest request, HttpServletResponse response, Object command,
            BindException errors) throws Exception
        {
            return new ModelAndView(new RedirectView("home.htm"));
        }
        @Override
        protected Object formBackingObject(HttpServletRequest request) throws Exception
        {
            CustomerCommand command = new CustomerCommand();
            command.setCustomer(new Customer());
            return command;
        }
    
        @Override
        protected Map referenceData(HttpServletRequest request, Object command, Errors errors, int page) throws Exception
        {
        	Map<String, Object> refData = new HashMap<String, Object>();
            refData.put("stateList", DMOperations.getStates());
            return refData;
        }
    
        @Override
        protected boolean suppressValidation(HttpServletRequest request)
        {
            if ( (request.getParameter("_addDBA") != null) 
            {
                return true;
            }
            return super.suppressValidation(request);
        }
    
        @Override
        protected void postProcessPage(HttpServletRequest request, Object _command, Errors errors, int page)
            throws Exception
        {
            //If there is errors during validation, do nothing.
            if(errors.getErrorCount() >=1)
                return;
            CustomerCommand command = (CustomerCommand) _command;
            if (request.getParameter("_addDBA") != null)
            {
                command.addDba(new DBA());
                return;
            }
    }
    }
    As you can see, I have overridden the postProcessPage to handle the addDBA request in the wizard.

    As of now, I'm having the following code in the jsp.

    Code:
    <table class="mytable" id="dbaList" summary="DBAS" width="90%">
    	<caption>
    		<span> Doing Business As </span>
    		<input type="submit" name="_addDBA" value="Add" tabindex="7">
    	</caption>
    	<tbody id="dbas">
    		<c:forEach items="${newCustomer.dbas}" var="dba" varStatus="counter">
    			<tr>
    				<td>
    				<form:input path="dbas[${counter.index}].name" size="40" />				 
    				</td>
    			</tr>
    		</c:forEach>
    	</tbody>
    </table>
    Where the jsp is getting the DBA list from the command. (Thats the reason I'm not using referenceData method to populate the DBAList)

    From your initial page load answer, can I assume, I can have the code inside table body as it is? If so, will the ajaxAction response will override the content of the body?

    On a side note, I'm looking all over the world to have a good solution.

    I need exactly same as struts-layout datagrid behavior, where you can add multiple items in a table and save all during submit. They use javascript solution and nicely intergated with struts tag library.
    http://struts.application-servers.co...o?reqCode=edit

    My other option is to use javascript to add the rows and have to figure out how to bind the values in the command object.

    Thanks

  2. #22
    Join Date
    Jul 2006
    Location
    Rome, Italy
    Posts
    347

    Default

    Quote Originally Posted by surya_vus View Post
    Here is my Controller
    [CUT]
    At a first glance, it seems to be ok. However, I'm very overloaded right now, so I'll give it a deeper look later.
    In the meantime, is there any other info you can give me about the null command object problem?

    will the ajaxAction response will override the content of the body?
    The ajax action will not override anything if you use an action that actually just add contents (see javadocs).

    On a side note, I'm looking all over the world to have a good solution.
    I need exactly same as struts-layout datagrid behavior, where you can add multiple items in a table and save all during submit.
    I don't know how Struts Layout does that, but there's an XT Ajax sample that seems to do something similar: check out, build and deploy XT samples.

    Let me know if you need more info.

    Cheers,

    Sergio B.
    Sergio Bossa
    Spring Modules Team

  3. #23

    Default

    Sergio,

    Yes, you are right. The example 5 seems to be having similar behavior. But unfortunatly I could not make it to work.

    When select the "Add" button nothing happens, except the following WARN statement in the console.

    Code:
    WARN AjaxInterceptor:105 - Pre-handling ajax request for event: addEmployee
    And for Example 4, I'm getting classdefnotfound error,

    Code:
    java.lang.NoClassDefFoundError: net/sf/json/JSONObject
    	at org.springmodules.xt.ajax.action.prototype.scriptaculous.HighlightAction.getJavascript(HighlightAction.java:79)
    	at org.springmodules.xt.ajax.action.AbstractExecuteJavascriptAction.execute(AbstractExecuteJavascriptAction.java:34)
    	at org.springmodules.xt.ajax.AjaxResponseImpl.getResponse(AjaxResponseImpl.java:43)
    	at org.springmodules.xt.ajax.AjaxInterceptor.postHandle(AjaxInterceptor.java:201)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:729)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:663)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:394)
    	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:358)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)

    I think if I can make the example 5 to woprk, I will get an idea. Than I will try to do the same with my app.

    Thanks a lot.....

  4. #24
    Join Date
    Jul 2006
    Location
    Rome, Italy
    Posts
    347

    Default

    Quote Originally Posted by surya_vus View Post
    Yes, you are right. The example 5 seems to be having similar behavior. But unfortunatly I could not make it to work.
    When select the "Add" button nothing happens
    It is very strange, examples work well here, and no other user noticed these problems.
    Does your javascript console show any error?
    Have you tried to debug the code?

    And for Example 4, I'm getting classdefnotfound error,
    [CODE]java.lang.NoClassDefFoundError: net/sf/json/JSONObject
    You missed the JSON-Lib jar: http://json-lib.sourceforge.net/

    I think if I can make the example 5 to woprk, I will get an idea. Than I will try to do the same with my app.
    I'm running out of ideas, I don't know why you get all these errors: have you carefully looked at your tomcat (or jetty) log? Is there any other exception?

    Let me know *everything* you know.

    Cheers,

    Sergio B.
    Sergio Bossa
    Spring Modules Team

  5. #25
    Join Date
    Jul 2006
    Location
    Rome, Italy
    Posts
    347

    Default

    Hi Surya,

    I've just committed the fixes for solving the null pointer exceptions in components.
    Update to the latest CVS code as usual.

    Cheers,

    Sergio B.
    Sergio Bossa
    Spring Modules Team

  6. #26

    Default

    Sergio,

    After I added the json and ezmorph jars in the libs the example 4 and 5 are working.

    I will get your latest code from CVS and let you know how it goes.

    Thanks
    Surya

  7. #27

    Question

    Sergio,

    I got your new code.. I may sound stupid, but anyway, here is my story.

    I'm getting the command object and its association in the ajaxhandler.
    Here is my current handler code

    Code:
    public class CustomerAjaxHandler extends AbstractAjaxHandler
    {
        public AjaxResponse addDBA(AjaxActionEvent event)
        {
            int dbaCounter = Integer.parseInt(event.getHttpRequest().getParameter("dbacounter"), 10);
            
            AbstractCustomerCommand command = (AbstractCustomerCommand)event.getCommandObject();
    
            DBA newDba = new DBA();
    
            // Create a concrete ajax response:
            AjaxResponse response = new AjaxResponseImpl();
    
            if(command!=null)
            {
              Set<DBA> dbas = command.getDbas();
              command.addDba(newDba);
    
              InputField dbaField = new InputField(newDba.getName(), "", InputField.InputType.TEXT);
    
              TableRow row = new TableRow();
    
              TableData data = new TableData(dbaField);
    
              row.addTableData(data);
    
              // Create an ajax action for appending the new row:
              AppendContentAction appendRowAction = new AppendContentAction("dbas", row);
    
              // Create an ajax action for updating the employees counter:
              SetAttributeAction updateCounterAction = new SetAttributeAction("dbacounter", "value", "" + (dbaCounter + 1));
    
              // Add actions:
              response.addAction(appendRowAction);
              response.addAction(updateCounterAction);
              
            }
            
            
    
            return response;
        }
    }
    I'm able to add a editable row in the table. So for good.

    I created another simple page and a SimpleFormController to reduce some noise.

    Here is my new controller

    Code:
    public class DBATestController extends SimpleFormController
    {
        private static final Log log = LogFactory.getLog(DBATestController.class);
        
        public DBATestController()
        {
    //       this.setSessionForm(true);
           this.setCommandName("customerCommand");
        }
        
        @Override
        protected Object formBackingObject(HttpServletRequest request) throws Exception
        {
            CustomerCommand command = new CustomerCommand();
            command.setCustomer(new Customer());
            return command;
        }
        
        @Override
        protected void doSubmitAction(Object command) throws Exception
        {
            Set<DBA> dbaset = ((CustomerCommand)command).getDbas();
            log.debug("dba size > " + dbaset.size());
            for(DBA dba : dbaset) 
            {
                log.debug(">>>>>>>>>>>>>>>>>>>" + dba.getName());
            }
        }
        
        
    
    }
    Here is the jsp page

    Code:
    <form:form commandName="customerCommand">
    	<fieldset>
    		<table summary="main" width="98%" border="0">
    			<tr>
    				<td colspan="2">
    					<form:label path="customer.name">
    							Customer Name
    						</form:label>
    					<span class="required">*</span>
    				</td>
    				<td></td>
    			</tr>
    			<tr>
    				<td colspan="2">
    					<form:input path="customer.name" size="50" maxlength="50"
    						tabindex="1" />
    				</td>
    			</tr>
    			<tr>
    				<td colspan="2">
    					<form:errors cssClass="errorBox" path="customer.name" />
    				</td>
    			</tr>
    			<tr>
    				<td colspan="3" rowspan="2" valign="top">
    					<div class="tablewrapper1">
    						<table class="acetable" id="dbaList" summary="DBAS" width="90%">
    							<caption>
    								<span> Doing Business As</span>
    							<input type="button" value="Add" name="_addDBA" onclick="doAjaxAction('addDBA', this);" tabindex="7">
    							</caption>
    							<tbody id="dbas">
    								<c:forEach items="${newCustomer.dbas}" var="dba" varStatus="counter">
    									<tr>
    										<td>
     										<form:input path="dbas[${counter.index}].name" size="40" />				 
    										</td>
    									</tr>
    								</c:forEach>
    							</tbody>
    						</table>
    					</div>
                        <input type="hidden" name="dbacounter" id="dbacounter" value="0"/>
    				</td>
    			</tr>
    			<tr>
    				<td>
    					<form:errors cssClass="errorBox" path="customer.dbas" />
    				</td>
    			</tr>
    		</table>
    	</fieldset>
    	<div class="formcontrols">
    		<input type="submit" value="Save" style="float:right;margin-left:5px"
    			name="Save" />
    	</div>
    	<%--	<form:errors path="*" cssClass="errorBox" />--%>
    </form:form>

    So whats happening now is. when I do a SAVE after adding DBAs, the log

    Code:
    log.debug("dba size > " + dbaset.size());
    shows the size is 0.

    But when I uncomment setSessionForm(true); of the controller, I'm getting the current size, but with the DBA names as null.

    I'm lost here!!!

    All I want to do is update a table(collection of objects) data, with out refreshing the whole page.

    I tried DWR (Could not directly add DBA in the backend as there is no customer created yet), AJAXTags (Could not figure out how to chain tilesView and JSTLView together), javascript (Could not figure out how to bind the javascript created input fields) and XT(you know the story!) with no success.

    Is using tiles with Spring MVC went wrong? or my choice SpringMVC against Struts proved wromg? I don't know.

    Anyway, thanks for your help so for.

  8. #28
    Join Date
    Jul 2006
    Location
    Rome, Italy
    Posts
    347

    Default

    Quote Originally Posted by surya_vus View Post
    Code:
    InputField dbaField = new InputField(newDba.getName(), "", InputField.InputType.TEXT);
    Surya, here is your fault: you are creating a simple input field that doesn't bind *anything*.
    You have to create an input field that binds on a command path, i.e. : "command.customer.name".
    You could use the new BindStatusHelper (see XT Ajax example 5) and write something like this:
    Code:
    BindStatusHelper helper = new BindStatusHelper("customerCommand.customer.dbas"); // <-- Creates a SpringMVC binding expression, like the 1.2.X binding tag.
    InputField dbaField = new InputField(helper.getStatusExpression(), "...", InputField.InputType.TEXT);
    This is the approach used in the sample: however, it is not the same as yours, so you have to do something different.

    First, fix your InputField declaration in your Ajax handler:
    Code:
    BindStatusHelper helper = new BindStatusHelper("customerCommand.customer.dbas[" + command.getDbas().size() + "].name");
    InputField dbaField = new InputField(helper.getStatusExpression(), "", InputField.InputType.TEXT);
    This is because you are adding an input field that must bind on the latest customer dba!

    Then, fix your "for each" loop in your jsp code (it seems to be wrong, actually):
    Code:
    								<c:forEach items="${customerCommand.customer.dbas}" var="dba" varStatus="counter">
    									<tr>
    										<td>
     										<form:input path="customer.dbas[${counter.index}].name" size="40" />				 
    										</td>
    									</tr>
    								</c:forEach>
    So whats happening now is. when I do a SAVE after adding DBAs, the log
    Code:
    log.debug("dba size > " + dbaset.size());
    shows the size is 0.
    But when I uncomment setSessionForm(true); of the controller, I'm getting the current size, but with the DBA names as null.
    Following your approach, the session form property *must* be set to true: otherwise, you lose all dbas added in the Ajax handler.

    So, apply the fixes above and set the session form property to true: everything should work.

    Let me know.

    Cheers,

    Sergio B.
    Sergio Bossa
    Spring Modules Team

  9. #29

    Thumbs up

    THANK YOU VERY MUCH SERGIO.

    IT WORKS NOW !!!!!

    Here is the final ajaxhandler code

    Code:
       public AjaxResponse addDBA(AjaxActionEvent event)
        {
    //        System.out.println(" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>AjaxResponse  addDBA (AjaxActionEvent event)");
            AbstractCustomerCommand command = (AbstractCustomerCommand)event.getCommandObject();
    
            DBA newDba = new DBA();
            AjaxResponse response = new AjaxResponseImpl();
    
            if(command!=null)
            {
              command.addDba(newDba);
              int index = (command.getDbas().size())-1;
              BindStatusHelper helper = new BindStatusHelper("customerCommand.dbas[" + index + "].name");
              InputField dbaField = new InputField(helper.getStatusExpression(), "", InputField.InputType.TEXT);              
              dbaField.addAttribute("size", "40");
              TableRow row = new TableRow();
              TableData data = new TableData(dbaField);
              row.addTableData(data);
              // Create an ajax action for appending the new row:
              AppendAsFirstContentAction appendRowAction = new AppendAsFirstContentAction("dbas", row);
              // Add actions:
              response.addAction(appendRowAction);
            }
            return response;
        }
    Regarding jsp code, I do feel there is something wrong, but it works for now.

    I really appreciate your patience and help in resolving this issue.

    Let me explore more on XT farmework for other functionalities.


    Thank you
    Surya
    Last edited by surya_vus; Nov 14th, 2006 at 01:48 PM.

  10. #30
    Join Date
    Jul 2006
    Location
    Rome, Italy
    Posts
    347

    Default

    Quote Originally Posted by surya_vus View Post
    THANK YOU VERY MUCH SERGIO.
    IT WORKS NOW !!!!!
    Let me explore more on XT farmework for other functionalities.
    Well done.
    I'd be very happy if you could provide us more feedback about the XT Framework.

    Cheers!

    Sergio B.
    Sergio Bossa
    Spring Modules Team

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •