[SalesForce] How to call HTTP Get Request on the tab click in Visualforce

How can we call HTTP Apex REST method on tab click ?

I am referring the exact code Apex code from the link: Call the Rest API on the VisualForce page load and I want to call HTTP REST Method on the Tab click

Note: In future, I may have 10 tabs and on clicking on each different specific web service should be called.

enter image description here

Please suggest what changes do I need to in my VF code?

public class TabApexRestController {
    public List<CaseDetail> caseList {get; set;}

    public static String getAccessToken(){
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setHeader('Content-Type','application/x-www-form-urlencoded');
        req.setEndpoint('https://ap5.salesforce.com/services/oauth2/token');

        String CLIENT_ID = 'XX';
        String CLIENT_SECRET = 'XX';
        String USERNAME = 'XX';
        String PASSWORD = 'XX';

        req.setBody('grant_type=password' + '&client_id='+CLIENT_ID + 
            '&client_secret='+CLIENT_SECRET + '&username='+USERNAME + '&password='+PASSWORD);

        Http http = new Http();
        HTTPResponse res = http.send(req);
        return getAccessTokenValue(res.getBody());
    } 

     public static String getAccessTokenValue(String jsonInput){
         System.debug('OAuth Details : '+jsonInput);
         Map<String, Object> data = (Map<String, Object>) JSON.deserializeUntyped(jsonInput);
         return (String) data.get('access_token');
    }

    public PageReference getCaseDetailsById(){
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://ap5.salesforce.com/services/apexrest/Cases/5007F000000qqvCQAQ');
        req.setMethod('GET');
        req.setHeader('Authorization', 'Bearer '+getAccessToken());

        HTTPResponse res = http.send(req);
        String json = res.getBody();

        CaseDetail ca = (CaseDetail) System.JSON.deserialize(json.replace('"type"','"type_Z"'), CaseDetail.class);
        caseList = new List<CaseDetail>();
        caseList.add(ca);
        System.debug('Case Details : '+caseList);
        return null;
    } 
}

VisualForce Page

<apex:page >  
    <apex:tabPanel switchType="client" selectedTab="cinfo" id="ClientInfo" >
        <apex:tab label="Rest API Data" name="cinfo" id="cinfo">
        <div>
            <apex:outputLabel rendered="Test">Rest API Details</apex:outputLabel>
        </div>

        </apex:tab>
        <apex:tab label="New Rest API Data" name="myrest2" id="myrest2">
            <div>
                <apex:outputLabel rendered="Test">XXXX</apex:outputLabel>
            </div>
            <apex:tabPanel switchType="client" selectedTab="cards" id="cardsPoints" rendered="Test">
                <apex:tab label="YY" name="YY" id="YY">
                <table class="mytable">
                <tr>
                    <th>Id</th>
                    <th>CaseNumber</th>
                    <th>Subject</th>
                    <th>Status</th>
                    <th>Priority</th>
                    <th>Type</th>
                    <th>URL</th>
                </tr>
                <apex:repeat value="{!caseList}" var="ca">
                <tr>
                    <td>{!ca.Id}</td>
                    <td>{!ca.CaseNumber}</td>
                    <td>{!ca.Subject}</td>
                    <td>{!ca.Status}</td>
                    <td>{!ca.Priority}</td>
                    <td>{!ca.Attributes.type_Z}</td>
                    <td>{!ca.Attributes.url}</td>
                </tr>
                </apex:repeat>
                </table>
                </apex:tab>
                <apex:tab label="XX" name="XX" id="XX">
                    <table class="mytable">
                    <tr>
                        <th>XXX</th>
                        <td>XXX</td>
                    </tr>
                    <tr>
                        <th>XX</th>
                        <td>XX</td>
                    </tr>
                    <tr>
                        <th>XX</th>
                        <td>XX</td>
                    </tr>
                    <tr>
                        <th>XX</th>
                        <td>XX</td>
                    </tr>
                    <tr>
                        <th>XX</th>
                        <td>XX</td>
                    </tr>
                    </table>
                </apex:tab>
            </apex:tabPanel>
        </apex:tab>
    </apex:tabPanel>
</apex:page>

I am also getting the below error.

Unknown property 'caseList' referenced in TabVisualForcePage

UPDATE-1:
I changed my code as per your guidance !

<apex:page controller="ApexRestController" >  
    <apex:form>
        <apex:actionFunction name="callWebService1" action="{!getCaseDetailsById}" reRender="tab2" />
              <apex:tabPanel switchType="client" value="{!caseList}" selectedTab="cards" id="cardsPoints" rendered="Test" >
                <apex:tab label="YY" name="YY" id="YY" ontabenter="getCaseDetailsById()">
                    <apex:pageBlock id="table1">
                        <b>Output Contact Details </b>
                        <apex:pageBlockTable value="{!caseList}" var="ca">
                            <apex:column headerValue="Id" value="{!ca.Id}" />
                            <apex:column headerValue="CaseNumber" value="{!ca.CaseNumber}" />
                            <apex:column headerValue="Subject" value="{!ca.Subject}" />
                            <apex:column headerValue="Status" value="{!ca.Status}" />
                            <apex:column headerValue="Priority" value="{!ca.Priority}" />
                            <apex:column headerValue="Type" value="{!ca.Attributes.type_Z}" />
                            <apex:column headerValue="URL" value="{!ca.Attributes.url}" />
                        </apex:pageBlockTable>
                    </apex:pageBlock>
                    </apex:tab>
            </apex:tabPanel>
    </apex:form>
</apex:page>

But no tabs I can see

Best Answer

I will suggest you to change your design as follows:

Since there are could be 10 tabs for your use case, so you can create separate VFP pages and include them into main page.

But, you can design according to your own use case rather then creating separate pages.

By the way, for an example I am also displaying an outputPanel which will show correct tab selection, which conforms that it is displaying correctly.

Main Page

This is the container page which will display TabPanel and will hold all the tabs underneath.

<apex:page id="RestAPITabPage" showHeader="false" controller="ApexRestController">
    <apex:tabPanel id="tabpanelId"  value="{!var}" selectedTab="{!var}">        

        <apex:tab label="Rest API Data" name="cinfo" id="cinfo" ontabenter="setActiveTab('cinfo')">
            <apex:include pageName="RestAPIDatePage"/>            
        </apex:tab>

        <apex:tab label="New Rest API Data" name="myrest2" id="myrest2" ontabenter="setActiveTab('myrest2')">
            <apex:include pageName="NewRestAPIDatePage"/>                                       
        </apex:tab>
    </apex:tabPanel>
    <apex:form>
        <apex:actionFunction name='setActiveTab' action='{!setActiveTab}' reRender="tabpanelId,values">
        </apex:actionFunction>

        <apex:outputPanel id="values">
            <apex:outputText value="{!var}" label="You have selected:" />
    </apex:outputPanel>
    </apex:form>
</apex:page>

Controller

public class ApexRestController {
    /*Tab var*/
    public String var{get;set;}
    public List<Case> caseList{get;set;}

    public ApexRestController(){
        var = 'cinfo';
    }

    public void setActiveTab() {
        if(var == 'cinfo'){
            var='myrest2';
        }
        else {
            var = 'cinfo';
        }        
    }

    public void getCaseDetailsById()
    {
        //populate caseList, here you will call webservice and populate data
        caseList = [SELECT Id, CaseNumber, Subject,Status,Priority FROM Case WHERE Id='50090000001N25E'];
    }
}

Let's say on selection of myrest2 i.e. New Rest API Data you would like to show the caseList.

NewRestAPIDatePage

Here setActiveTab() assigning the correct tabid and on the visualforce page loading you can call action method.

I have shown here as a page action method. You can also call this method from setActiveTab() rather page action. It is up to your design.

<apex:page id="NewRestAPIDatePage" controller="ApexRestController" action={!getCaseDetailsById}>
    <apex:pageBlock id="table1">
        <b>Output Case Details </b>
        <apex:pageBlockTable value="{!caseList}" var="ca">
            <apex:column headerValue="Id" value="{!ca.Id}" />
            <apex:column headerValue="CaseNumber" value="{!ca.CaseNumber}" />
            <apex:column headerValue="Subject" value="{!ca.Subject}" />
            <apex:column headerValue="Status" value="{!ca.Status}" />
            <apex:column headerValue="Priority" value="{!ca.Priority}" />                           
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

RestAPIDatePage (just a sample page is showing, nothing fancy as an example)

<apex:page id="RestAPIDatePage">
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your RestAPIDatePage Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>

Output (working as expected at my DE)

When the tab page is displayed it will look like this, here by default "Rest API Data" is displaying since in the Controller constructor var = 'cinfo' is assigned.

initial load

Clicking on "New Rest API Data" tab it will display:

new rest API data

Clicking on "Rest API Data" tab it will display:

Rest API Data