0

I have a button:

<apex:commandButton action="{!pullReport}" value="Pull Report" id="pullReportbutton"/>

That refreshes the page every time it is clicked. If the page does not refresh, the data will not be returned. (IE: if I use reRender="none" or return= "false")

I have a JS function that will hide the button once it is clicked.

My issue is that once I click the button, the button is hidden for 2 seconds, then the page reloads, and the button is back.

Is there a way around this without having to restructure my apex:form or apex:commandButton? I have written conditionals to try and say "if there is data returned then hide the button" but these get refreshed as well. My last resort is to re-write the button in JS but I would prefer to not do that since I have it already written in visualforce.

some JS I've tried:

/*
$("#pullReportbutton").click(function(event){
event.stopPropagation();
alert("The span element was clicked.");
});

if("{!companyname}" != null){
    $(function(){
        document.getElementById('pullReportbutton').style.display = 'none';
    });
}

function hidebaseObject(e){
    e.preventDefault();
    var elem = document.getElementById('pullReportbutton');
    elem.parentNode.removeChild(elem);
}
*/

UPDATES: Full Code For Easier Viewing

<script type="text/javascript">>
  if("{!companyname}" != null){
      $(function(){
          document.getElementById('pullReportbutton').style.display = 'none';
      });
      function hidebaseObject(e){
          e.preventDefault();
          var elem = document.getElementById('pullReportbutton');
          elem.parentNode.removeChild(elem);
      }
  }
</script>
<apex:form id="mainForm">
<div class="col-md-6" style="position:relative">

     <div>
         Business ID Report
     </div>

     <div id="removeMePlease">
         Instant ID Report has not yet been pulled for this organization.
     </div>

      <div>
           <apex:commandButton action="{!pullReport}" value="Pull Report" id="pullReportbutton" reRender="mainForm" />
      </div>

      <div>
         Business ID Report 
      </div>

      <div>
          Company Name: {!companyname}
      </div>

      <div>
          Report Date
      </div>

      <div>
          {!newDate}
      </div>

      <div>
          Full Report
      </div>

      <div><a href="{!helloKitty}" target="blank">
                              View Details
           </a>
       </div>
</div>
</apex:form>

Results from One Suggestion:

10
  • have you tried rerendering the <apex:form /> by adding reRender in the apex:commandButton?
    – Praveen
    Oct 4, 2016 at 17:15
  • yes, I took it out of my example because it stops all processes from happening. <apex:commandButton action="{!pullReport}" value="Pull Report" id="pullReportbutton" reRender="none" />
    – Olivia
    Oct 4, 2016 at 17:19
  • Just to clarify. So you tried rerendering the form something like this :<apex:form id="myForm">..... <apex:commandButton action="{!pullReport}" value="Pull Report" id="pullReportbutton" reRender="myForm" /></apex:form> and it didn't work right?
    – Praveen
    Oct 4, 2016 at 17:24
  • WHen you add rerender what is not working? Oct 4, 2016 at 17:25
  • @Praveen exactly. TusharSharma- when I add reRender= "false" or reRender="mainForm" (this is the id on the form) the JavaScript is getting no response. The button does not change with the Javascript un-commented. If I take out reRender, with the JavaScript un-commented, the JavaScript works. But only until the page reRenders
    – Olivia
    Oct 4, 2016 at 17:29

2 Answers 2

3

Ok, there are a couple of things going on here:

  1. When you include merge syntax in javascript they do not get updated when the properties in the controller get updated unless you rerender them.

When I need that to happen I usually wrap the JS code inside an outPutPanel and rerender that when doing ajax actions:

<apex:outPutPanel layout="block" id="post_processing">
<script type="text/javascript">
console.log({!hideButton});
  if({!hideButton}){

        document.getElementById('hideMe').style.display = 'none';

  }
</script>
</apex:outPutPanel>
  1. Ids in visualforce are a strange thing. See this for a complicated explanation:

To refer to a Visualforce component in JavaScript or another Web-enabled language, you must specify a value for the id attribute for that component. A DOM ID is constructed from a combination of the id attribute of the component and the id attributes of all components that contain the element.

Use the $Component global variable to simplify referencing the DOM ID that is generated for a Visualforce component, and reduce some of the dependency on the overall page structure. To reference a specific Visualforce component’s DOM ID, add a component path specifier to $Component, using dot notation to separate each level in the component hierarchy of the page. For example, use $Component.itemId to reference a component at the same level in the Visualforce component hierarchy, or use $Component.grandparentId.parentId.itemId to specify a more complete component path.

https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_best_practices_accessing_id.htm

However there is an easier solution:

  • Use HTML tags like div and give them an ID and use that (Like in my example below)
  • Use jQuery and the endswith selector $("[id$=pullReportbutton]").xxx

    1. You need to actually rerender the JS panel.

Example Controller

public class myExample{


    public boolean hideButton {get;set;}

    public void dohide(){
        hideButton = true;
    }


}

Example Page

I tried to use your markup whenever possible to illustrate thins as in your example

<apex:page controller="myExample">
<apex:outPutPanel layout="block" id="post_processing">
<script type="text/javascript">
console.log({!hideButton});
  if({!hideButton}){

        document.getElementById('hideMe').style.display = 'none';

  }
</script>
</apex:outPutPanel>

<apex:form id="mainForm">
<div class="col-md-6" style="position:relative">

     <div>
         Business ID Report
     </div>

     <div id="removeMePlease">
         Instant ID Report has not yet been pulled for this organization.
     </div>

      <div id="hideMe">
           <apex:commandButton action="{!doHide}" value="Pull Report" id="pullReportbutton" reRender="post_processing" />
      </div>

      <div>
         Business ID Report 
      </div>

      <div>
          Company Name: TEST
      </div>

      <div>
          Report Date
      </div>

      <div>
            Now
      </div>

      <div>
          Full Report
      </div>

      <div><a href="Javascript:void(0)" target="blank">
                              View Details
           </a>
       </div>
</div>
</apex:form>
</apex:page>

You will notice that I used the following points in the code, if you use jQuery you can stick to using the button ID to hide using the endswith selector.

  • Id on Div
  • Wrapped JS in an outputPanel so the JS could be re rendered
  • Rerendered the new outputpanel and the button hides on click (in this case the containing div)

So take what is above, it is a working example. Start making modifications to have it meet your needs, test, test, test, when it breaks you will know what modification broke it and then don't do that and find the correct way.

Update based on your comments

I would do it differently than above (I would also use jQuery) but here is a working example:

Code

public class myExample{


    public String[] theList {get;set;}

    public void populateItems(){
        theList = New string[]{'A','B','C'};
    }


}

VF Page

<apex:page controller="myExample">

<apex:form id="mainForm">

    <span id="hideMe">
        <apex:commandButton action="{!populateitems}" onclick="document.getElementById('hideMe').style.display = 'none';" value="Pull Report" id="pullReportbutton" reRender="data_list" />
    </span>
    <apex:outPutPanel layout="block" id="data_list">
        <apex:repeat value="{!theList}" var="t">
            <apex:outPuttext value="{!t}"/>
        </apex:repeat>
        <script>
            document.getElementById('hideMe').style.display = 'inline';
        </script>
    </apex:outPutPanel>
</apex:form>
</apex:page>
9
  • thank you @Eric. I appreciate you taking the time to help, I am working through this, I am not getting back the data I need but it is hiding the button after the click. I will circle back around after a little while.
    – Olivia
    Oct 4, 2016 at 20:39
  • Right. You will have to add back in your data as I did not know what your methods were and orgs are obviously different
    – Eric
    Oct 4, 2016 at 20:41
  • I did add it back in. For example: for (Doc_Formulas__c cn : compName) { companyname = cn.Legal_Name__c; system.debug('this is the company name: ' + companyname); } compName is a SOQL query in my pullReport() method. companyname is in my VFP: {!companyname} and it is in my method in the controller and it is a static variable with a {get;set;}
    – Olivia
    Oct 4, 2016 at 20:44
  • That seems to be a different question. Constantly updating your question makes it hard for others to finds answers as answers become invalid or out of context
    – Eric
    Oct 4, 2016 at 20:50
  • Sorry if this is confusing. It is a lot of information. In my original question I said I have a JavaScript Function, a VFP, and a controller. As you can see on the VFP I have the {!companyname} listed with other variables I am pulling from my controller. I need to list this information once a button is clicked. then once the information is listed I want the button to disappear. So in my original question My issue is that once I click the button, the button is hidden for 2 seconds, then the page reloads, and the button is back.
    – Olivia
    Oct 4, 2016 at 21:05
0

I found a work around thanks to this wonderful platform. I used 'DOMContentLoaded' to change the text to alert the user that the report has already been pulled. I also disabled the "pull report" button so they are unable to pull the report twice.

<script> 
window.addEventListener('DOMContentLoaded', function() {
var bananas = true;      
   if ('{!companyname}'.length > 0) {
      console.log(bananas);
      document.getElementById("changeString").innerHTML = "You have successfully run the report."
      console.log(bananas);
   }
});
</script>  

This changes the inner HTML of:

<div class="cell" id="changeString" >Instant ID Report has not yet been pulled for this organization.</div>
<apex:commandButton action="{!pullReport}" value="Pull Report" disabled="{!disabl}"/>

In my controller I set disabl = true in my {!pullReport} method

You must log in to answer this question.

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