-
Notifications
You must be signed in to change notification settings - Fork 77
Paging
#Overview Paging in OpenElis differs from normal table paging because of the need to control where the page breaks and because edits to a page should not be written to the database until the user clicks on "Save". This means that if a user makes edits on one page, goes to another page and then goes back they should see their edits preserved.
The core of paging is that all of the pages are stored as a collection in the session object and changes in pages means getting a new page from the collection.
#Life cycle of a set of pages
-
Load all pages. The complete set of data is loaded from some source, such as the database, and broken up into pages based on the criteria for that form. The pages are saved with session object
-
Change pages Update the page in the session object with any changes made by the user
-
Get new page
-
Save page
-
Update the session object any changes made by the user
-
Get all the pages as a flat list (the same format they were in before they were broken up into pages
The core of the paging is PagingUtility.java. It is a generic class which takes as the type parameter the type which represents a single page. For instance if a page is a list of TestResultItems then PagingUtility would be instantiated as PagingUtility<List> paging = new PagingUtility<List>();
Details of the public methods can be found in the java docs at us.mn.state.health.lims.common.paging.PagingUtility #Paging Bean The paging bean encapsulates the current and total number of pages. By convention the name of the member in the form is 'paging'
#Client Side There are two parts on the client. One is the display of forward and back buttons
<logic:notEqual name="<%=formName%>" property="paging.totalPages" value="0">
<html:hidden styleId="currentPageID" name="<%=formName%>" property="paging.currentPage"/>
<bean:define id="total" name="<%=formName%>" property="paging.totalPages"/>
<bean:define id="currentPage" name="<%=formName%>" property="paging.currentPage"/>
<%if( "1".equals(currentPage)) {%>
<input type="button" value='<%=StringUtil.getMessageForKey("label.button.previous") %>' style="width:100px;" disabled="disabled" >
<% } else { %>
<input type="button" value='<%=StringUtil.getMessageForKey("label.button.previous") %>' style="width:100px;" onclick="pageBack();" />
<% } %>
<%if( total.equals(currentPage)) {%>
<input type="button" value='<%=StringUtil.getMessageForKey("label.button.next") %>' style="width:100px;" disabled="disabled" />
<% }else{ %>
<input type="button" value='<%=StringUtil.getMessageForKey("label.button.next") %>' style="width:100px;" onclick="pageFoward();" />
<% } %>
<bean:write name="<%=formName%>" property="paging.currentPage"/> of
<bean:write name="<%=formName%>" property="paging.totalPages"/>
</logic:notEqual>
The other part is the javaScript which does the post back to the server to get the next page. The following is taken from ResultsListView?.jsp. Note that some of the parameters are to preserve the permissions for different roles and will differ from jsp page to jsp page.
function /*void*/ pageFoward()
{
var form = window.document.forms[0];
form.action = '<%=formName%>'.sub('Form','') + ".do?page=" + (Number($("currentPageID").value) + 1 ) + '<%= logbookType == "" ? "" : "&type=" + logbookType %>';
form.submit();
}
function /*void*/ pageBack()
{
var form = window.document.forms[0];
form.action = '<%=formName%>'.sub('Form','') + ".do?page=" + (Number($("currentPageID").value) - 1 ) + '<%= logbookType == "" ? "" : "&type=" + logbookType %>';
form.submit();
}
#Action The common pattern is that if the page is not present then assume that the request is not for a different page but has been made from the menu and the paging has to be set up. The test can be done with
String newPage = request.getParameter("page");
if (GenericValidator.isBlankOrNull(newPage)) {
.........setup paging and get first page
}else{
.........update cache and get new page
}
For the save action the pattern is
String newPage = request.getParameter("page");
update cache with new page
get flattened results
save flattened results to database
Note that if an error is thrown during saving the paging cache is still valid.
#Encapsulation The mechanics of paging, such assigning the new page to the dyna form, getting the session from the request are a separate concern from the action and should be encapsulated in there own class. An example of this can be found in us.mn.state.health.lims.result.action.util.ResultsPaging #Future enhancements
Future enhancements include
- Doing a better job in deciding if the cache is dirty and the save button should be enabled
- Change the display on the jsp to allow the user to jump from page to page rather than just going forward or back