2

Is there a way to implement horizontal and vertival scroll to a pageblocktable similar to the ones in ListViews?

Similar to ListViews means vertical scrolling is only for the data and not for header and header and body share the same horizontal scrolling .

I tried;

<script>
var idx = "{!$Component.myPb.displayTable}";
idx = idx +':tb'; // Get the body of page block table
document.getElementById(idx).style = "overflow:auto;height: 250px;";
</script>

But it is not helping.

Update: I tried the StickyTableHeader mentioned in Eric's Answer which is working great but only problem is if overflowing horizontally it miss-aligns the header and body

After Horizontal scroll enter image description here

After Horizontal-Vertical scrollenter image description here

3
  • You have two answers that took the time to provide you a solution yet you have not awarded the bounty. As it stand the bounty will not be awarded to anyone that took the time to help you. Can you please either select and answer, up vote the one that helped you most, or award the bounty? – Eric Nov 22 '16 at 4:08
  • You were on 45 minutes ago. Can you let us know why you did not award the bounty so we can help you get this answered? – Eric Nov 22 '16 at 5:00
  • Seems is because inside a container with fixed width. Either take it out of the container or see: github.com/jmosbech/StickyTableHeaders/issues/1 (goto March 30 2013 answer on) – Eric Nov 22 '16 at 12:33
4

Quickest way to do this would be to use StickyTableHeaders. (Most reliable solution I have used) and provides the most standard like UI compared to other solutions. Datatables.net is also a great resource if you want to add search and filtering. I like it much better that jQuery data tables.

https://github.com/jmosbech/StickyTableHeaders

Here is a MVR code for you to try using a set height div and the Account object. I have to placed the JS in a static resource for this example.

<apex:page id="examplePage" standardController="Account" recordSetVar="acc">

    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"/>
    <apex:includeScript value="{!URLFOR($Resource.StickyHeaders)}"/>

    <style>
        .squeeze {
            overflow: auto;
            height: 200px;
        }
    </style>
    <apex:pageBlock>
        <apex:outputPanel layout="block" styleClass="squeeze">
            <apex:pageBlockTable id="pgb_table" value="{!acc}" var="a">
                <apex:column headerValue="Name" value="{!a.Name}"/>
            </apex:pageBlockTable>

            <script>
                $('[id$=pgb_table]').stickyTableHeaders({scrollableArea: $('.squeeze')});
            </script>
        </apex:outputPanel>

    </apex:pageBlock>

</apex:page>

Image on load

enter image description here

Image after scrolling a few

enter image description here

Horizontal scrolling should happen by default.

6
  • Hi Eric. Thanks for the answer. I will try it and let you know. – Saumya Ranjan Satapathy Nov 20 '16 at 13:20
  • @SaumyaRanjanSatapathy - How did it work for you?? – Eric Nov 21 '16 at 16:24
  • Eric, This api works great. Actually this is what I was looking for. Sorry for this late replay as I was stuck with some other issues. And sure I will add the bounty again and award it. – Saumya Ranjan Satapathy Nov 22 '16 at 7:53
  • Just one problem I am seeing with this api, when I set width of the table and then I scroll horizontally or vertically. I am updating the screenshot in the questions. – Saumya Ranjan Satapathy Nov 22 '16 at 7:55
  • @SaumyaRanjanSatapathy did you add any css?? – Eric Nov 22 '16 at 11:38
1

One easy way to implement this requirement is using Jquery datatable plugin. It will give you horizontal and vertical scrolling including many other functionality. Here is a sample Visualforce Page. Hope this helps.

 <apex:page standardController="Account" recordSetVar="accounts" >
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
    <style type="text/css">
        div.dataTables_wrapper {
            width: 800px;
            margin: 0 auto;
        }
    </style>    
    <apex:pageBlock id="thePageBlock" >
        <apex:pageBlockSection id="theSection">
            <apex:pageBlockTable value="{!accounts}" width="100%" var="acc" id="theTable" styleClass="opp-table">
                <apex:column value="{!acc.name}"/>
                <apex:column value="{!acc.AccountNumber}"/>
                <apex:column value="{!acc.AnnualRevenue}"/>
                <apex:column value="{!acc.Fax}"/>
                <apex:column value="{!acc.phone}"/>
                <apex:column value="{!acc.AccountSource}"/>
                <apex:column value="{!acc.BillingStreet}"/>
                <apex:column value="{!acc.BillingCity}"/>
                <apex:column value="{!acc.BillingState}"/>
                <apex:column value="{!acc.BillingPostalCode}"/>
                <apex:column value="{!acc.BillingCountry}"/>
                <apex:column value="{!acc.OwnerId}"/>
                <apex:column value="{!acc.ParentId}"/>                
            </apex:pageBlockTable>
        </apex:pageBlockSection>
    </apex:pageBlock>
    <script type="text/javascript">
        j$ = jQuery.noConflict();
        j$(document).ready(function () {
            j$('[id$=theTable]').DataTable( {
                "bSort" : false,
                "bPaginate": false,
                "bFilter": false,
                "bInfo": false,
                "scrollY": 200,
                "scrollX": true
            } );
        });  
    </script>    
</apex:page>

Screenshot:

enter image description here

1
  • Thanks Saroj. I tried Datatables jquery api. I liked its ui even more. But I was not able to bind the table buttons with the server side actions, like the next and previous buttons should invoke next() and preivious() of standard set controller. Even the page size, sorting and searching should go to controller and fetch the data instead of operating on the data that gets downloaded when the page loads. Could you help me doing that? – Saumya Ranjan Satapathy Nov 20 '16 at 13:19
0

StickyTableHeaders jquery api is definitely easy and concrete approach if your page do not over flow horizontally.

As my table had many columns and rows which made the container div overflow horizontally and vertically, so I switched to HTML tables.

SampeTable

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css"></link>
<meta charset=utf-8 />
<title>Scroll Example</title>
  <style>
    .scroll-example {
      display: block;
      margin-right: 20px;
      width: 100%;
    }
    td {
        border: 1px solid black;
        min-width:100px;
        max-width:100px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    td:hover i{
        display: block;
        float:right;
        visibility: visible;
    }
    i{
        display: none;
        visibility: hidden;
    }
  </style>

</head>
<body>
<div style="overflow: hidden;width: 400px;">
  <table id="target" class="scroll-example" style="overflow: hidden;">
    <tr>
        <td class="col11">HHHHHHHHHHHHH</td>
        <td class="col2">HHHHHHHHHHH</td>
        <td class="col3">HHHHHHHHHHH</td>
        <td class="col4">HHHHHHHHHHH</td>
        <td class="col5">HHHHHHHHHHH</td>
        <td class="col6">HHHHHHHHHHH</td>
        <td class="col7" width="20px"     style="border-color: white;"></td>
    </tr>
  </table>

  <table id="source" class="scroll-example" style="overflow: scroll;height: 80px;">
    <tr>
        <td class="col1"><i class="fa fa-pencil"></i>AAAAAAAAAAA</td>
        <td class="col2"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
    </tr>
    <tr>
        <td class="col1"><i class="fa fa-pencil"></i>AAAAAAAAAAA</td>
        <td class="col2"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
    </tr>
    <tr>
        <td class="col1"><i class="fa fa-pencil"></i>AAAAAAAAAAA</td>
        <td class="col2"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-pencil" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
        <td class="col1"><i class="fa fa-lock" aria-hidden="true"></i>AAAAAAAAAAA</td>
    </tr>
    </table>
  </div>
  <script>
  (function() {
    var target = $("#target");
    $("#source").scroll(function() {
      target.prop("scrollTop", this.scrollTop)
            .prop("scrollLeft", this.scrollLeft);
    });
  })();
  </script>
</body>
</html>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.