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

    Wrong place of context menu in datatable with scrollbar

    Marcin Bednarek Newbie

      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
          Marcin Bednarek Newbie

          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
            Alessio Maggiori Newbie

            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
              Alessio Maggiori Newbie

              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;
              }
              
              
              
              


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

                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 Master

                  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
                    Newbie

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

                     

                    thx

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

                      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?