Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    12.0 null exception on resort()

    Hi Isomorphic,

    can you please take a look at this? On loading I have null exception on line 109 (resort();).
    (v12.0p_2018-08-23/PowerEdition Deployment (built 2018-08-23))
    Code:
    package com.smartgwt.sample.client;
    
    import com.google.gwt.core.client.EntryPoint;
    import com.smartgwt.client.Version;
    import com.smartgwt.client.core.KeyIdentifier;
    import com.smartgwt.client.data.AdvancedCriteria;
    import com.smartgwt.client.data.Criterion;
    import com.smartgwt.client.data.SortSpecifier;
    import com.smartgwt.client.types.OperatorId;
    import com.smartgwt.client.types.SelectionStyle;
    import com.smartgwt.client.types.SortDirection;
    import com.smartgwt.client.util.Page;
    import com.smartgwt.client.util.PageKeyHandler;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.Canvas;
    import com.smartgwt.client.widgets.IButton;
    import com.smartgwt.client.widgets.Label;
    import com.smartgwt.client.widgets.Window;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.grid.ListGrid;
    import com.smartgwt.client.widgets.grid.ListGridField;
    import com.smartgwt.client.widgets.grid.ListGridRecord;
    import com.smartgwt.client.widgets.grid.events.DataChangedEvent;
    import com.smartgwt.client.widgets.grid.events.DataChangedHandler;
    import com.smartgwt.client.widgets.layout.VLayout;
    
    public class BuiltInDS extends VLayout implements EntryPoint {
        private IButton recreateBtn;
        private final String fakeLGFName = "fakeLGFName";
    
        public void onModuleLoad() {
            KeyIdentifier debugKey = new KeyIdentifier();
            debugKey.setCtrlKey(true);
            debugKey.setKeyName("D");
    
            Page.registerKey(debugKey, new PageKeyHandler() {
                public void execute(String keyName) {
                    SC.showConsole();
                }
            });
    
            setWidth100();
            setHeight100();
    
            recreateBtn = new IButton("Recreate");
            recreateBtn.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    new MyWindow().show();
                }
            });
            addMember(recreateBtn);
            new MyWindow().show();
            draw();
        }
    
        private class MyWindow extends Window {
            public MyWindow() {
                setWidth(400);
                setHeight(600);
                setMembersMargin(0);
                setModalMaskOpacity(70);
                setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                SC.logWarn(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                setShowMinimizeButton(false);
                setIsModal(true);
                setShowModalMask(true);
                centerInPage();
    
                VLayout vL = new VLayout();
    
                // Img svgImg = new Img("http://127.0.0.1:8888/builtinds/tools/images/kiwi.svg", 100, 100);
                ListGrid lg = new ListGrid() {
                    {
                        setSelectionType(SelectionStyle.SINGLE);
                        setVirtualScrolling(true);
                        setShowRecordComponents(true);
                        setShowRecordComponentsByCell(true);
                        // Records becomes unreadable every next click in 12.0. version, we don't expect many record so this is fine solution.
                        // setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
                        setPoolComponentsPerColumn(true);
                        setFixedRecordHeights(true);
                        setRecordComponentHeight(56);
                        setCanSort(false);
                        setCanPickFields(false);
                        setCanResizeFields(false);
                        setCanAutoFitFields(false);
                        setCanGroupBy(false);
    
                        setAutoFetchData(false);
                        setDataSource("animals");
    
                        ListGridField scientificNameLGF = new ListGridField(fakeLGFName);
                        ListGridField lifeSpanLGF = new ListGridField("lifeSpan");
                        lifeSpanLGF.setCanEdit(true);
    
                        setFields(scientificNameLGF, lifeSpanLGF);
    
                        setSort(new SortSpecifier[] { new SortSpecifier("lifeSpan", SortDirection.DESCENDING) });
                        setInitialSort(new SortSpecifier[] { new SortSpecifier("lifeSpan", SortDirection.DESCENDING) });
                        fetchData(new AdvancedCriteria(new Criterion("status", OperatorId.EQUALS, "Endangered")));
    
                        addDataChangedHandler(new DataChangedHandler() {
                            @Override
                            public void onDataChanged(DataChangedEvent event) {
                                SortSpecifier[] ss = ((ListGrid) event.getFiringCanvas()).getSort();
                                SC.logWarn(ss.toString());
                                resort();
                            }
                        });
                    }
    
                    @Override
                    protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
                        String fieldName = this.getFieldName(colNum);
                        if (fakeLGFName.equals(fieldName)) {
                            String topicName = record.getAttributeAsString("scientificName");
    
                            Label testLabel = new Label();
                            testLabel.setContents(topicName);
    
                            VLayout vLayout = new VLayout(6);
                            vLayout.setHeight(50);
                            vLayout.setWidth100();
                            vLayout.setMembers(testLabel);
    
                            return vLayout;
                        } else
                            return null;
                    }
                };
    
                vL.addMembers(lg);
    
                addItem(vL);
            }
        }
    }
    So I think this is a bug, because this ListGrid has sort-specifier array.

    Best regards
    Pavo

    #2
    What are you trying to achieve with this call? As shown, it would do nothing. The data will already be in the specified sort order.

    Comment


      #3
      Hi Isomorphic,

      I think the reason for the resort() call is this:

      ResultSet.getUpdatePartialCache():
      Code:
      newly added rows will be added at either the end (first preference) or beginning of the dataset if that part of the dataset is cached and was most recently requested. If not, the new row is added at the end of the most recently requested contiguously cached range
      Also, the sort indicator is removed.

      This matches these docs:
      ListGrid.resort():
      Code:
      If a list has become unsorted due to [B]data modification[/B] or a call to [URL="https://www.smartclient.com/smartgwtee-release/javadoc/com/smartgwt/client/widgets/grid/ListGrid.html#unsort--"]unsort()[/URL], ......
      You can reproduce this in this sample:
      Code:
      isc.ListGrid.create({
          ID:"dsListGrid", 
          width: "100%",
          height: "100%",
          autoFetchData: true,
          dataSource: "supplyItem",
      [B]    canEdit:true[/B]
      });
      and sorting by SKU, then editing a row and changing SKU. The ListGrid sort will be removed.

      In order to have the data sorted again, you need a call to resort().

      Please note that this sample code runs into a endless request-loop, so this might not the correct way to do this after all:
      Code:
      isc.ListGrid.create({
          ID:"dsListGrid", 
          width: "100%",
          height: "100%",
          autoFetchData: true,
          dataSource: "supplyItem",
      [B]    canEdit: true,
          sortField: "SKU", 
          dataChanged: function () {
              dsListGrid.resort();
          }[/B]
      });
      Best regards
      Blama

      Comment


        #4
        We don't resort automatically for a reason: it would move the record out of view, which is mysterious.

        Adding an automatic resort() here creates a worse user experience, and as you noted, an infinite loop.

        Comment


          #5
          Hi Isomorphic,

          imagine this use case:
          1. ListGrid with many rows, sorted descending by a fixed sequence-PK field. Sort can not be changed by the user
          2. DynamicForm to add an entry to the ListGrid's DataSource
          3. After adding a row (=highest PK, because of sequence) with the DynamicForm, the new entry should be on top of the ListGrid
          How does one solve this use case best?

          Thank you & Best regards
          Blama

          Comment


            #6
            The resort() API exists for this kind of use case. The point made above is that using it every time, for every data change, does not make sense.

            Comment


              #7
              Ok, but then where and when should it be called?

              Thank you & Best regards
              Blama

              Comment


                #8
                Whenever you want it to happen? dynamicForm.saveData()'s callback, for example.

                Comment


                  #9
                  Note also, even though the call above is useless, we've made it no longer crash.

                  The reason it was crashing is that resort() was called when a resort was already going to happen.

                  Comment

                  Working...
                  X