Announcement

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

    Timeline error in hover component

    When using a custom Hover in the Timeline via the getTaskHoverHTML function, I noticed (through the browser’s devTools) that after mouseout the Hover component becomes invisible, but it continues to track mouse movement and follows the cursor. This (with large Hover components) causes scrollbars to appear on the screen and leads to unwanted re-rendering of all components on the screen.

    If I then create the same Hover in a TreeGrid, the same behavior occurs.
    The error can be seen in the video at the link below.


    #2
    We don't have a function called getTaskHoverHTML() - we assume you mean getEventHoverHTML()?

    Please show what you're returning from whichever method it is.

    Comment


      #3
      We don't have a function called getTaskHoverHTML() - we assume you mean getEventHoverHTML()?
      Sorry, I actually meant getEventHoverHTML().

      Comment


        #4
        I have the following functions defined in my custom DataSource:
        getHoverComponent
        getHoverHTML
        Code:
            static setFieldToDisplay = function (record, field) {
                const name = field.name;
                field.escapeHTML = this.getField(name).escapeHTML;
                if (name === CONSTANT.AUTHOR) {
                    field.formatCellValue = function (value, record, field, viewer) {
                        return record[CONSTANT._AUTHOR];
                    };
                } else if (name === CONSTANT.SEND_TO) {
                    field.formatCellValue = function (value, record, field, viewer) {
                        return record[CONSTANT._SEND_TO];
                    };
                } else if (name === CONSTANT.TYPE) {
                    field.formatCellValue = function (value, record, field, viewer) {
                        return NoticesDataSource.getIcon(value) + "&nbsp" + Strings.get(CONSTANT.NOTICES_TYPE_NAME[value]);
                    };
                };
            }
            static getHoverComponent = function (record, showEmptyField = false, width = 500) {
                const owner = this;
                const rowHoverComponent = isc.DetailViewer.create({
                    dataSource: this,
                    data: [record],
                    top: -1000,
                    width: width,
                    minWidth: width,
                    showEmptyField: showEmptyField, labelAlign: "left", labelSuffix: "",
                    styleName: "hoverDetail",
                    blockStyle: "hoverDetailBlock",
                    cellStyle: "hoverDetailCell",
                    labelStyle: "hoverDetailLabel",
                    headerStyle: "hoverDetailHeader",
                    initComplete: function () {
                        Object.values(this.fields).forEach(field => {
                            owner.setFieldToDisplay(record, field);
                        });
                    }
                });
                return rowHoverComponent;
            }
            static getHoverHTML = function (record) {
                let component = this.getHoverComponent(record);
                let html = component.getInnerHTML();
                component.destroy();
                return html;
            }
        and the getEventHoverHTML function looks like this:
        Code:
        getEventHoverHTML: function(event, eventCanvas, view, defaultValue) {
            this.dataSource.getHoverHTML(event);
        }

        Comment


          #5
          Here is one of the examples that I return from the getEventHoverHTML function.

          Code:
          <TABLE BORDER=0 CELLSPACING=0 CLASS='hoverDetailBlock' CELLPADDING='3' style='width:499px'><TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Type</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'><img src='http://localhost:3000/shared/skins/standard/images/notices/2.png' width='18' height='18' align='TEXTTOP' align=center border='0' suppress='TRUE' draggable='true'/>&nbspTask</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Subject</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>&lt;b&gt;test&lt;/b&gt; jr &lt;img src=foobar onerror='alert(123);'&gt;</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Sender</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>Jurij &lt;b&gt;Riksen&lt;/b&gt;</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Recipient</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>Jurij <b>Riksen</b></TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Content</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'><p class="western">&nbsp;The <code class="element-western">&lt;meta:user-defined&gt;</code>
          element specifies any additional user-defined metadata for the
          document. Each instance of this element can contain one piece of
          user-defined metadata. The element contains:</p><p style="margin-top: 0.42cm; margin-bottom: 0.42cm; border-top: 1px solid #000000; border-bottom: none; border-left: none; border-right: none; padding-top: 0.04cm; padding-bottom: 0cm; padding-left: 0cm; padding-right: 0cm">
          </p><ul>
              <li value="1"><p class="western">A <font face="Courier New, monospace"><font style="font-size: 10pt">meta</font></font><code class="element-western"><font face="Courier New, monospace"><font style="font-size: 10pt">:name</font></font></code>
              attribute, which identifies the name of the metadata element.</p>
              </li><li><p class="western">An optional <code class="attribute-western">meta:type</code>
              attribute, which identifies the type of the metadata element. The
              allowed meta types are <font color="#000000"><font face="Courier, monospace"><font style="font-size: 10pt"><span lang="en-US">float</span></font></font></font>,
              <font color="#000000"><font face="Courier, monospace"><font style="font-size: 10pt"><span lang="en-US">date</span></font></font></font>,
              <font color="#000000"><font face="Courier, monospace"><font style="font-size: 10pt"><span lang="en-US">time</span></font></font></font>,
              <font color="#000000"><font face="Courier, monospace"><font style="font-size: 10pt"><span lang="en-US">boolean</span></font></font></font>
              and <font color="#000000"><font face="Courier, monospace"><font style="font-size: 10pt"><span lang="en-US">string</span></font></font></font>
              (see also section 6.7.1).</p>
              </li><li><p class="western"> (see section 6.7.1).
              </p>
              </li><li><p class="western">The value of the element, which is the
              metadata in the format described in section 6.7.1 as value of the
              <code class="attribute-western">office:value</code> attributes for
              the various data types.</p>
          </li></ul></TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Date</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>19.11.2020 10:53</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Read</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>16.04.2021 10:39</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Start by</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>22.08.2025 23:00</TD></TR>
          <TR HEIGHT='19'><TD WIDTH=10% CLASS='hoverDetailLabel' style='text-align:left;' NOWRAP><NOBR>Complete by</NOBR></TD><TD CLASS='hoverDetailCell' style='text-align:left;'>12.09.2025 22:59</TD></TR>
          </TABLE>

          Comment


            #6
            The immediate fix to the reflowing issue is probably to set overflow: "hidden" on your document body, which is something we've recommended for some years now - that should address things being resized.

            We'll try your use-case in the Timeline in the coming days.

            Are you saying that this happens with any large hover, since you mentioned TreeGrids, or that TreeGrid hovers are fine until you show a Timeline hover, and then it will happen in the TreeGrid as well?

            Comment


              #7
              I solved the issue with limiting the Hover height by restricting the height of the description field through CSS.
              However, I’m concerned that after calling setHide(), the Hover component still tracks the mouse movement and updates its position.

              Are you saying that this happens with any large hover, since you mentioned TreeGrids, or that TreeGrid hovers are fine until you show a Timeline hover, and then it will happen in the TreeGrid as well?
              If I create the same Hover only in a TreeGrid (without a prior Hover in the Timeline), then after mouseout the Hover becomes invisible, its top is set to -1000, and it no longer follows the mouse.

              Last edited by Hirn; 30 Aug 2025, 01:23.

              Comment


                #8
                But after the first appearance of a Hover in the Timeline, all Hovers from the TreeGrid also start tracking mouse movements and updating the coordinates of the already invisible Hover.

                Comment


                  #9
                  Again, have you set overflow: "hidden" on your document body? It's not clear why you'd be tracking the movements of invisible components.

                  Comment


                    #10
                    Again, have you set overflow: "hidden" on your document body?
                    For me, this is not a solution to the problem, since we are also developing for mobile devices, and there are many cases where the scrollbar on the <body> is simply necessary.

                    It's not clear why you'd be tracking the movements of invisible components.
                    It is precisely these hidden movements that cause the performance issue and unnecessary redraws.

                    I reported the strange behavior of Hover in the Timeline and found a workaround by limiting the height of the appearing Hover. I also mentioned that after a Hover in the Timeline, the same issue occurs in the TreeGrid, in the hope that this will help you.
                    From here, it’s up to you whether to fix it or not.
                    Last edited by Hirn; 30 Aug 2025, 08:07.

                    Comment


                      #11
                      Thanks for the detail. This issue has been fixed - the hoverCanvas will no longer move with the mouse if it isn't visible, and the moveWithMouse behavior will no longer affect all subsequent hovers.

                      You can try out the change as of today's builds, dated August 31.
                      Last edited by Isomorphic; 30 Aug 2025, 21:58.

                      Comment

                      Working...
                      X