Announcement Announcement Module
Collapse
No announcement yet.
Cancel button for annotated portlet controller Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cancel button for annotated portlet controller

    I can't seem to figure out how to implement a form cancel button using an annotated portlet controller. I'm close, but the problem I am having is the canceled changes are still in the form when I come back to it.

    This is what my render code looks like

    Code:
        @RequestMapping
        // default render (action=list)
        public String showEditDefaults(Model model) {
    
            if (!model.containsAttribute("editDefaultsCommand")) {
    
                EditDefaultsForm editDefaultsCommand = new EditDefaultsForm();
                ...init editDefaultsCommand values
                model.addAttribute("editDefaultsCommand", editDefaultsCommand);
    
            }
            return "edit_defaults";
        }
    One fix would be to get rid of the check for the containsAttribute in the render code, but then this breaks Save if there is a validation error.

    My submit action looks like this

    Code:
    	@RequestMapping(params = "action=save")
    	// action phase
    	public void editDefaultsSubmit(ActionRequest request, ActionResponse response, @ModelAttribute("editDefaultsCommand") EditDefaultsForm editDefaultsForm, BindingResult result,
    			PortletPreferences preferences, SessionStatus sessionStatus) {
    
    		if (request.getParameter("_cancel") != null) {
    			sessionStatus.setComplete();
                            response.setPortletMode(javax.portlet.PortletMode.VIEW);
    		} else if (request.getParameter("_save") != null) {
    			new EditDefaultsFormValidator().validate(editDefaultsForm, result);
    			if (!result.hasErrors()) {
    				...persist values code
    				sessionStatus.setComplete();
                                    response.setPortletMode(javax.portlet.PortletMode.VIEW);
    			} else {
    				response.setRenderParameter("action", "list");
    			}
    		}
    	}
    Has anyone figured out how to code a form cancel button on an annotated portlet controller? I pieced together a cancel button from the forum posts for SimpleFormController that did the trick with the now deprecated supressBinding:

    Code:
        protected boolean suppressBinding(javax.portlet.PortletRequest request) {
            return isCancelButton(request);
        }
    
        private boolean isCancelButton(javax.portlet.PortletRequest request) {
            if (PortletUtils.hasSubmitParameter(request, "_cancel")) {
                return true;
            }
            return false;
        }
    Is there a similar way to accomplish this with the annotated portlet controller?

    Brad

  • #2
    Hmm. Seems like your call to SessionStatus.setComplete() should be having the desired effect by stopping that model entry from being persisted in the session across requests. Can you verify that you still seeing the edited object being persisted in the session after hitting cancel?

    Comment


    • #3
      John,

      Thank you for your reply. I think I found the problem but not the solution. The problem is JSR 286. I changed the portlet.xml from JSR 286 to JSR 168 and cancel is working well.

      I'm not using any JSR 286 features so this is no problem for this portlet - though it makes me wonder if this is a spring problem, a portlet container problem (WebSphere 6.1 in my case), or lack of understanding on my part as to how this type of thing should be carried out in JSR 286.

      I see the JSR 286 "problem" in 3.0.0M4 and the latest nightly.

      Brad

      Comment


      • #4
        Ah -- good catch. Go ahead and open a JIRA ticket for this, so we can make sure the SessionStatus stuff is working properly w/ JSR 286.

        Comment


        • #5
          JIRA SPR-6126 opened

          Comment


          • #6
            Did anyone else check whether 3.0.3 update fixed the issue?

            As I am currently testing it seems that it is not fixed.

            Will have to isolate example portlet into own project and add that to the issue so that others could see it too.

            Comment


            • #7
              Figured out what was wrong.

              I used status.setComplete() in portlet actionphase, which meant that even though the session attribute was properly cleared away it was later on added again into the session.

              See line 355 AnnotationMethodHandlerAdapter.java

              // Expose implicit model for subsequent render phase.
              if (response instanceof ActionResponse && !implicitModel.isEmpty()) {
              ActionResponse actionResponse = (ActionResponse) response;
              try { actionResponse.setRenderParameter(IMPLICIT_MODEL_A TTRIBUTE, Boolean.TRUE.toString()); request.getPortletSession().setAttribute(IMPLICIT_ MODEL_ATTRIBUTE, implicitModel); }
              catch (IllegalStateException ex) { // Probably sendRedirect called... no need to expose model to render phase. }
              }

              Not sure whether this is a bug, which should be fixed by adding another condition to the test?

              Anohow my problem went away by using sessionStatus.setComplete() in the render phase after the action phase.

              Comment


              • #8
                SessionStatus.setComplete() not working properly with JSR 286 portlets

                SPR-6126 was resolved, but the bug still remains. Calling SessionStatus.setComplete() effectively does not work when called in a portlet Action phase.

                If it is not a bug, can someone explain why it isn't?

                Thanks.

                Rob

                Comment


                • #9
                  I think I'm having the same issue right now (this thread). Does this get fixed?

                  Comment


                  • #10
                    No further information on this thread. Apparently I'm having the similar problem using Jboss as portal server and spring 3.2 lib.

                    I would like to know, if this is the only way, to pass information from Action to Render phase by copying stuff into Session or there is any better way.

                    Following are my code excerpt

                    Code:
                      @ActionMapping(params = { ACTION_PARAM + "=" + SUBMIT_FORM })
                        protected void submitForm(ActionRequest request,
                            ActionResponse response) {
                             response.setRenderParameter(RENDER_PARAM, ENTER_VALUE);
                             setSessionAttribute(request, VALIDATION_ERROR, status.getValue());
                    }
                    
                    
                    @RenderMapping(params = { RENDER_PARAM + "=" + ENTER_VALUE })
                        public String renderEnterDetail(RenderRequest request, ModelMap modelMap, SessionStatus sessionStatus) {
                            getLogger().info("Rendering Enter Details page");
                    
                            String otaValidationError = (String) getSessionAttribute(request, VALIDATION_ERROR);
                            modelMap.addAttribute(VALIDATION_ERROR, validationError);
                    
                            sessionStatus.setComplete();
                            return ENTER_DETAIL;
                        }

                    Since I'm not clearing up the session manually(I was hoping that SessionStatus would provide this functionality), so I see the value populated when I return to the same page from other pages.

                    Regards,
                    Irfan

                    Comment


                    • #11
                      Originally posted by IrfanAnsari View Post
                      No further information on this thread. Apparently I'm having the similar problem using Jboss as portal server and spring 3.2 lib.

                      I would likeى to know, if this is the only way, to pass information from Action to Render phase by copying stuff into Session or there is any better way.

                      Following are my code excerpt

                      Code:
                        @ActionMapping(params = { ACTION_PARAM + "=" + SUBMIT_FORM })
                          protected voidتكاليف التسويق الالكترونى  submitForm(ActionRequest request,
                              ActionResponse response) {
                               response.setRenderParameter(RENDER_PARAM, ENTER_VALUE);
                               setSessionAttribute(request, VALIDATION_ERROR, status.getValue());
                      }
                      
                      
                      @RenderMapping(params = { RENDER_PARAM + "=" + ENTER_VALUE })
                          public String renderEnterDetail(RenderRequest request,Recruitment  ModelMap modelMap,الاثاث بدمياط  SessionStatus sessionStatus) {
                              getLogger().info("Rendering Enter Details page");
                      
                              String otaValidationError = (String) getSessionAttribute(request, VALIDATION_ERROR);
                              modelMap.addAttribute(VALIDATION_ERROR, validationError);
                      
                              sessionStatus.setComplete();
                              return ENTER_DETAIL;
                          }

                      Since I'm not clearing up the session manually(I was hoping that SessionStatus would provide this functionality), so I see the value populated when I return to the same page from other pages.

                      Regards,
                      Irfan
                      good exegetics
                      Last edited by samiaeg; Jun 24th, 2013, 03:49 PM.

                      Comment

                      Working...
                      X