[SalesForce] apex command button that allows you to not refresh the page

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:

Best Answer

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>
Related Topic