How to sort records (with code) in a grouped ListG

2019-02-15 23:10发布

问题:

This is the scenario: I'm working with a listgrid that needs to be grouped, and also needs to have its records ordered within each group. I've already used the ListGrid.sort() and the ListGrid.sort(String, SortDirection) methods but none of them works properly.

This problem doesn't show up when the grid isn't grouped (it makes the sort perfectly); and when the sort (with the listgrid is grouped) is made by clicking the column header, works fine but I need to sort it by code (without user interaction) because the header sort option needs to be disabled (and context menu too).

I'm using SmartGWT 4.0

Here is the class I'm using:

public class Access extends ListGrid {

    public Access() {
        super();
        setWidth("30%");
        setHeight100();
        // setShowHeaderContextMenu(false);
        setCanResizeFields(false);
        // setCanSort(false);
        setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
        setWrapCells(true);
        setFixedRecordHeights(false);
        setShowRecordComponents(true);
        setShowRecordComponentsByCell(true);

        ListGridField id = new ListGridField("id", "ID");
        ListGridField user = new ListGridField("user", "User");
        ListGridField access = new ListGridField("access", "Access");

        id.setHidden(true);
        user.setWidth("60%");
        access.setWidth("40%");

        access.setType(ListGridFieldType.BOOLEAN);
        access.setCanEdit(true);

        setFields(id, user, access);

        groupBy("access");
        access.setGroupTitleRenderer(new GroupTitleRenderer() {
            public String getGroupTitle(Object groupValue, GroupNode groupNode, ListGridField field, String fieldName,
                    ListGrid grid) {
                return (String) groupValue + " - " + groupNode.getGroupMembers().length;
            }
        });
        getField("access").setGroupValueFunction(new GroupValueFunction() {
            public Object getGroupValue(Object value, ListGridRecord record, ListGridField field, String fieldName,
                    ListGrid grid) {
                Boolean access = (Boolean) value;
                if (access)
                    return "With access";
                else
                    return "Without access";
            }
        });

        ListGridRecord lgr1 = new ListGridRecord();
        lgr1.setAttribute("id", 1);
        lgr1.setAttribute("user", "ewgzx");
        lgr1.setAttribute("access", true);

        ListGridRecord lgr2 = new ListGridRecord();
        lgr2.setAttribute("id", 2);
        lgr2.setAttribute("user", "Bgfths");
        lgr2.setAttribute("access", false);

        ListGridRecord lgr3 = new ListGridRecord();
        lgr3.setAttribute("id", 3);
        lgr3.setAttribute("user", "utcvs");
        lgr3.setAttribute("access", true);

        ListGridRecord lgr4 = new ListGridRecord();
        lgr4.setAttribute("id", 4);
        lgr4.setAttribute("user", "gfdjxc");
        lgr4.setAttribute("access", false);

        ListGridRecord lgr5 = new ListGridRecord();
        lgr5.setAttribute("id", 5);
        lgr5.setAttribute("user", "763");
        lgr5.setAttribute("access", true);

        ListGridRecord lgr6 = new ListGridRecord();
        lgr6.setAttribute("id", 6);
        lgr6.setAttribute("user", "2");
        lgr6.setAttribute("access", false);

        ListGridRecord lgr7 = new ListGridRecord();
        lgr7.setAttribute("id", 7);
        lgr7.setAttribute("user", "35");
        lgr7.setAttribute("access", false);

        ListGridRecord lgr8 = new ListGridRecord();
        lgr8.setAttribute("id", 8);
        lgr8.setAttribute("user", "123");
        lgr8.setAttribute("access", true);

        ListGridRecord lgr9 = new ListGridRecord();
        lgr9.setAttribute("id", 9);
        lgr9.setAttribute("user", "2342");
        lgr9.setAttribute("access", true);

        ListGridRecord lgr10 = new ListGridRecord();
        lgr10.setAttribute("id", 10);
        lgr10.setAttribute("user", "aqwc");
        lgr10.setAttribute("access", false);

        setRecords(new ListGridRecord[] { lgr1, lgr2, lgr3, lgr4, lgr5, lgr6, lgr7, lgr8, lgr9, lgr10 });

        sort("user", SortDirection.ASCENDING);
    }
}

回答1:

I have been having a similar issue. Disclaimer: if the "grouping data" message is not appearing when you group then the following solution may not help.

In my case the sorting of a grouped column was screwed because of the "grouping data" pop up. Let me clarify.

The "grouping data" pop up appears when trying to group a ListGrid that is displaying more than 50 records.

It appears because the ListGrid, internally, is doing the grouping operation asynchronously to avoid the "script running slowly" message from the browser.

What I did was to set the grouping async threshold to a higher value. The risk of doing this is getting the "script running slowly" browser message, even though this is likely to happen only with IE8/9.

In the end , in the grid constructor, just add (I used 500 as a threshold):

setInitialSort(new SortSpecifier[] {new SortSpecifier("user", SortDirection.ASCENDING)}));
setGroupByField("access");
setGroupByAsyncThreshold(500);

Also set the initial sort and the grouped column as shown above.

PROGRAMMATICALLY, FIRST SORT, THEN GROUP.

Hope this helps.



回答2:

This is due to sort() being called before rendering the grid, and setRecords() complicates things further.
Initial rendering of the grid happens along with its parents when rootCanvas.draw() is called (in onModuleLoad or similar).
As setRecords() can be used to change data set in the grid anytime, it tries to redraw the grid regardless of whether its initial stage or not.

If in the real scenario, sort is triggered after UI initialization, it should work as given in following code sample.
Remove the sort() call at the end of the constructor.

final Access access = new Access();

Button button = new Button("Sort");
button.addClickHandler(new ClickHandler() {
    public void onClick(ClickEvent event) {
        // toggle sort direction, using two different ways to do it

        SortSpecifier sortSpecifier = access.getSortSpecifier("user");

        if (sortSpecifier == null || SortDirection.DESCENDING.equals(sortSpecifier.getSortDirection())) {
            access.sort("user", SortDirection.ASCENDING);
        } else {
            access.setSort(new SortSpecifier[]{
                    new SortSpecifier("user", SortDirection.DESCENDING)
            });
        }
    }
});

Check http://www.smartclient.com/smartgwt/showcase/#grid_multilevel_sort to see how to use listGrid.setInitialSort().

Having setRecords() in the constructor could lead to other initialization issues as well.

Update
To have the grid grouped by and sorted on load, set an initial sort and a group by field as indicated below.

// along with other configuration methods, can not use after grid is drawn
SortSpecifier sortSpecifier = new SortSpecifier("user", SortDirection.ASCENDING);
setInitialSort(new SortSpecifier[]{sortSpecifier});

// use following instead of groupBy(), which is used to group the grid programmatically
// groupBy() causes a redraw
setGroupByField("access");

An overloaded ListGrid.setGroupByField(String... field) method is available to group by multiple fields.



标签: smartgwt