Announcement

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

    #16
    This doesn't make much sense to us as stated - this Canvas or Label is inside of a grid cell, so having its width be anything less than the grid column width just leaves blank space. And if you force the Canvas to be wider than the cell, that's a violation of how record components work and will break scrolling as you saw before.

    Outside of the recordComponents use case, a Canvas or Label will fit to the widest unbreakable row of text and the "width" acts as a min-width.

    Comment


      #17
      Hi Isomorphic,

      I'd like to archive a design similar to this one. If you say it is not possible I can still enforce linebreaks with <br> after some "em" (e.g. every 80 characters), but I'd like autoWrap better.
      What you do suggest?

      Best regards
      Blama

      Comment


        #18
        That context is *extremely* helpful. Please start with that next time.

        If you have a maxWidth on a component in a Layout it will behave as the Layout docs describe: the layout algorithm will avoid assigning a width that exceeds the max width, when, for example, the component's size is specified as "*" or a percent.

        If you just set width of a Canvas to the widest you want the text to go, you'll get the behavior you want *except* you want to put the CSS styling of the bubble shape into the HTML contents of the Canvas with a surrounding <span>. That way it will wrap around the text instead of showing the all the text bubbles as being the same size.

        Comment


          #19
          Hi Isomorphic,

          thanks a lot. I was able to further improve on the design, and I'm almost there, but there is still one big design issue left.
          It renders the different rows as if it were long long label cut into pieces. Please see the screenshot. These pieces then seem to be moved to different positions - see how the "middle row" of a "3-row" text has no rounded borders. Or how the 1st line has rounded corners on the left and the last line has rounded corners on the right - the markup does not show any of those, though - it shows as if it were one <span>.

          Click image for larger version

Name:	Design.PNG
Views:	187
Size:	12.5 KB
ID:	249978

          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.google.gwt.user.client.Random;
          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.DSCallback;
          import com.smartgwt.client.data.DSRequest;
          import com.smartgwt.client.data.DSResponse;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.types.Alignment;
          import com.smartgwt.client.types.OperatorId;
          import com.smartgwt.client.types.Overflow;
          import com.smartgwt.client.types.RecordComponentPoolingMode;
          import com.smartgwt.client.types.VerticalAlignment;
          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.layout.HLayout;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          public class BuiltInDS extends VLayout implements EntryPoint {
              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();
          
                  final IButton 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(720);
                      setHeight(600);
                      setMembersMargin(0);
                      setModalMaskOpacity(70);
                      setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                      setTitle("RecordComponent horizontal scroll problem" + getTitle());
                      setShowMinimizeButton(false);
                      setIsModal(true);
                      setShowModalMask(true);
                      centerInPage();
          
                      ListGrid messengerTest = new MessengerTest();
                      addItem(messengerTest);
                  }
              }
          
              private class MessengerTest extends ListGrid {
                  private final String FAKECOLUMNNAME = "FAKECOLUMN";
          
                  public MessengerTest() {
                      super(DataSource.get("supplyItem"));
                      setVirtualScrolling(true);
                      setShowRecordComponents(true);
                      setShowRecordComponentsByCell(true);
                      setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
                      setPoolComponentsPerColumn(true);
                      setFixedRecordHeights(false);
                      setAlternateRecordStyles(false);
          
                      setWidth(600);
                      setHeight(500);
          
                      ListGridField skuLGF = new ListGridField("SKU");
                      skuLGF.setWidth(100);
                      ListGridField fakecolumnLGF = new ListGridField(FAKECOLUMNNAME);
                      fakecolumnLGF.setShowTitle(false);
          
                      setFields(skuLGF, fakecolumnLGF);
                      setSortField("SKU");
                      fetchData(new AdvancedCriteria(new Criterion("description", OperatorId.NOT_NULL)), new DSCallback() {
                          @Override
                          public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                              scrollToRow(100000, VerticalAlignment.BOTTOM);
                          }
                      });
                  }
          
                  @Override
                  protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
                      return updateRecordComponent(record, colNum, null, true);
                  }
          
                  public Canvas updateRecordComponent(ListGridRecord record, Integer colNum, Canvas component, boolean recordChanged) {
                      String fieldName = this.getFieldName(colNum);
                      if (FAKECOLUMNNAME.equals(fieldName)) {
          
                          String text = record.getAttribute("description") != null ? record.getAttributeAsString("description") : "";
          
                          int labelType = Random.nextInt(2);
                          int stringLength = Random.nextInt(200) + 10;
                          String shortenedText = (stringLength >= text.length()) ? text : text.substring(0, stringLength);
                          Label myLabel = new Label("<span>" + shortenedText + "</span>");
                          myLabel.setWidth(300);
                          myLabel.setHeight(1);
                          myLabel.setPadding(10);
                          myLabel.setOverflow(Overflow.VISIBLE);
                          // FYI: This has vertical alignment issues and does not max to 300.
                          /*
                          myLabel.setMaxWidth(300);
                          myLabel.setWidth("*");
                           */
          
                          HLayout myLayout = new HLayout();
                          myLayout.setPadding(2);
                          myLayout.setHeight(1);
                          myLayout.setWidth(500);
          
                          switch (labelType) {
                          case 0:
                              myLayout.setAlign(Alignment.RIGHT);
                              myLabel.setStyleName("blueLabel");
                              break;
                          case 1:
                              myLayout.setAlign(Alignment.LEFT);
                              myLabel.setStyleName("grayLabel");
                              break;
                          }
          
                          myLayout.setWidth100();
                          myLayout.addMember(myLabel);
                          return myLayout;
                      } else
                          return null;
                  }
              }
          }
          BuiltInDS.html-css addition:
          Code:
          <style type="text/css">
          .blueLabel {
            text-align: right;
          }
          .blueLabel span {
              font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
              color: #FFFFFF;
              background-color: #08F;
              padding: 8px;
              border-radius: 10px;
              text-align: right;
          }
          
          .grayLabel span {
              font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
              color: #FFFFFF;
              background-color: lightgray;
              padding: 8px;
              border-radius: 10px;
              text-align: left;
          }
          </style>

          Also, with respect to this thread and the scrolltoRow() / linked scrollToCell() docs, which say:
          With mixed-height rows it will only reliably work if virtualScrolling is enabled.
          Is it somehow possible to scroll to the last row of the dataset, displaying it on the very bottom? This means no virtualScrolling-almost blank page (=virtualScrolling disabled) while still having records components with mixed-heights?
          A method like "scrollToLastRecord()", that works regardless of the other ListGrid-setting?

          Thank you & Best regards
          Blama

          Comment


            #20
            We suggested putting the span inside a Canvas, not a Label. We're not sure what's happening here, but probably the style is being double-applied in some way due to logic within the Label that works around various browser bugs by splitting up the style definition.

            It also makes more sense to just write the style name directly into the <span> rather than try to do it via a selector. Especially with Label, you cannot assume your <span> is the only span, since Label might use them internally in some situations.

            Comment


              #21
              And, with variable height records and incremental rendering, there is no way to avoid the blank area at the bottom.

              Comment


                #22
                Hi Isomorphic,

                Originally posted by Isomorphic View Post
                We suggested putting the span inside a Canvas, not a Label.
                It also makes more sense to just write the style name directly into the <span> rather than try to do it via a selector
                I did both things, the result is the same. Please see this code:

                BuiltInDS.java:
                Code:
                package com.smartgwt.sample.client;
                
                import com.google.gwt.core.client.EntryPoint;
                import com.google.gwt.user.client.Random;
                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.DSCallback;
                import com.smartgwt.client.data.DSRequest;
                import com.smartgwt.client.data.DSResponse;
                import com.smartgwt.client.data.DataSource;
                import com.smartgwt.client.types.Alignment;
                import com.smartgwt.client.types.OperatorId;
                import com.smartgwt.client.types.Overflow;
                import com.smartgwt.client.types.RecordComponentPoolingMode;
                import com.smartgwt.client.types.VerticalAlignment;
                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.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.layout.HLayout;
                import com.smartgwt.client.widgets.layout.VLayout;
                
                public class BuiltInDS extends VLayout implements EntryPoint {
                    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();
                
                        final IButton 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(720);
                            setHeight(600);
                            setMembersMargin(0);
                            setModalMaskOpacity(70);
                            setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                            setTitle("RecordComponent horizontal scroll problem" + getTitle());
                            setShowMinimizeButton(false);
                            setIsModal(true);
                            setShowModalMask(true);
                            centerInPage();
                
                            ListGrid messengerTest = new MessengerTest();
                            addItem(messengerTest);
                        }
                    }
                
                    private class MessengerTest extends ListGrid {
                        private final String FAKECOLUMNNAME = "FAKECOLUMN";
                
                        public MessengerTest() {
                            super(DataSource.get("supplyItem"));
                            setVirtualScrolling(true);
                            setShowRecordComponents(true);
                            setShowRecordComponentsByCell(true);
                            setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
                            setPoolComponentsPerColumn(true);
                            setFixedRecordHeights(false);
                            setAlternateRecordStyles(false);
                
                            setWidth(600);
                            setHeight(500);
                
                            ListGridField skuLGF = new ListGridField("SKU");
                            skuLGF.setWidth(100);
                            ListGridField fakecolumnLGF = new ListGridField(FAKECOLUMNNAME);
                            fakecolumnLGF.setShowTitle(false);
                
                            setFields(skuLGF, fakecolumnLGF);
                            setSortField("SKU");
                            fetchData(new AdvancedCriteria(new Criterion("description", OperatorId.NOT_NULL)), new DSCallback() {
                                @Override
                                public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                                    scrollToRow(100000, VerticalAlignment.BOTTOM);
                                }
                            });
                        }
                
                        @Override
                        protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
                            return updateRecordComponent(record, colNum, null, true);
                        }
                
                        public Canvas updateRecordComponent(ListGridRecord record, Integer colNum, Canvas component, boolean recordChanged) {
                            String fieldName = this.getFieldName(colNum);
                            if (FAKECOLUMNNAME.equals(fieldName)) {
                
                                String text = record.getAttribute("description") != null ? record.getAttributeAsString("description") : "";
                
                                int canvasType = Random.nextInt(2);
                                int stringLength = Random.nextInt(200) + 10;
                                String shortenedText = (stringLength >= text.length()) ? text : text.substring(0, stringLength);
                                Canvas myCanvas = new Canvas();
                                myCanvas.setWidth(300);
                                myCanvas.setHeight(1);
                                myCanvas.setPadding(10);
                                myCanvas.setOverflow(Overflow.VISIBLE);
                                // FYI: This has vertical alignment issues and does not max to 300.
                                /*
                                myLabel.setMaxWidth(300);
                                myLabel.setWidth("*");
                                 */
                
                                HLayout myLayout = new HLayout();
                                myLayout.setPadding(2);
                                myLayout.setHeight(1);
                                myLayout.setWidth(500);
                
                                switch (canvasType) {
                                case 0:
                                    myLayout.setAlign(Alignment.RIGHT);
                                    myCanvas.setContents("<span class=\"blueCanvasSpan\">" + shortenedText + "</span>");
                                    myCanvas.setStyleName("chatCanvasRight");
                                    break;
                                case 1:
                                    myLayout.setAlign(Alignment.LEFT);
                                    myCanvas.setContents("<span class=\"grayCanvasSpan\">" + shortenedText + "</span>");
                                    break;
                                }
                
                                myLayout.setWidth100();
                                myLayout.addMember(myCanvas);
                                return myLayout;
                            } else
                                return null;
                        }
                    }
                }
                BuiltInDS.html CSS rules:
                Code:
                <style type="text/css">
                .chatCanvasRight {
                  text-align: right;
                }
                .blueCanvasSpan {
                    font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                    color: #FFFFFF;
                    background-color: #08F;
                    padding: 8px;
                    border-radius: 10px;
                    text-align: right;
                }
                
                .grayCanvasSpan {
                    font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                    color: #FFFFFF;
                    background-color: lightgray;
                    padding: 8px;
                    border-radius: 10px;
                    text-align: left;
                }
                </style>
                This is how the markup looks like:
                Click image for larger version

Name:	Markup.PNG
Views:	154
Size:	25.4 KB
ID:	249998

                This is the result:
                Click image for larger version

Name:	Display.PNG
Views:	121
Size:	11.4 KB
ID:	249999

                Please note that the markup contains only one span.

                Best regards
                Blama

                Comment


                  #23
                  Sorry, we forgot that you were throwing <br>s in there, at which point, the effect of the span is essentially to style each line of text individually.

                  You can either get rid of the <br>s (it's not clear that you still want them with this approach) or use a <div> rather than a <span>.

                  If that doesn't result in exactly what you want, it's time to use basic HTML and CSS resources to figure out how to get the styling you're after - SmartGWT is just acting as a container for your HTML, and isn't doing the rendering per se.

                  Comment


                    #24
                    Hi Isomorphic,

                    I got it to look like I want, using manually inserted <br/>-linebreaks in the data. It turns out, I do have a *vertical* scroll problem though if the last record is higher than the ListGrid. I assume this is a bug.
                    Please see this revised sample (now using 6.1p, v11.1p_2018-01-11):

                    BuiltInDS.java:
                    Code:
                    package com.smartgwt.sample.client;
                    
                    import java.util.ArrayList;
                    import java.util.List;
                    
                    import com.google.gwt.core.client.EntryPoint;
                    import com.google.gwt.user.client.Random;
                    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.DSCallback;
                    import com.smartgwt.client.data.DSRequest;
                    import com.smartgwt.client.data.DSResponse;
                    import com.smartgwt.client.data.DataSource;
                    import com.smartgwt.client.types.Alignment;
                    import com.smartgwt.client.types.OperatorId;
                    import com.smartgwt.client.types.RecordComponentPoolingMode;
                    import com.smartgwt.client.types.VerticalAlignment;
                    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.layout.HLayout;
                    import com.smartgwt.client.widgets.layout.VLayout;
                    
                    public class BuiltInDS extends VLayout implements EntryPoint {
                        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();
                    
                            final IButton 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(720);
                                setHeight(600);
                                setMembersMargin(0);
                                setModalMaskOpacity(70);
                                setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                                setTitle("RecordComponent horizontal scroll problem" + getTitle());
                                setShowMinimizeButton(false);
                                setIsModal(true);
                                setShowModalMask(true);
                                centerInPage();
                    
                                ListGrid messengerTest = new MessengerTest();
                                addItem(messengerTest);
                            }
                        }
                    
                        private class MessengerTest extends ListGrid {
                            private final String FAKECOLUMNNAME = "FAKECOLUMN";
                    
                            public MessengerTest() {
                                super(DataSource.get("supplyItem"));
                                setVirtualScrolling(true);
                                setShowRecordComponents(true);
                                setShowRecordComponentsByCell(true);
                                setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
                                setPoolComponentsPerColumn(true);
                                setFixedRecordHeights(false);
                                setAlternateRecordStyles(false);
                    
                                setWidth(400);
                                setHeight(400);
                    
                                ListGridField skuLGF = new ListGridField("SKU");
                                skuLGF.setWidth(100);
                                ListGridField fakecolumnLGF = new ListGridField(FAKECOLUMNNAME);
                                fakecolumnLGF.setShowTitle(false);
                    
                                setFields(skuLGF, fakecolumnLGF);
                                setSortField("SKU");
                                fetchData(new AdvancedCriteria(new Criterion("description", OperatorId.NOT_NULL)), new DSCallback() {
                                    @Override
                                    public void execute(DSResponse dsResponse, Object data, DSRequest dsRequest) {
                                        scrollToRow(100000, VerticalAlignment.BOTTOM);
                                    }
                                });
                            }
                    
                            @Override
                            protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
                                return updateRecordComponent(record, colNum, null, true);
                            }
                    
                            public Canvas updateRecordComponent(ListGridRecord record, Integer colNum, Canvas component, boolean recordChanged) {
                                String fieldName = this.getFieldName(colNum);
                                if (FAKECOLUMNNAME.equals(fieldName)) {
                    
                                    String text = record.getAttribute("description") != null ? record.getAttributeAsString("description") : "";
                                    text = text + ". " + text + ". " + text + text + ". " + text + ". " + text + ". " + text + ". ";
                                    text = listToString(splitByText(text, " ", 30));
                                    text = text.replace(" ", "&nbsp;");
                    
                                    int canvasType = Random.nextInt(2);
                    
                                    Label messageLabel = new Label(text);
                                    messageLabel.setWidth(1);
                                    messageLabel.setWrap(true);
                    
                                    HLayout myLayout = new HLayout();
                                    myLayout.setPadding(2);
                                    myLayout.setHeight(1);
                                    myLayout.setWidth(500);
                    
                                    switch (canvasType) {
                                    case 0:
                                        myLayout.setAlign(Alignment.RIGHT);
                                        messageLabel.setContents(text);
                                        messageLabel.setStyleName("chatLabelRight");
                                        break;
                                    case 1:
                                        myLayout.setAlign(Alignment.LEFT);
                                        messageLabel.setContents(text);
                                        messageLabel.setStyleName("chatLabelLeft");
                                        break;
                                    }
                    
                                    myLayout.setWidth100();
                                    myLayout.addMember(messageLabel);
                                    return myLayout;
                                } else
                                    return null;
                            }
                        }
                    
                        private List<String> splitByText(String text, String sep, int maxLength) {
                            List<String> ret = new ArrayList<String>();
                            int start = 0;
                            while (start + maxLength < text.length()) {
                                int index = text.lastIndexOf(sep, start + maxLength);
                                if (index < start)
                                    throw new IllegalArgumentException("Unable to break into strings of " + "no more than " + maxLength);
                                ret.add(text.substring(start, index));
                                start = index + sep.length();
                            }
                            ret.add(text.substring(start));
                            return ret;
                        }
                    
                        private String listToString(List<String> list) {
                            StringBuilder sb = new StringBuilder();
                            for (String s : list)
                                sb.append(s + "<br/>");
                            return sb.toString();
                        }
                    }
                    CSS for BuiltInDS.html:
                    Code:
                    <style type="text/css">
                    .chatLabelRight {
                        font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                        color: #FFFFFF;
                        background-color: #08F;
                        padding: 8px;
                        border-radius: 10px;
                        text-align: right;
                    }
                    
                    .chatLabelLeft {
                        font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                        color: #FFFFFF;
                        background-color: lightgray;
                        padding: 8px;
                        border-radius: 10px;
                        text-align: left;
                    }
                    </style>
                    Screenshot of issue:
                    Click image for larger version

Name:	Very high last recordComponent.png
Views:	158
Size:	20.4 KB
ID:	251242

                    Best regards
                    Blama

                    Comment


                      #25
                      There's no good way around this edge case, because the grid has no idea what size the last recordComponent is going to be until it renders that area, and at that point, it's a choice between a few different ugly interactions. The cleanest thing would be to limit the heights of messages to the viewport of the grid. The iMessages UI and similar UIs do this, possibly for the same underlying reason.

                      Comment


                        #26
                        Hi Isomorphic,

                        OK, that was something I was thinking about as well.
                        I'll go that way then until someone complains.
                        As the data is sorted by date, another way around the problem might be to always add an empty "last record" with date 31.12.9999 in SQL via UNION. This should also work then, shouldn't it?

                        Best regards
                        Blama

                        Comment


                          #27
                          This would cause the last scroll position to move the preceding record entirely off the screen, so doesn't seem an especially good solution.

                          Comment


                            #28
                            Hi Isomorphic,

                            I wanted to use it with this overload, also taking a VerticalAlignment as parameter.
                            IMHO there is also something wrong, but in order to prepare a testcase, it would be great if you could explain what the different options mean:
                            I'd interpret them this way:
                            Code:
                            TOP: Top of recordComponent at top of ListGrid body visible area
                            CENTER: Middle of recordComponent at middle of ListGrid body visible area (?)
                            BOTTOM: Bottom of recordComponent at bottom of ListGrid body visible area (?)
                            Best regards
                            Blama

                            Comment


                              #29
                              Hi Isomorphic,

                              I went ahead and created an easy testcase (v11.1p_2018-01-18) that is almost as my application. Scrolling with TOP and CENTER in general works like a charm.
                              There are two problems IMHO:
                              • Scrolling to BOTTOM does position the record component before knowing its real height and uses a too small value (my assumption). This works for TOP and CENTER, but not for BOTTOM, as here then the lower part of the recordComponent will not be visible. Unfortunately BOTTOM is the mode I need to use for a chatter-like appearance. Try 1000/BOTTOM and click it again after 1st scroll finished.
                              • Scrolling for all modes does not work if the record is already completely in the viewport. Try to scroll to any record with CENTER and then with TOP and with BOTTOM.
                              I also noticed that in the Developer Console the redraw count grows by approximately 1 per second even if I do nothing. The draw and clear counts grow by 120(!) per second. This is not the case in my application of far, nor in this sample. This also continues when I close the window. Is this an issue?

                              BuiltInDS.java:
                              Code:
                              package com.smartgwt.sample.client;
                              
                              import java.util.ArrayList;
                              import java.util.List;
                              
                              import com.google.gwt.core.client.EntryPoint;
                              import com.google.gwt.user.client.Random;
                              import com.smartgwt.client.Version;
                              import com.smartgwt.client.core.KeyIdentifier;
                              import com.smartgwt.client.data.DataSource;
                              import com.smartgwt.client.types.Alignment;
                              import com.smartgwt.client.types.RecordComponentPoolingMode;
                              import com.smartgwt.client.types.VerticalAlignment;
                              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.form.DynamicForm;
                              import com.smartgwt.client.widgets.form.fields.ButtonItem;
                              import com.smartgwt.client.widgets.form.fields.SelectItem;
                              import com.smartgwt.client.widgets.form.fields.SpinnerItem;
                              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.layout.HLayout;
                              import com.smartgwt.client.widgets.layout.VLayout;
                              
                              public class BuiltInDS extends VLayout implements EntryPoint {
                                  private IButton recreateBtn;
                              
                                  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(800);
                                          setHeight(800);
                                          setMembersMargin(0);
                                          setModalMaskOpacity(70);
                                          setTitle(" (" + Version.getVersion() + "/" + Version.getSCVersionNumber() + ")");
                                          setTitle("RecordComponent scrollToRow problem" + getTitle());
                                          setShowMinimizeButton(false);
                                          setIsModal(true);
                                          setShowModalMask(true);
                                          centerInPage();
                              
                                          final ListGrid messengerTest = new MessengerTest();
                                          addItem(messengerTest);
                              
                                          DynamicForm df = new DynamicForm();
                                          df.setNumCols(6);
                                          final SpinnerItem rowSI = new SpinnerItem("row", "Row");
                                          rowSI.setDefaultValue(600);
                                          rowSI.setMin(0);
                                          rowSI.setStep(200);
                                          final SelectItem positionSI = new SelectItem("position", "Position");
                                          positionSI.setValueMap("TOP", "CENTER", "BOTTOM");
                                          positionSI.setAllowEmptyValue(false);
                                          positionSI.setDefaultToFirstOption(true);
                                          final ButtonItem jumpBI = new ButtonItem("jump", "Jump");
                                          jumpBI.setStartRow(false);
                                          jumpBI.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {
                                              @Override
                                              public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
                                                  Integer selectedRow = (Integer) event.getForm().getValue("row");
                                                  String selectedPosition = (String) event.getForm().getValue("position");
                                                  switch (selectedPosition) {
                                                  case "TOP":
                                                      messengerTest.scrollToRow(selectedRow, VerticalAlignment.TOP);
                                                      break;
                                                  case "CENTER":
                                                      messengerTest.scrollToRow(selectedRow, VerticalAlignment.CENTER);
                                                      break;
                                                  case "BOTTOM":
                                                      messengerTest.scrollToRow(selectedRow, VerticalAlignment.BOTTOM);
                                                      break;
                                                  }
                                              }
                                          });
                                          df.setFields(rowSI, positionSI, jumpBI);
                                          addItem(df);
                                      }
                                  }
                              
                                  private class MessengerTest extends ListGrid {
                                      private final String FAKECOLUMNNAME = "FAKECOLUMN";
                              
                                      public MessengerTest() {
                                          super(DataSource.get("supplyItem"));
                                          setShowRecordComponents(true);
                                          setShowRecordComponentsByCell(true);
                                          setFixedRecordHeights(false);
                                          setVirtualScrolling(true);
                                          setPoolComponentsPerColumn(true);
                                          setRecordComponentPoolingMode(RecordComponentPoolingMode.RECYCLE);
                              
                                          setWidth100();
                                          setHeight100();
                              
                                          ListGridField fakecolumnLGF = new ListGridField(FAKECOLUMNNAME);
                                          fakecolumnLGF.setShowTitle(false);
                                          ListGridField itemNameLGF = new ListGridField("itemName");
                                          itemNameLGF.setWidth(200);
                              
                                          setFields(itemNameLGF, fakecolumnLGF);
                                          setSortField("itemName");
                                          fetchData();
                                      }
                              
                                      @Override
                                      protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {
                                          return updateRecordComponent(record, colNum, null, true);
                                      }
                              
                                      public Canvas updateRecordComponent(ListGridRecord record, Integer colNum, Canvas component, boolean recordChanged) {
                                          String fieldName = this.getFieldName(colNum);
                                          if (FAKECOLUMNNAME.equals(fieldName)) {
                              
                                              int rownumber = record.getAttributeAsInt("rowNumber");
                                              String text = record.getAttributeAsString("description") == null ? "" : record.getAttributeAsString("description");
                                              text = text + ". " + text + ". " + text + text + ". " + text + ". " + text + ". " + text + ". ";
                                              if (rownumber == 1000)
                                                  text = "I need some text in the case of the last record to make the recordComponent two rows minimum in order to show one of the problems.";
                                              text = "Data-Row " + rownumber + ": " + text;
                                              text = listToString(splitByText(text, " ", 100));
                                              text = text.replace(" ", "&nbsp;");
                              
                                              if (component == null) {
                                                  return new MessageLayout(text);
                                              } else {
                                                  if (recordChanged) {
                                                      MessageLayout oldMessageLayout = (MessageLayout) component;
                                                      oldMessageLayout.setContents(text);
                                                      return oldMessageLayout;
                                                  } else {
                                                      return component;
                                                  }
                                              }
                                          } else
                                              return null;
                                      }
                              
                                      private class MessageLayout extends HLayout {
                                          private Label messageLabel;
                              
                                          public MessageLayout(String contents) {
                                              setPadding(5);
                                              setHeight(1);
                                              setWidth100();
                              
                                              messageLabel = new Label();
                                              messageLabel.setWidth(1);
                                              messageLabel.setWrap(true);
                                              setContents(contents);
                                              addMember(messageLabel);
                                          }
                              
                                          public void setContents(String contents) {
                                              int canvasType = Random.nextInt(2);
                              
                                              switch (canvasType) {
                                              case 0:
                                                  setAlign(Alignment.RIGHT);
                                                  messageLabel.setContents(contents);
                                                  messageLabel.setStyleName("chatLabelRight");
                                                  break;
                                              case 1:
                                                  setAlign(Alignment.LEFT);
                                                  messageLabel.setContents(contents);
                                                  messageLabel.setStyleName("chatLabelLeft");
                                                  break;
                                              }
                                          }
                                      }
                              
                                      private List<String> splitByText(String text, String sep, int maxLength) {
                                          List<String> ret = new ArrayList<String>();
                                          int start = 0;
                                          while (start + maxLength < text.length()) {
                                              int index = text.lastIndexOf(sep, start + maxLength);
                                              if (index < start)
                                                  throw new IllegalArgumentException("Unable to break into strings of " + "no more than " + maxLength);
                                              ret.add(text.substring(start, index));
                                              start = index + sep.length();
                                          }
                                          ret.add(text.substring(start));
                                          return ret;
                                      }
                              
                                      private String listToString(List<String> list) {
                                          StringBuilder sb = new StringBuilder();
                                          for (String s : list)
                                              sb.append(s + "<br/>");
                                          return sb.toString();
                                      }
                                  }
                              }
                              BuiltInDS.html addition (as before):
                              Code:
                                      <style type="text/css">
                                      .chatLabelRight {
                                          font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                                          color: #FFFFFF;
                                          background-color: #08F;
                                          padding: 8px;
                                          border-radius: 10px;
                                          text-align: right;
                                      }
                              
                                      .chatLabelLeft {
                                          font-family: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif;
                                          color: #FFFFFF;
                                          background-color: lightgray;
                                          padding: 8px;
                                          border-radius: 10px;
                                          text-align: left;
                                      }
                                      </style>
                              supplyItem.ds.xml (change at end):
                              Code:
                              <DataSource
                                  ID="supplyItem"
                                  serverType="sql"
                                  tableName="supplyItem"
                                  titleField="itemName"
                                  testFileName="/examples/shared/ds/test_data/supplyItem.data.xml"
                                  dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
                              >
                                  <fields>
                                      <field name="itemID"      type="sequence" hidden="true"       primaryKey="true"/>
                                      <field name="itemName"    type="text"     title="Item"        length="128"       required="true"/>
                                      <field name="SKU"         type="text"     title="SKU"         length="10"        required="true"/>
                                      <field name="description" type="text"     title="Description" length="2000"/>
                                      <field name="category"    type="text"     title="Category"    length="128"       required="true"
                                             foreignKey="supplyCategory.categoryName"/>
                                      <field name="units"       type="enum"     title="Units"       length="5">
                                          <valueMap>
                                              <value>Roll</value>
                                              <value>Ea</value>
                                              <value>Pkt</value>
                                              <value>Set</value>
                                              <value>Tube</value>
                                              <value>Pad</value>
                                              <value>Ream</value>
                                              <value>Tin</value>
                                              <value>Bag</value>
                                              <value>Ctn</value>
                                              <value>Box</value>
                                          </valueMap>
                                      </field>
                                      <field name="unitCost"    type="float"    title="Unit Cost"   required="true">
                                          <validators>
                                              <validator type="floatRange" min="0" errorMessage="Please enter a valid (positive) cost"/>
                                              <validator type="floatPrecision" precision="2" errorMessage="The maximum allowed precision is 2"/>
                                          </validators>
                                      </field>
                                      <field name="inStock"   type="boolean"  title="In Stock"/>
                                      <field name="nextShipment"  type="date" title="Next Shipment"/>
                                      <field name="rowNumber"   type="integer"  customSelectExpression="ROW_NUMBER() OVER() -1" />
                                  </fields>
                              
                                  <operationBindings>
                                      <operationBinding operationType="fetch">
                                      <tableClause>(SELECT * FROM supplyItem ORDER BY itemName) SUPPLYITEM</tableClause>
                                      <whereClause>ROW_NUMBER() OVER() -1 &lt;= 1000</whereClause>
                                      </operationBinding>
                                  </operationBindings>
                              </DataSource>
                              Best regards
                              Blama

                              Comment


                                #30
                                As the docs say, the position refers to the position the row will have within the viewport. scrollToRow does not do sub-row positioning, and with variable height rows, does not know the size of the row before you bring it into view and draw it. So if you need that level of positioning, you should wait for the redraw and call scrollToRow again.

                                Comment

                                Working...
                                X