Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Cancel button for annotated portlet controller

  1. #1
    Join Date
    Sep 2009
    Posts
    5

    Default 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. #2
    Join Date
    Sep 2004
    Location
    Arizona, USA
    Posts
    383

    Default

    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?

  3. #3
    Join Date
    Sep 2009
    Posts
    5

    Default

    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

  4. #4
    Join Date
    Sep 2004
    Location
    Arizona, USA
    Posts
    383

    Default

    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.

  5. #5
    Join Date
    Sep 2009
    Posts
    5

    Default

    JIRA SPR-6126 opened

  6. #6
    Join Date
    Oct 2004
    Location
    Helsinki, Finland
    Posts
    17

    Default

    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.

  7. #7
    Join Date
    Oct 2004
    Location
    Helsinki, Finland
    Posts
    17

    Default

    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.

  8. #8

    Default 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

  9. #9

    Default

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

  10. #10
    Join Date
    Nov 2007
    Posts
    16

    Default

    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

Posting Permissions

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