1

I am trying to use a different components in a VF page.At present,the component is made only on Account object.The requirement is to make it for other standard objects like Contacts,Leads etc.

Any idea on how will this go ? A code sample will be really helpful.

Thanks in advance, James

Page

 <apex:page standardController="Account">  <!-- This is for Account,how to do it for other objects ? -->
  <c:MadoleChartComponent />
 </apex:page>  

Component

<apex:component Controller="HighchartsController">
   <script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
   <script src="https://code.highcharts.com/highcharts.js"></script>
   <script src="https://code.highcharts.com/modules/exporting.js"></script>

  <div id="container" style="min-width: 310px; height: 400px; margin:0 auto"></div>

    <script>
        pieOrdinate = {!X};
       // pieOrdinate = ServerStr.split(',');
         $(function () {
         $('#container').highcharts({
         title: {
         text: 'Chart showing opportunities'
    },
    xAxis:{
            categories: ['Jan','Feb','Mar','Apr','May','Jun','July','Aug','Sept','Oct','Nov','Dec']
        },
          labels: {
          items: [{
          html: 'Opportunities',
          style: {
                left: '50px',
                top: '18px',
                color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
            }
        }]
    },
    series: [ {
        type: 'column',
        name: 'Indian Railways',
        data: {!str}
        //data:[2,3,4,5,6]
    },
     {
        type: 'spline',
        name: 'Monthly Sales', // Average
       // data: [3, 2.67, 3, 6.33, 3.33],   
       data :{!bar},
        marker: {
            lineWidth: 2,
            lineColor: Highcharts.getOptions().colors[3],
            fillColor: 'white'
        }
    },
    {
        type: 'pie',
        name: 'Total consumption',
        data: [ {
            name: 'Lost',
            //y:23,
            y :parseInt(pieOrdinate[0]),
            sliced:true,
            selected:true,
            color: Highcharts.getOptions().colors[1] // Opp's Lost color
          }, 
           {
            name: 'Won',
            y:parseInt(pieOrdinate[1]),
            color: Highcharts.getOptions().colors[2] // Opp's won color
          }],
           center: [100, 80],
           size: 100,
           showInLegend: false,
           dataLabels:
           {
             enabled:true
           }
         }]
     });
  });
  </script>
 </apex:component>



   **=== Class ===**

     public class HighchartsController
      {  
        public String str;
        public String getStr()
        {
          String res = '';
            Integer i;
            //SOQL 
            res = '[';
            for(i=1;i<13;i++)
            res +=  '' + (i+1) +  ',';
            res += 12;
            res += ']';
            return  res;
        } 
      public String bar;
      public String getBar()
      {
          String str = '';
            Integer i;
            //SOQL 
            str = '[';
            for(i=1;i<13;i++)
            str +=  '' + i + ',';
            str += 12;
            str += ']';
            return  str;
      }


    public List<Integer> X;
    public List<Integer> getX()
    {
         X=new List<Integer>();
         String q = 'Select count(Id),StageName from opportunity where StageName IN(\'Closed Won\',\'Closed Lost\') group by StageName';
         AggregateResult[] agr =Database.query(q);
         X.add(Integer.valueof(agr[0].get('expr0')));
         X.add(Integer.valueof(agr[1].get('expr0')));
         return X;
    }
    public void setX()
    {}

   }
2
  • I think it would also be helpful to see relevant code in the HighChartsController class. The page itself appears to be driven by that.
    – pchittum
    Aug 4 '14 at 14:00
  • HighChartsController class added to the question.I think I'll have to add attribute to take it for generic Sobject ? Thanks.
    – JJoseph
    Aug 5 '14 at 5:17
2

Without seeing the controller code, I'm going to venture a guess that what you need to do is:

  1. Clone the component, and the component's controller
  2. Edit the cloned controller to pull data from your new object
  3. Edit your cloned component to utilize your new controller
  4. ...
  5. Profit!
3
  • Have added Controller in my question.I tried something like this below but still no luck.There is one one or two things unique on each object and so i tried to generalize the component.Your help will be needy. <apex:component> <apex:attribute type="sObject" name="sobj" required="true" description="test"/> <apex:attribute name="fieldsets" type="Schema.FieldSetMember[]" description="test"/> <apex:repeat var="field" value="{!fieldsets}"> <apex:outputText value="{!sobj[field]}" /> </apex:repeat> </apex:component> . Another comment for Page.Posting another comment.
    – JJoseph
    Aug 5 '14 at 8:49
  • and Page <apex:page standardController="Account"> <c:MyVisualforceComponent sobj="{!Account}" fieldsets="{!$ObjectType.Account.FieldSets.AccountFields}" /> </apex:page>
    – JJoseph
    Aug 5 '14 at 8:51
  • If you can please help me with an example,that would help me to understand much better.
    – JJoseph
    Aug 5 '14 at 12:32
1

James,

I'm reformatting your code to make it easier to read. Please familiarize yourself with StackExchange's code inclusion tools so that this is easier in the future.

<apex:component>
<apex:attribute type="sObject" name="sobj" required="true" description="test"/>
<apex:attribute name="fieldsets" type="Schema.FieldSetMember[]" description="test"/>
<apex:repeat var="field" value="{!fieldsets}">
    <apex:outputText value="{!sobj[field]}" />
</apex:repeat>

You can totally pull in a fieldset name here, but the type is going to be "string" and it should probably be required. To utilize a fieldset, your component is going to need its own Controller to find the fieldset elements. Once you've created a controller with the constructor logic to get the fields in your fieldset, you'll likely want to use dynamic soql to construct a query with those fields to display in your component.

You can think of your component as a miniature page snippet that will be merged into the HTML when rendered by visualforce. Because it's a miniature page, it can have it's own controller. In this case a controller that utilizes two parameters: the sObject API name and the Fieldset name you want to retrieve. It will then need to find the fields that are part of that fieldset on that object. Once it's done that, it will need to use dynamic soql to generate a query using those fields. Then you'll execute your query into a list, and then render the results via your components vf markup.

Using this recipe Your component will look almost identical to what you posted, but with the addition of a controller. Here's a getting started bit:

<apex:component Controller="MyAwesomeControllerICopiedAndPastedFromStackExchange">
<!-- These attributes are REQUIRED -->
<apex:attribute type="String" name="sobj" required="true" description="Original poster failed to provide a useful description"/>
<apex:attribute type="String" name="fieldsetName" required="true" description="Original poster failed to provide a useful description"/>

<!-- This is the Markup of the actual component. -->
<!-- An apex:repeat tag iterates over the collection specified by the value attribute
        For each iteration it provides a local variable whose name you assign with the
        var attribute. So, for example: we'll iterate over the records returned
        by our query, and then for a given record, we'll iterate over
        the fields in the fieldsets. -->

<!-- iterate over each of the records in the records collection -->
<apex:repeat var="record" value="{!records}">
    <!-- iterate over each of the fields in the fieldset -->
    <apex:repeat var="field" value="{!fieldsets}"> 
        <!-- for this iteration's record and for this field in the fieldset
                    create an outputText field. -->
        <apex:outputText value="{!record[field]}" />
    </apex:repeat>
</apex:repeat>

//The Controller will look like this:
public with sharing class MyAwesomeControllerICopiedAndPastedFromStackExchange {


// Can't use property syntax for component attributes so here's setters:
public string sobj;
public string fieldsetName;

public void setSobj(string incomingSobj){
    this.sobj = incomingsObj;
}

public void setFieldsetName(string incomingFieldsetName){
    this.fieldsetName = incomingFieldsetName;
}

public MyAwesomeControllerICopiedAndPastedFromStackExchange(){

}

Public List<Schema.FieldSetMember> getFields() {
    Schema.SObjectType t = Type.forName(this.sobj).getSObjectType();
    return t.contact.fieldSets.get(this.fieldsetName).getFields();
}

}

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.