Comments? Feedback?

This wiki does not yet support public comments (a limitation of Google Sites), so we encourage you to post your comments either:

On Twitter by responding to @orbeon.

On our community mailing list: subscribe sending an email to ops-users-subscribe@ow2.org (content of subject/body doesn't matter), you'll get a response with the email to use to send your message to the community mailing list.

Recent site activity

How-to guides‎ > ‎XForms View‎ > ‎

Avoid a table being immediately sorted



The problem

If you use the built-in support for sorting the datatable, or use an exf:sort() expression in the nodeset of you <xforms:repeat>, rows are sorted immediately after you change a value. This might move the row being edited to a different position. This may or may not be the effect you want to have. If it isn't, this how-to provides a solution using the datatable. But first, the following video illustrates the initial situation:


The solution

You want the table to be sorted (and re-sorted), only when you click on the table headers, as shown in this video:


To do this:
  1. Tell the datatable that you'll handle the sorting with: sortAndPaginationMode="external" on the <fr:datatable> element.
  2. Add an instance, which you'll use to keep track of what column you're currently sorting on, and in what order (ascending or descending) you're doing the sorting:

    <xforms:instance id="sorting">
        <sorting>
            <column/>
            <order/>
        </sorting>
    </xforms:instance>


  3. Inside the <fr:datatable>, handle the fr-update-sort event, which the datatable fires when users click on column headers. You can know what column users clicked on by calling event('fr-column'). You'll do the sorting in this event handler by reordering the elements in the instance based on the column and sort order selected by users.

    <xforms:action ev:event="fr-update-sort">
        <xxforms:variable name="column"
            select="('name', 'email', 'phone')[event('fr-column')]"/>

        <xxforms:variable name="contacts" select="contact"/>
        <xforms:setvalue ref="$sorting/order" value="
            if ($sorting/column = $column and . = 'ascending')
            then 'descending' else 'ascending'"/>

        <xforms:setvalue ref="$sorting/column" value="$column"/>
        <xforms:delete nodeset="$contacts"/>
        <xforms:insert context="instance('contacts')" nodeset="*"
                       origin="exf:sort($contacts, $column, 'text',
                                        instance('sorting')/order)"/>

    </xforms:action>

  4. On each sortable <xhtml:th>, you tell the datatable what the tooltip should read when users position the mouse on the table header. The tooltip indicates what will happen when user click on that header, and it will read "Click to sort ascending" or "Click to sort descending" depending on the whether the table is sorted by the current column, and if it is, what the current sort order is. In this example, the actual string shown to users comes from a separate instance containing resources, and pointed to by $resources. For instance, for the name column:

    fr:sortMessage="if ($sorting/column = 'name' and $sorting/order = 'ascending')
                    then $resources/sort-descending else $resources/sort-ascending"

  5. Also on each sortable <xhtml:th>, you add a style to indicate if the table is sorted by that column, and if it is, if the sorting order is ascendant or descendant.

    class="{if ($sorting/column != 'name')
            then '' else if ($sorting/order = 'ascending')
            then 'yui-dt-asc' else 'yui-dt-desc'}"


Run it and get the source