9 Replies Latest reply on May 28, 2010 5:02 AM by vim

    Wrong place of context menu in datatable with scrollbar

    smile24

      I have a datatable with css scrollbar.


      <rich:panel id="dirView" style="margin-left: 310px;width:830px;height:420px;position:absolute;top:65px;overflow:auto;padding-bottom:0px;padding-left:0px;padding-right:0px;padding-top:0px;">
      <rich:dataTable id="lineItemTable" cellpadding="0" cellspacing="0" border="0" var="element" value="#{treeBean.folderData}">
      .......


      In one column I have context menu :

      <rich:column style="width:580px;">
      <s:div id="fileName" rendered="#{element.nodeType=='F'}">
      <rich:contextMenu id="fileNameContextMenu" event="oncontextmenu" attached="true"
      submitMode="ajax" hideDelay="60000">
      <rich:menuItem value="History"
      action="#{treeBean.setSelectedDocument(element)}"
      oncomplete="Richfaces.showModalPanel('versionModalPanel');"
      id="showVersion" status="statusDirView"
      reRender="fileVersionModalHeader">
      </rich:menuItem>
      </rich:contextMenu>
      <h:graphicImage value="/images/iconFile.gif">
      </h:graphicImage>
      <h:outputLabel value="#{element.name}">
      </h:outputLabel>
      </s:div>
      </rich:column>
      </rich:dataTable>
      </rich:panel>


      There are a lot of rows in the table. When I scroll down and click on column to show context menu it is shown in wrong place (near
      top of the table). It looks like the scrollbar position isn't taken into consideration when calculating the position of context menu.


      How can I fix this problem?

        • 1. Re: Wrong place of context menu in datatable with scrollbar
          smile24

          I fixed this problem by adding these lines to RichFaces.Menu.DelayedContextMenu:

          var scrollOffsets = Position.realOffset(this.layer);
          toolTipX = toolTipX + scrollOffsets[0];
          toolTipY = toolTipY + scrollOffsets[1];

          • 2. Re: Wrong place of context menu in datatable with scrollbar

            Hi to all,

            According this issue:

            https://jira.jboss.org/jira/browse/RF-2648

            the bug it's closed, but I've still got the same problem. I've noted that the suggested workaround is already included in source files (RF 3.3.0 GA). Tested with IE7, FF3.

            Someone can help me?

            Thanks


            • 3. Re: Wrong place of context menu in datatable with scrollbar

              For a complete comprehension.
              Using RF3.2.2 SR1 all works fine. The problem begin with 3.3.0.

              This is the code:


              <div id="id_scroll" class="scroll2">
               <h:panelGroup id="pnl_tree" >
               <rich:tree binding="#{treeModelBean.treeReq}" requestDelay="200" eventsQueue="evTree" ignoreDupResponses="true" id="id_tree" adviseNodeOpened="#{treeModelBean.adviseNodeOpened}" switchType="client" ajaxSubmitSelection="true" >
               <rich:treeNodesAdaptor id="request" nodes="# {treeModelBean.requests}" var="req">
               <rich:treeNode eventsQueue="evTree" nodeSelectListener="#{treeModelBean.processRic}" reRender="pnl_container,pnl_btn" >
               <h:outputLabel id="reqst" value="Richiesta: #{req.accessnumber} - #{req.data}" />
              
               <rich:contextMenu submitMode="ajax" id="menu_req" attached="true" attachTo="reqst" >
               <rich:menuItem rendered="#{req.canDelete}" submitMode="ajax" value="Modifica Richiesta" action="#{treeModelBean.editSavedReq}" reRender="popupEditRequest,pnl_tree,pnl_btn,pnl_container,pnl_puls" />
               <rich:menuItem rendered="#{req.canDelete}" submitMode="ajax" value="Elimina Richiesta" action="#{treeModelBean.prepareDelReq}" reRender="confirmPanel"/>
               <rich:menuItem rendered="#{req.newInsert}" submitMode="ajax" value="Modifica Richiesta" action="#{treeModelBean.prepareEditReq}" reRender="popupEditRequest" />
               <rich:menuItem rendered="#{req.newInsert && req.canAddImpegnativa}" value="Aggiungi Impegnativa" action="#{treeModelBean.prepareNewImpegnativa}" submitMode="ajax" reRender="popupEditImpegnativa" />
              
               <rich:menuItem rendered="#{req.canDelete}" value="Stampa Ticket" action="#{treeModelBean.viewTicket}" />
               </rich:contextMenu>
              
               </rich:treeNode>
              
              ...
              
              
              CSS fragment:
              
              div.scroll2 {
               overflow-y: auto;
               overflow-x: hidden;
               height: 330px;
               width: 250px;
               border: 0px;
               background-color: #fff;
              }
              
              
              
              


              • 4. Re: Wrong place of context menu in datatable with scrollbar
                nbelaevski

                Thanks, we'll check!

                • 5. Re: Wrong place of context menu in datatable with scrollbar
                  adubovsky

                  Hello,

                  Issue was opened: https://jira.jboss.org/jira/browse/RF-6467

                  Thanks for participation.

                  • 6. Re: Wrong place of context menu in datatable with scrollbar

                    Hi,

                     

                    i solved the problem in <rich:dropDownMenu> by implementing a workaround that calculates the scrollx recursive to the parents.

                     

                    here is my implementation for richfaces 3.3.3.Final (marked red):

                    menu.js

                     

                    this.listPositions = function(jp, dir) {
                            var poss = new Array(new Array(2,1,4),new Array(1,2,3),new Array(4,3,2),new Array(3,4,1));
                            var list = new Array();
                            if (jp>0 && dir>0) {
                                  list.push({jointPoint: jp, direction: dir });
                            } else if (jp>0 && dir==0) {
                                for(var i=0;i<3;i++) {
                                    list.push({jointPoint: jp, direction: poss[jp-1][i] });
                                }
                            } else if (jp==0 && dir>0) {
                                for(var i=0;i<3;i++) {
                                    list.push({jointPoint: poss[dir-1][i], direction: dir });
                                }
                            } else if (jp==0 && dir==0) {
                                  list.push({jointPoint: 4, direction: 3 });
                                  list.push({jointPoint: 1, direction: 2 });
                                  list.push({jointPoint: 3, direction: 4 });
                                  list.push({jointPoint: 2, direction: 1 });
                            }
                            return list;
                        }.bind(this);

                     

                       this.findScrollX = function (obj) {
                            var curleft = 0;
                            if(obj.parentNode) {
                               while(obj.parentNode) {
                                  curleft += obj.scrollLeft
                                  obj = obj.parentNode;
                               }
                            }
                            return curleft;
                         }

                         
                        this.calcPosition = function(jp, dir) {
                            var layerLeft;
                            var layerTop;
                            switch (jp) {
                                case 1:
                                    layerLeft = this.left;
                                    layerTop = this.top;
                                    break;
                                case 2:
                                    layerLeft = this.right;
                                    layerTop = this.top;
                                    break;
                                case 3:
                                    layerLeft = this.right;
                                    layerTop = this.bottom;
                                    break;
                                case 4:
                                   layerLeft = this.left - this.findScrollX(this.element);
                                    layerTop = this.bottom;
                                    break;
                            }
                            switch (dir) {
                                case 1:
                                    layerLeft -= this.layerdim.width;
                                    layerTop -= this.layerdim.height;
                                    break;
                                case 2:
                                    layerTop -= this.layerdim.height;
                                    break;
                                case 4:
                                    layerLeft -= this.layerdim.width;
                            }
                            return {left: layerLeft, top: layerTop};
                        }.bind(this);

                     

                    hope that helps!

                     

                    Christian

                    • 7. Re: Wrong place of context menu in datatable with scrollbar
                      ilya_shaikovsky

                      the issue marked as already fixed.. So I'm not sure why you need the workaround.

                      • 8. Re: Wrong place of context menu in datatable with scrollbar

                        ok, i will post my problem as a new point.

                         

                        thx

                        • 9. Re: Wrong place of context menu in datatable with scrollbar

                          I has seen a similar issue.

                          This my workaround

                           

                          add in in rich:contextmenu this option:

                          onexpand="myonexpand();"

                           

                          In my javascript this is myonexpand() function to fix issue in IE:

                           

                          function myonexpand()
                          {
                              /*
                               * Bind context menu to correct scope
                               * Fix for IE
                               */
                              RichFaces.Menu.DelayedContextMenu.bind(this);
                          }

                           

                          Note:

                          It is need a function in a js file  if put the code in this way:

                          onexpand="RichFaces.Menu.DelayedContextMenu.bind(this);"

                          we don't resolve the issue.

                           

                          So perhaps the cause of issue is that when bind RichFaces.Menu.DelayedContextMenu this is not the correct scope.

                           

                          Why "this" in some cases, IE, is not the correct scope?