0

Background: I have a requirement where we need to display a VF page on the Contact object that indicates whether or not a contact has had their contact information verified within the last 14 days or not. If the contacts Last_Verification_Date__c is more than 14 days prior to Today, I render one outputPanel that says "Customer Needs Verification". When you mouse over that portion of the VF page, a "Verify" commandLink appears. When you press this "Verify" link, I want to re-render the Visualforce page and show that the contact is now verified, without forcing a page load.


Screenshot on Unverified Contact before Mouse Over:

Example 1

Screenshot on Unverified Contact on Mouse Over:

Example 2

Screenshot on VERIFIED Contact after pressing Verify button and MANUALLY refreshing the page:

Example 3

From the example screens above, I hope you can see what I am trying to achieve. Basically - the contacts are all not verified if we haven't checked their info in the last 14 days. When they aren't verified I render Image 1, and when you mouse over it you get the button in Image 2. When you click the button, the Last_Verification_Date__c field DOES get updated correctly in the databse, but the rerender doesn't do anything. The only way to see Image 3 is if you manually reload the page after pressing Verify.


I originally attempted to assign ids to each of the outputPanels separately and then do a rerender="Id1,Id2" on my commandLink, but I found this blog post by Bob Buzzard where he notes that you can't do it like that because the reRender is trying to render something that was never rendered in the first place (because it didn't meet render conditions): http://bobbuzzard.blogspot.co.uk/2011/02/visualforce-re-rendering-woes.html

His solution is to wrap both of my dynamically rendered outputPanels inside another parent outputPanel, assign the parent panel an Id, and then do the reRender to that Id instead. I tried that too, but still it will not rerender.

At this point I'm not sure what's wrong. Is it not working because my commandLink is inside of the panel that is being rerendered? Is there a problem with the way my rerender is structured? Is my render condition for the 2 different alert messages not being updated correctly/returning the right value from the controller during rerender?

I'm not really sure how to debug rerender, so I'm at a loss - any thoughts are appreciated.

Code:

Page:

<apex:page standardController="Contact" extensions="ContactCTRL_XT">
    <script src="https://use.fontawesome.com/305c6a828e.js"></script>
    <style tyle="text/css">
        .hide {display:none;}
        .show {display:none;border:1px solid #ccc;background-color:green;color:white;font-weight:bold;border-radius: 6px;margin-top:0px;margin-bottom:0px;padding:6px;}
        .verify {display:inline-block;border:1px solid #ccc;border-radius: 6px;margin-top:0px;margin-bottom:0px;padding:10px;margin-left:-120px;}
         .verify:hover .show {display:inline-block;}
         span.needToVerify {display:inline-block;font-weight:bold;font-size:1.5em;color:red;margin-top:5px}
         span.verifiedText {display:inline-block;font-weight:bold;font-size:1.5em;color:green;margin-top:5px}
         .isVerified {border:1px solid #ccc;border-radius: 6px;margin-top:0px;margin-bottom:0px;padding:10px;display:inline-block;margin-left:0px;}
    </style>

    <apex:form >      
        <div style="width:100%;text-align:center">
        <apex:outputPanel id="refreshMe">
            <apex:outputPanel rendered="{!!isVerified}" id="needToVerify">
                <div class="verify">
                    <apex:commandLink action="{!verifyContact}" rerender="refreshMe">
                        <div class="show">
                            Verify
                        </div>
                    </apex:commandLink>

                    <span class="fa-stack fa-lg" style="color:red;vertical-align:middle;margin-top:-7px">
                        <i class="fa fa-circle-thin fa-stack-2x"></i>
                        <i class="fa fa-exclamation fa-stack-1x"></i>
                    </span> 
                    <span class="needToVerify">Contact Needs Verification</span>
                </div>
            </apex:outputPanel>

            <apex:outputPanel rendered="{!IsVerified}" id="Verified">
                <div class="isVerified">
                    <span class="fa-stack fa-lg" style="color:green;vertical-align:middle;margin-top:-7px">
                        <i class="fa fa-circle-thin fa-stack-2x"></i>
                        <i class="fa fa-check fa-stack-1x"></i>
                    </span> 
                    <span class="verifiedText">Contact Verified</span>
                </div>
            </apex:outputPanel>

            <apex:outputPanel rendered="{!(contact.account.Password__c != NULL) && (contact.account.Zuora__Active__c == 'Yes')}">
                <c:PasswordRequiredBanner Password="{!contact.account.Password__c}" />
            </apex:outputPanel>
        </apex:outputPanel>
        </div>
    </apex:form>
</apex:page>

Controller Extension:

public with sharing class ContactCTRL_XT {
    Contact cont {get;set;}

    public ContactCTRL_XT(ApexPages.StandardController stdController) {
        stdController.addFields(new String[]{
        'FirstName',
        'LastName',
        'Contact_Verified__c',
        'Last_Verification_Date__c'
        });

        this.cont = (Contact)stdController.getRecord();
    }

    public Boolean getIsVerified(){
        Date contactDate = cont.Last_Verification_Date__c;
        Date todaysDate = Date.today();
        if(contactDate == null){
            return false;
        }
        else{
            Date contactDatePlus14 = cont.Last_Verification_Date__c + 14;

            if(contactDatePlus14 >= todaysDate){
                return true;
            }
            else{
                return false;
            }

        }
    }

    public PageReference verifyContact(){
        Contact tempContact = new Contact(Id = cont.Id,
                                          Last_Verification_Date__c = Date.today(),
                                          Contact_Verified__c = true
                                         );

        update tempContact;

        return null;
    }
}
3

You issue is that:

  1. You are updating tempContact
  2. Your getIsVerified method is using the cont variable Last_Verification_Date__c field which is set on page load
  3. You are not updating the cont variable in the verifyContact method

You should simply use the cont in the verify method

public void verifyContact(){
    cont.Last_Verification_Date__c = Date.today();
    cont.Contact_Verified__c = true;
    update cont;
}

Once you do that the getIsVerified will return TRUE and the page section will re render

  • Winner winner! Makes perfect sense now that I look at it that way, the variable may have updated behind the scenes but its still persisted to the page from load until a refresh occurs, so the rerender is running, it's just returning false still because the variable hasn't changed. Silly me :) – Morgan Marchese Oct 28 '16 at 1:12
0

I had an almost exact same problem where I could not rerender my page with a commandLink button. I got it debugged to where it would work in IE but not Chrome or Firefox. What I ended up doing is adding target="_self" to the button and that caused it to rerender the vf page. Without it my page would refresh the entire page and only display the vf page and cut out the rest of the SF UI.

Here's an example from my vf page that looks like a related list but sits in the Account page layout:

        <apex:commandLink action="{!toggleInactive}" value="Show All Contacts" rendered="{!showActiveContacts}" target="_self" >
            <apex:actionSupport event="OnClick"
                reRender="frm"
                status="counterStatus" />
        </apex:commandLink>
        <apex:commandLink action="{!toggleInactive}" value="Show Active Contacts" rendered="{!showInactiveContacts}" target="_self">
            <apex:actionSupport event="OnClick"
                reRender="frm"
                status="counterStatus" />
        </apex:commandLink> 
  • I was hoping this would be it, it seemed so easy. Unfortunately, too good to be true. Doesn't appear to make a difference in my case. When I press my link, it doesn't do anything at all, no page reload, no rerender - but in the background the database fields are updated, so the method is being run - it's just not rerendering anything unless i manually refresh – Morgan Marchese Oct 27 '16 at 22:21
0

Would you try out with actionFunction like this:

<apex:commandLink onclick="return performOperation()" rerender="refreshMe">
<div class="show">
    Verify
</div>
</apex:commandLink>  
<apex:actionFunction name="callControllerMethod" action="{!verifyContact}" reRender="refreshMe"/>

<script type="text/javascript">
function performOperation(){
    callControllerMethod();
}
</script>

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.