Home | Printable Version
4.2: Paging Table Control
This control provides a table structure, which gives the user the ability to sort the data by clicking on the column headings, and to page through the data by using controls at the bottom of the table. When this control is added to the page, it will add a number of components, which by default provide a table structure containing two output fields (table_field1 and table_field2). These two fields can be modified or removed if not required. Additional fields can be added by dragging controls from the palette or from a data source. Controls inserted in the table can include data entry controls such as text boxes. This control requires a number of additional JavaScript files, which are linked automatically when the control is added.
Customising Functionality
At the bottom of the control, there is a a custom field called table_init. This contains a script fragment that initialises the paging table functionality, and specifies the configuration options that apply to it. It is important that the position of this custom field is not changed, but the configuration options can be adjusted as required. The configuration options are split into two main sections, tablesorterOptions and pagerOptions. The control uses the tablesorter script from http://mottie.github.io/tablesorter/docs/ and these two sets of options match to those for the main tablesorter, and the pager plugin.
Some options that are commonly used include:
widthFixed - If this option is set to true, then the width of each column will be fixed on initial display, and will not adjust further based on content. This can be useful when using the paging option to ensure consistent display across pages. zebra - This widget is enabled by default to provide alternate row highlighting. It can be turned off if required by removing the 'zebra' entry from the widgets array. The default configuration should use the correct styling for the applied theme, but if needed the class names used to provide the styling can be adjusted by setting the 'zebra' property under widgetOptions. sticky headers - This widget ensures that the table heading row does not go off the screen if you need to scroll down the page to see all the table data. It is enabled by including the 'stickyHeaders' entry in the widgets array, and can be very useful if the paging option is not in use.
Pager Configuration
The paging capability is enabled by setting the top level enablePaging flag to 'true'. With this default setting, the table will only show the first page of records, and controls will be shown below it to provide access to further pages of information. If this is set to false, then all the records will be shown at once, but the rest of the table functionality (sorting, filtering, etc) will still apply. When enabled, the contents of the pagerOptions configuration section will control behaviour. Some common options you may want to adjust include:
size - If this is set to a number, then this sets the number of rows of data that will be shown on each page. If this is null or not provided, then the user will be given a drop down to select the number of entries to be displayed on each page. Note: The paging table stores some details about table state using local storage within the browser. As a result, changes to the size property may not take effect immediately in browsers that have previously rendered an older version of the page. fixedHeight - If this is set to true, the table height will be maintained, and the pager control's position fixed, even for pages that have less rows displayed on them. output - This string controls the format of the current page display string shown within the pager controls. Please see the tablesorter documentation for details on the available settings. As an example, the following output value would allow the user to set exactly which page to display: Page {page:input} of {filteredPages}
Customising Tooltip Strings
Each theme will provide images or content to use for the paging control buttons. In addition, each button has a default tooltip message which can be changed if required. To do this, add a messages property to the pagerOptions. This should be an object that defines the new messages to use, which can contain any of the following settings: firstBtnTitle, prevBtnTitle, nextBtnTitle, lastBtnTitle, pageSizeTitle. As mentioned in the previous section on the Editable Table control, these values could also be retrieved from Display Variables to enable translation.
Showing Child Data
One common requirement when showing a table of results is to present some summary information, and allow the ability to reveal more details for each row. One way of doing this is to use the child data capability provided by the WebMaker Paging Table control. To use this, an HTML Container Group should be placed within the table structure after all the other columns. This group should be given the CSS Classes child-data and hide. Any required controls and groups can be placed within this container to lay out the detailed information in the required format. When the page is rendered, the information in this container group will initially be hidden, but can be displayed below the relevant row simply by clicking on the row. If you wish to use a specific component to toggle visibility of the child data, rather than the whole row, then you should add an appropriate control to the table. Give this control an appropriate CSS Class name (eg child-data-toggle), and then adjust the initialisation script for the table to include an additional cssChildDataToggle setting containing the class name you are using on the toggle control. For example:
hyf.pagingtable.init(hyf.pagingtable.getLastTableOutput(),
                    {
                        enablePaging:true,
                        cssChildDataToggle: 'child-data-toggle',
                        tablesorterOptions: {
                                ...
                        },
                        pagerOptions: {
                                ...
                        }
                    }
                    );
                                    
Filtering
This provides the option to narrow down the set of results being displayed. To enable this, the filter widget must be added to the widgets list in the tablesorterOptions configuration, for example:
hyf.pagingtable.init(hyf.pagingtable.getLastTableOutput(),

{
    enablePaging:true,
    tablesorterOptions: {
            widthFixed:true,
            widgets: ['zebra', 'stickyHeaders', 'filter']
    },
    pagerOptions: {
            ...
    }
}
);
                
This will provide a text box under every heading (label for the column) that can be used to filter the results on that column. To easily customise the behaviour, you can add class names to the column Label(s). The list of class names available can be seen in the tablesorter filter demo, but as an example, you could show a select box for filtering a column by adding the filter-select class to the label, or prevent filtering by using the filter-false class. These classes must be added to the CSS Classes setting for the column Label(s). For more advanced filtering configuration there are a number of settings that can be added under tablesorterOptions / widgetOptions. Please see the tablesorter documentation for more details.
Grouping
This option groups common rows of data when sorting by an appropriate column (Label) . Each group can then be collapsed as required. To enable this, the 'group' widget must be added to the widgets array in the tablesorterOptions configuration. You then use specific class names on the headings (Label) of each column to control the grouping behaviour that will occur when sorting on that column. For example, you may want to group a list of users by the first letter of their surnames, by adding group-letter class. If you have a date column you could group by year, by adding group-date-year class. With a currency or number column, you could group by an amount, by adding group-number-10000 class. The number at the end defines the breakpoint: 10,000 / 20,000 / 30,000. The list of supported class names is available from the tablesorter grouping demo documentation. Some common examples include the use of class group-false to prevent grouping on a column, or group-letter to group by the first letter of values in the column. These classes must be added to the CSS Classes setting for the column's label.
Ajax Based Paging (Requires Server Controllers)
The default operation of the paging table control is to page through data on the client. This may be fine for a lot of situations, but in cases with large amounts of data, this may not be an acceptable solution. To resolve this, the table can be set up to use Ajax calls to retrieve each page of data, one at a time. The first step to configure this is to place the paging table control on a partial page. Then set up an 'onload' event on the main page to load in the partial page. When using Ajax based paging, each call also needs to return the total number of rows in the data to ensure the control knows how many pages there are, etc. There also needs to be a hidden field on the partial page to contain this. As an example, this could be called 'total'. The final step to configure the control for Ajax paging is to adjust the table_init script. The following fragment can be used as the basis for this script:
<script type="text/javascript">
/* For more details on the available configuration options please see the following FAQ entry:
* http://www.hyfinity.net/faq/index/solution_id/2005
*/
<xsl:text disable-output-escaping="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    hyf.pagingtable.init(hyf.pagingtable.getLastTableOutput(),
        {
            enablePaging:true,
            tablesorterOptions: {
                widthFixed:false,
                widgets: ['zebra']
            },
            pagerOptions: {
                size:null,
                processAjaxOnInit: false,
                ajaxObject: {
                    dataType: 'html'
                },
                ajaxUrl: 'PARTIAL_PAGE_ACTION_NAME.do?page_number={page}&amp;page_size={size}&amp;{sortList:sortcol}',
                ajaxProcessing: function(data, table, xhr) {

                    var $data = $(data)

                    return {total: $data.find('#total').val(),
                            rows: $data.find('table&gt;tbody&gt;tr')
                           };

                }
            }
        }
    );
</xsl:text>
</script>
                
Some import notes on this fragment:
The <xsl:text> element must be present to prevent issues with the XML reserved characters (e.g. &) used in the ajax URL. The PARTIAL_PAGE_ACTION_NAME text must be replaced with the name of the action going from the main page to the partial page. Nothing else on this line should require changes. If the hidden field containing the total number of rows is not called 'total' then the total: $data.find('#total').val() section needs to be updated accordingly, by replacing '#total' with the name of the field, e.g. '#mytotalfield'.
These changes should ensure that the control is configured correctly. The remaining step is to ensure the rules for the partial page controller are retrieving the correct set of results using the incoming page_number and page_size parameters. The approach used to do this will depend on where the data is coming from, e.g. SQL database, web service call, etc. The page_number parameter starts from 0 for page 1, 1 for page 2, etc. For example, if you have 100 records on the server (numbered 0-99) and wish to display 10 records per page across 10 pages, then you would set the total to 100 throughout your different AJAX requests within your rules. For each AJAX request, you would then interpret the page_number and page_size parameters from the incoming request and multiply page_number by page_size to calculate the starting point of the next batch of records and then read records totalling page_size. For example, if page_number=5 and page_size=10 then you would read 10 records starting from record 50. Once this is configured, and the partial page fields bound accordingly, the paging table should be correctly using ajax calls to retrieve each page of data. Depending on the requirements, further customisation of the behaviour may be needed. Please refer to the tablesorter documentation for more details.
Editable Table Control Data Cards Control