-3

On our page we have a scrollable table with date input fields. However, whenever we scroll the table up and down and select date input field, the date picker pops up in the position where the table row would have started on the page(which would be obviously at the bottom with out scroll). So, often that is outside of the bounds of our scrollable table.

Does anyone know how to make the datepicker scroll with the table rows?

<apex:page sidebar="false" controller="Test" standardStylesheets="true">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/JavaScript" />
<style>
    .table-container {
        Width:  100.5%;
        height: 400px;
        border: 1px solid black;
        margin: 10px auto;
        background-color: #FFFFED;
        position: relative; /* or absolute */
        padding-top: 30px; /* matches height of header */
    }
    .table-container-inner {
        overflow-x: hidden;
        overflow-y: auto;
        height: 100%;
        Width:  auto;
    }
    .heading-bg {
        background-color: #66C87D;
        height: 30px; /* matches padding of table-container */
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        border-bottom: 1px solid black;
    }
    table {
        width: auto;
    }
    .heading {
        position: absolute;
        top: 0;
        font-weight: bold;
        text-align: center;
    }    
</style>
<apex:form id="formId">
    <apex:pageMessages id="msgId"/>
    <apex:pageBlock Title="Accounts List" mode="inlineEdit" id="acc_list" >
    <apex:pagemessages />
        <apex:pageBlockButtons >
             <apex:commandButton action="{!Edit}" id="editButton" value="Edit"/>
             <apex:commandButton action="{!save}" id="saveButton" value="Save"/>
             <apex:commandButton action="{!cancel}" onclick="resetInlineEdit()" id="cancelButton" value="Cancel"/>
        </apex:pageBlockButtons>    
<!-- ***Detail Mode*** -->            
        <apex:outputpanel rendered="{!view}" id="view">
            <apex:actionStatus id="loading" >
                <apex:facet name="start" >
                  <center><img src="/img/loading32.gif" />      Loading....  Please Wait...  </center>          
                </apex:facet>
            </apex:actionStatus>
            <div class="table-container">
            <div class="heading-bg"></div><div class="table-container-inner"> 
                    <table id="schTable" >
                        <thead><tr><td><div class="heading" style="width: 60px;word-wrap:break-word;">Activity Date</div></td></tr></thead>
                        <tbody>
                            <apex:repeat value="{!lstaAccs}" var="a"><tr onmouseover="this.style.backgroundColor='#e3f3ff';" onmouseout="this.style.backgroundColor='#ffffff';">
                            <td><div style="width: 80px;word-wrap:break-word;">
                               <apex:outputField value="{!a.Acc.Due_Date__c}" title="Due Date">
                                            <apex:inlineEditSupport showOnEdit="saveButton, cancelButton" hideOnEdit="editButton" event="ondblclick" changedStyleClass="myBoldClass" resetFunction="resetInlineEdit"/>
                              </apex:outputField></div>
                            </td></tr></apex:repeat>
                        </tbody>
                    </table>
                </div></div>
        </apex:outputpanel>                       
    </apex:pageBlock>
</apex:form>
<script>
    var $ = jQuery.noConflict();
     $(document).ready(function(){
      $("#toggleId").click(function(){
        $("#detailTblId").toggle();
        if($("#detailTblId").css('display')=='none'){
            $('#linkTextId').html('Click here to show the Contact information in the Tabular form.');
        }else{
            $('#linkTextId').html('Click here to Hide.');
        }
      });                                           
    }); </script> </apex:page>

When i inline edit the datefield, the datepicker wont show just below the rowInstead it shows at the bottom of the page where the record would actually exist with out table scroll

8
  • I'm having a hard time trying to figure out how your provided Visualforce can possibly generate the table in your image. To me, it looks like your table should only have 1 column (for Due_Date__c). Also, why are you using <apex:outputField> if you're trying to accept the date as input? Also also, is there any particular reason why you're not using <apex:PageBlockTable>?
    – Derek F
    Commented May 17, 2017 at 15:57
  • I don't think any of my previous comment explains why your datepicker is appearing on the bottom of your page. If you're using Javascript/CSS to shuffle things around, however, I can see that potentially messing with the Javascript and styling that Salesforce provides.
    – Derek F
    Commented May 17, 2017 at 15:59
  • @Sam why dont you go to any freelance sites and ask for help there? I think response time will be shorter there for urgent hot fixes
    – kurunve
    Commented May 17, 2017 at 16:01
  • 3
    Also, accosting users for help in the comments is a pretty good way to ensure that they won't end up helping you. If you provide sufficient detail in your question, it should naturally attract people who may be able to answer. Including things like "URGENT, pls hlp" personally makes me shy away from interacting with the question at all.
    – Derek F
    Commented May 17, 2017 at 16:02
  • 2
    Yes, mentioning specific users is extremely rude. Please refrain from this behavior in the future.
    – Adrian Larson
    Commented May 17, 2017 at 16:08

2 Answers 2

3

tl;dr: I wasn't able to keep the datepicker position adjusted, but I did find an explanation for why the standard datepicker is behaving the way it is.

It took an amount of searching and luck, but I was able to find another question that had a similar (but different) issue.

Datepicker widget location issue

The answer by Mark Masterson contains some helpful information:

When you click on the date field, an onfocus event is fired that calls the Datepicker javascript function. This does a variety of things, but the relevant part to your question is that it uses the window object to determine the Date Picker's position.

An inline visualforce page on the page layout is displayed in an iframe. The iframe has its own window object, so it is using that to determine the position. When you examine the Visualforce page on it's own, it is using the regular height and width to determine the window size, and not the iframe's.

From this, it isn't that far of a stretch to say that something similar is happening with your table contained in an element that can scroll. Basically, the Javascript that Salesforce is using is ignoring the fact that your table is in a scrollable container.

Based on this, I set off on trying to adjust the positioning of the datepicker. All we basically need to do is use Javascript to figure out how much the scrollable element containing your table has scrolled, and subtract that from where Salesforce thinks the datepicker should be.

I used the following visualforce page:

<apex:page standardController="Account" extensions="TestAccountPageExtension">
    <script>
         var adjustDatePicker = function(e){
             e.preventDefault();
             var picker = document.getElementById('datePicker');
             var scrollContainer = document.getElementById('containingDiv');
             
             console.log(picker.style.top);
             picker.style.top = (parseInt(picker.style.top) - scrollContainer.scrollTop) + 'px';
             console.log(picker.style.top);
         };
    </script>    
    <apex:form id="theForm">
        <div id="containingDiv" style="height: 200px; overflow-y:scroll;">
        <apex:pageBlock id="myTable">
            <apex:pageBlockTable value="{!accounts}" var="acct">
                <apex:column>
                    <apex:inputField value="{!acct.Last_Payment_Date__c}" onclick="adjustDatePicker(event);"/>
                </apex:column>
            </apex:pageBlockTable>
        </apex:pageBlock>
        </div>
    </apex:form>
</apex:page>

The extension is hardly worth mentioning, but here it is for sake of completeness:

public class TestAccountPageExtension{
    public List<Account> accounts {get;set;}
    
    public TestAccountPageExtension(ApexPages.StandardController stdCon){
        accounts = [SELECT Id, Name, Last_Payment_Date__c FROM Account LIMIT 20];
    }
}

I tried setting the id attribute on a standard visualforce component (<apex:pageBlock> here), and using $Component.<the Id I set on the pageBlock>, but found it more reliable to just use a div to wrap the whole table (which I then made scrollable).

<element var>.scrollTop in Javascript fetches the amount that a scrollable element has been scrolled, which is exactly what we would need.

picker.style.top fetches the currently calculated value of the top attribute of the datepicker's css styling. It comes as a string with 'px' at the end, so we need to parseInt to grab the number so we can subtract the scrollTop value.

If you're looking at a javascript console, you'll see that the before and after values are different, but if you inspect the markup of the datepicker itself, the new value doesn't stick.

I can see, by setting a breakpoint in the javascript via my browser's dev tools, that we do in fact change the initial position, but Salesforce goes and reverts the changes I made via javascript right after my adjustDatePicker() function returns.

If you could find a way to prevent Salesforce from mucking with things after a custom event handler returns, then this method would work. That said, I have no idea how to accomplish that.

Your best bet may be to use a jquery datepicker instead, or to completely override the datepicker's positioning using !important in CSS like so

<style>
    .datePicker{
        top: 0 !important; # Using !important prevents Salesforce from mucking about.
                           # Unfortunately, it also means we can't do much via Javascript ourselves.
    }
</style>
0
0

Thanks for the suggestion Derek! I was able to add little enhancement for your suggestion the date picker in the center of the page and this solves the above mentioned issue.

.datePicker{
        top: 200px !important; 
        left: 796px !important;
    } 

However, I still didn't find the precise solution using the jquery and I also tried the solution from reddit.com/r/salesforce/comments/39azsj/… which didnt work for me(May be, I might have not done it the right way)

Not the answer you're looking for? Browse other questions tagged .