问题
I am trying to use SearchContainer
in my liferay application. Currently I've to use JSP Scriplets to set the results in <liferay-ui:search-container-results>
tags. This is the snippet so far:
<liferay-ui:search-container emptyResultsMessage="there-are-no-courses" delta="5">
<liferay-ui:search-container-results>
<%
List<Course> tempResults = ActionUtil.getCourses(renderRequest);
results = ListUtil.subList(tempResults,
searchContainer.getStart(),
searchContainer.getEnd());
total = tempResults.size();
pageContext.setAttribute("results", results);
pageContext.setAttribute("total", total);
%>
</liferay-ui:search-container-results>
<liferay-ui:search-container-row ...></liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
Now, I would like to change those scriplets to EL. I found one post regarding the same issue, but that is using Spring MVC
. And I've no idea where to write the below line as given in the answer to that question, in portlets:
SearchContainer<Book> searchContainer = new SearchContainer<Book>(renderRequest, renderResponse.createRenderURL(), null, "there are no books");
In can't write it in my portlet action, as the parameter in my action is ActionRequest
and ActionResponse
, which does not define the method createRenderURL()
. How would I get the PortletURL
?
Where should I write the above statement? Currently I'm writing in the same action from where I'm returning to this page. Am I doing it right? Here's the action that I'm firing from the same page, as the search-container
is in:
public void addCourse(ActionRequest request, ActionResponse response)
throws Exception {
ThemeDisplay themeDisplay =
(ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
Course course = ActionUtil.courseFromRequest(request);
List<String> errors = new ArrayList<String>();
if (CourseRegValidator.validateCourse(course, errors)) {
CourseLocalServiceUtil.addCourse(course, themeDisplay.getUserId());
SessionMessages.add(request, "course-added-successfully");
// I thought I might put it here.
// But I don't know what to pass as `PortletURL` in constructor of SearchContainer
} else {
SessionErrors.add(request, "fields-required");
}
}
I want that, everytime a Course
is added, it is rendered in my search container, on the same page from where I'm firing the addCourse
action.
And yes, my portlet extends MVCPortlet
.
UPDATE:
Ok, I figured out a few part.
- For the first time when portlet is loaded, I can override the
doView
method in my portlet, and then add theSearchContainer
inrenderRequest
there, as I've access to it indoView
. - But again, when I go on to
editCourse()
action, where I'am doing aresponse.setRenderParameter()
, to send it to another jsp page. And in that JSP page, I'm firing anupdateCourse()
action. - Now, from
updateCourse()
action, I'm again usingresponse.setRenderParameter()
to send it to the original JSP page, where I'm using Search Container. But now, since it is not going throughdoView()
method, I can't create theSearchContainer
and add it to request.
So, is there any work-around here? How to make sure that the attribute I set in renderRequest
in doView
method is available in updateCourse
method? I know that doesn't sound practical, as it is completely a new request, but is there any other way?
One work-around I can think of is to set the attribute in larger scope, like session
or context
instead of renderRequest
. But, I won't need that attribute anywhere else. So, I don't think that would be appropriate.
Any inputs?
Update 2:
Just now, I used:
actionResponse.setPortletMode(PortletMode.VIEW);
in place of:
actionResponse.setRenderParameter("jspPage", jspPage);
And it worked, as it now goes through doView()
method. Just wanted to ask, is this the appropriate way? What's the difference between two methods when we are setting render parameter to the same JSP page, where doView
methods redirects?
My Current doView
method looks like:
@Override
public void doView(RenderRequest renderRequest, RenderResponse renderResponse)
throws IOException, PortletException {
SearchContainer<Course> searchContainer =
new SearchContainer<Course>(renderRequest, renderResponse.createRenderURL(), null, "there-are-no-courses");
searchContainer.setDelta(5);
List<Course> tempResults = ActionUtil.getCourses(renderRequest);
List<Course> results = ListUtil.subList(tempResults,
searchContainer.getStart(),
searchContainer.getEnd());
searchContainer.setTotal(tempResults.size());
searchContainer.setResults(results);
renderRequest.setAttribute("searchContainer", searchContainer);
super.doView(renderRequest, renderResponse);
}
回答1:
Converting comments to answer:
- Whenever you render a portlet it is rendered through the doView method and not directly through the action methods as part of the portlet life-cycle.
- the results and total set as renderRequest.setAttribute("searchResults", courses) and renderRequest.setAttribute("searchTotal", total) in doView will be available in the view.jsp as ${searchResults} and ${searchTotal}.
- Everytime you perform any action the doView will be called after that and the searchResults and searchTotal will be set again and will be shown.
- or you can just set the
searchContainer
in the doView method itself as explained in the answer which you had linked in your question.
来源:https://stackoverflow.com/questions/17923082/setting-searchcontainer-in-portlet-to-use-it-in-jsp-using-el-and-jstl