3

Newb Alert

With a basic Extension, I populate a field with a SOQL. The desired behavior is when the lookup field is populated by a user, the second field shows a picklist with only the relevant values. A commandButton then allows the user to quicksaves a record and rerender the main form to show the "generated" link (formula field on the newly created record). Everything works as intented and each time I choose a different value in the lookup field the picklist shows the appropriate related list.

My challenge is when I click the commandButton the behavior stops working and the picklist doesn't update anymore.

For the sake of simplicity I only kept relevant code:

Extension.:

public class TESTGenerator { 

private final Link_Generator__c linkgen;

public TESTGenerator(ApexPages.StandardController stdController) {  
     this.linkgen = (Link_Generator__c)stdController.getRecord(); 
    }  

// Offer URL list options before saving new Link Generator Record  
public SelectOption[] getOfferUrlOptions() {  
       SelectOption[] OfferUrl = new SelectOption[]{};  
         for (Offer_URL__c l : [SELECT id, name FROM Offer_URL__c WHERE Offer__c = :linkgen.Offer__c ORDER by name ASC]) {  
         OfferUrl.add(new SelectOption(l.id, l.name));  
    }  
   return OfferUrl;
    }
 }

VisualPage.:

<apex:form id="myForm">
<apex:pageBlock >

        <!--Section - Main Infos--> 

<div class="bodystyle">
<apex:pageBlockSection title="Main Infos" columns="1" collapsible="false">

   <apex:inputField taborderhint="2" value="{!Link_Generator__c.Offer__c}" required="true" style="font-size: 10pt" >
   <apex:actionSupport event="onchange" rerender="myForm" />
   </apex:inputField>

   <apex:selectList id="OfferURLLookupPicklist" title="Offer URL" value="{!Link_Generator__c.Offer_URL__c}" size="1" >
   <apex:selectOptions value="{!OfferUrlOptions}" />
   <apex:actionSupport event="onchange" rerender="myForm"  />
   </apex:selectList>

</apex:pageBlockSection>
</div>

        <!--Section - Buttons-->

  <apex:pageBlockButtons location="bottom">
   <apex:commandButton value="Generate Link" style="background:#055fa8;color: white;width:95px;font-size: 9pt" action="{!quicksave}" rerender="myForm" />
   <input type="button" class="btn" onclick="location.reload();" value="Reset"/> 
</apex:pageBlockButtons>

        <!--Section - Result--> 

<div class="bodystyle"> 
<apex:pageBlockSection title="Result" columns="1" collapsible="false" >
  <apex:pageBlockSectionItem dataStyle="width:10%">
   {!Link_Generator__c.Link__c} 
   <br/>
   <br/>
   <span style="color:green; font-weight:bold;font-size: 10pt">  
   {!IF(ISBLANK(Link_Generator__c.Link__c),"","Use Control-C to directly copy this link")}   
   </span> 

            <!--Javascript - Allows user to use Control-C only to directly copy link to clipboard -->

<script type="text/javascript">
    document.addEventListener('copy', function(e){
    e.clipboardData.setData('text/plain', '{!Link_Generator__c.Link__c}');
    e.preventDefault(); 
    });
</script>    

 </apex:pageBlockSectionItem> 
</apex:pageBlockSection>
</div>

</apex:pageBlock>
</apex:form>
  • Can you post the quicksave method in your controller into your question? – Vigneshwaran G Mar 22 '16 at 13:33
  • It's the standard quicksave method so not in the extension – Philippe Tremblay Mar 22 '16 at 13:43
  • there is a recalculateFormulas() method you may be able to use (although it has some limitations) – cropredy Mar 22 '16 at 18:55
2

I strongly suspect the problem is because you've declared the following as final:

private final Link_Generator__c linkgen;

Even when using an instance method as you do when using the this keyword, you can't reset it using your command button. That would seem to be what's causing your issue. Try removing the final keyword and see if that doesn't solve your issue.

Edit (summary of my comments)

When there's a save of any kind, you want your controller to reinitialize and run that query regardless of whether's it's a quick-save. If so, then you'll want to refresh the select list and need your method to do that.

Since you're only refreshing the form, that's not going to happen unless you specifically do something to reinitialize your class. I suggest you consider adding a method to your class which your command button calls when you do your quick save that explicitly does that.

Since you've only posted a portion of your code, it's very difficult for me to advise you further. The main thing I'd recommend is putting your save method in your custom controller. QuickSave is essentially a Save without a redirect. There are several options including using a Save method that's Void, returns "this", adding "redirect = false", calling it "DoSave", etc. Regardless of which way you go, you want to avoid returning a pageReference.

| improve this answer | |
  • removing the final makes no difference, the behavior is still the same. Thanks though! – Philippe Tremblay Mar 22 '16 at 15:37
  • From what I can see, when there's a save of any kind, you want your controller to reinitialize and run that query regardless of whether's it's a quick-save or a save or do you want the ones that have already been selected to be removed from your select list? If so, then you'll want to refresh the select list and need your method to do that. – crmprogdev Mar 22 '16 at 15:55
  • Yep, I want my extension to reinitialize and run the query whenever I change the value of the lookup (Offer__c). This behavior should be the same before and after I save with the commandButton. All fields should retain their values before and after I save the record (unless changed by the user). I tried a bunch of things to no avail – Philippe Tremblay Mar 22 '16 at 17:16
  • 2
    Since you're only refreshing the form, that's not going to happen unless you specifically do something to reinitialize that class. I suggest you consider adding a method to your class which your command button calls when you do your quick save that explicitly does that. – crmprogdev Mar 22 '16 at 18:29
  • 1
    Since you've only posted a portion of your code, it's very difficult for me to advise you further. The main thing I'd recommend is putting your save method in your custom controller. QuickSave is essentially a Save without a redirect. Use a Save method that's Void, returns "this", add "redirect = false", call it "DoSave", etc, but don't return a pageRef. – crmprogdev Mar 29 '16 at 13:56
0

Success finally!

I used a pagereference to returns the page url with the newly saved record id at the end so now the refreshlist method also works after saving the record.

i.e: https://c.cs00.visual.force.com/apex/TESTGeneratorPage?id=a0A4B000001IdWbUAK

I still need to change the reset button, but other than that it works flawlessly.

Thank you @crmprogdev for your input!

Extension.:

public class TESTGenerator { 

public Link_Generator__c linkgen{get;set;}

public TESTGenerator(ApexPages.StandardController stdController) { 
       this.linkgen = (Link_Generator__c)stdController.getRecord();
       }  

// Offer URL list options before saving new Link Generator Record

public SelectOption[] getOfferUrlOptions() { 
       SelectOption[] OfferUrl = new SelectOption[]{};  
       for (Offer_URL__c l : [SELECT id, name FROM Offer_URL__c WHERE  Offer__c = :linkgen.Offer__c ORDER by name ASC]) {  
       OfferUrl.add(new SelectOption(l.id, l.name));
       }  
       return OfferUrl;
       }

public void refreshlist(){
    getOfferUrlOptions();               
    }

public PageReference customSave(){
        upsert linkgen;
        PageReference pageref = new PageReference('https://c.cs00.visual.force.com/apex/TESTGeneratorPage?id=' + linkgen.Id);
        pageref.setRedirect(false);
        return pageref;
        }
    }

Page

<apex:page standardController="Link_Generator__c" extensions="TESTGenerator" >

<html>

        <!--Main Form and main PageBlock-->

<apex:outputPanel id="all" >
<apex:form>
<apex:pageBlock >

        <!--Section - Main Infos--> 

<div class="bodystyle">
<apex:pageBlockSection title="Main Infos" columns="1" collapsible="false">

   <apex:inputField taborderhint="2" value="{!Link_Generator__c.Offer__c}" required="true" style="font-size: 10pt" >
   <apex:actionSupport event="onchange" action="{!refreshlist}" rerender="all"/>
   </apex:inputField>

   <apex:selectList id="OfferURLLookupPicklist" title="Offer URL" value="{!Link_Generator__c.Offer_URL__c}" size="1" >
   <apex:selectOptions value="{!OfferUrlOptions}" />
   </apex:selectList>

</apex:pageBlockSection>
</div>

        <!--Section - Buttons-->

<apex:pageBlockButtons location="bottom">
   <apex:commandButton value="Generate Link" style="background:#055fa8;color: white;width:95px;font-size: 9pt" action="{!customSave}" rerender="all" />

   <input type="button" class="btn" onclick="location.reload();" value="Reset"/> 
</apex:pageBlockButtons>

        <!--Section - Result--> 

<div class="bodystyle"> 
<apex:pageBlockSection title="Result" columns="1" collapsible="false" >
  <apex:pageBlockSectionItem dataStyle="width:10%">
   {!Link_Generator__c.Link__c} 
   <br/>
   <br/>
   <span style="color:green; font-weight:bold;font-size: 10pt">  
   {!IF(ISBLANK(Link_Generator__c.Link__c),"","Use Control-C to directly copy this link")}   
   </span> 

            <!--Javascript - Allow users to only use Control-C to directly copy link to clipboard -->

<script type="text/javascript">
    document.addEventListener('copy', function(e){
    e.clipboardData.setData('text/plain', '{!Link_Generator__c.Link__c}');
    e.preventDefault(); 
    });
</script>    

</apex:pageBlockSectionItem> 
</apex:pageBlockSection>
</div>
</apex:pageBlock>
</apex:form>
</apex:outputPanel>

</html>
</apex:page>
| improve this answer | |

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.