• MayTheForceBeWithYou
  • NEWBIE
  • 175 Points
  • Member since 2011

  • Chatter
    Feed
  • 5
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 16
    Questions
  • 34
    Replies

Hi Guys,

 

I'm struggling to write an apex test class for my apex trigger. Please Bear in mind that this is the second thing i've ever written in APEX, however i do have other programming knowledge.

 

My Apex Trigger looks something like this:

 

trigger DisputeStatus on Dispute__c (before update) {

	// Get Trigger Object
	Dispute__c dispute = trigger.new[0];
	
	
	if((dispute.Un_Actioned_Conversations__c == 0) && (dispute.Resolved__c == true))
	{
		dispute.Status_of_Problem__c = 'Resolved';
		dispute.Resolved__c = true;
	} else if (dispute.Un_Actioned_Conversations__c > 0)
	{
		dispute.Status_of_Problem__c = 'Waiting for ACTION';
		dispute.Resolved__c = false;
	} else
	{
		dispute.Status_of_Problem__c = 'Waiting for RESPONSE';
		dispute.Resolved__c = false;
	}
}

 

Background information

 

An account object has these custom "Dispute" objects attached

 

A dispute object has custom "Conversation" objects attached

 

dispute.Un_Actioned_Conversations__c // is a roll up summary counting a boolean field in conversation 

 

However i have no idea how to write an APEX test class. I understand that it's essentially a unit test and should test the all the scope of the trigger. I've had a go, using tutorials, and produced the following code:

 

@isTest
private class testDisputeStatus {

    static testMethod void myUnitTest() {
        Dispute__c dispute = new Dispute__c();

		        
        dispute.Un_Actioned_Conversations__c = 0;
        dispute.Resolved__c = false;

		insert dispute;
		
		dispute.Un_Actioned_Conversations__c = 1;
		
		update dispute;
		
		dispute.Resolved__c = true;
		
		update dispute;
		
		dispute.Un_Actioned_Conversations__c = 0;
		
		update dispute;
        
    }}

 However all i've managed to produce is : 

Field is not writeable: Dispute__c.Un_Actioned_Conversations__c

 I appreciate i'm probably doing this completely wrong however being pointed in the right direction would be appreciated.

 

Any ideas?

 

From the Case object, we have a custom button that creates an RMA with case and account information filled in and then opens the new RMA record. It works fine in the normal salesforce.com.

 

In the Service Cloud Console, we have Accounts, Cases, and RMA's. If we create new Cases or new RMA's from the Account, the new records get create in new subtabs to the account.

 

But if we launch our CaseToRMA page from the case in a Service Cloud Console subtab, it results in a whole new instance of saleforce.com running in the original case tab. What we want is for the new RMA to open in a new subtab under the account and to leave the case open.

 

CasetoRMA class

 

public class CaseToRMA {
    public Case c {get; set;}
    public RMA__c rma {get; set;}
public CaseToRMA () { c = [ select c.Id, c.CaseNumber, c.Account.ShippingCountry, c.Account.ShippingPostalCode, c.Account.ShippingState, c.Account.ShippingCity, c.Account.ShippingStreet, c.Account.Name, c.AccountId from Case c where id = : apexPages.currentPage().getParameters().get('id')];
List<Settings__c> cs = [ select RMA_Warehouse__c from Settings__c]; RMA__c rma = new RMA__c( ZipPostalCode__c = c.Account.ShippingPostalCode, Warehouse__c = (cs.size() > 0) ? cs[0].RMA_Warehouse__c : null, Street__c = c.Account.ShippingStreet, StreetTextArea__c = c.Account.ShippingStreet, RMADate__c = system.today(), Country__c = c.Account.ShippingCountry, City__c = c.Account.ShippingCity, Case__c = c.Id, Account__c = c.AccountId, AccountName__c = c.Account.Name, Reference__c = c.CaseNumber); }

public PageReference NewRMA() {
insert rma;
return new PageReference('/' + rma.id);
}

 

 

 

 VisualForce Page

<!-- Old way -->
<apex:page controller="CaseToRMA" action="{!newRMA}" >
<!-- Attempt at opening in a new tab
<apex:page controller="CaseToRMA" action="{!newRMA}" >
    <apex:includeScript value="/support/console/20.0/integration.js"/>
    <script type="text/javascript">
        function init() {
                //First find the ID of the primary tab to put the new subtab in
            sforce.console.getEnclosingPrimaryTabId(openSubtab);
        }
        var openSubtab = function openSubtab(result) {
                //Now that we've got the primary tab ID, we can open a new subtab in it
            var primaryTabId = result.id;
            sforce.console.openSubtab(primaryTabId , '/' + rma.id, false,
                rma.Name, null, null);
        };
    </script>
    <body onLoad="Init()"/>
-->
</apex:page>

 If someone has a working example of this, it would be great.

 

 

I'm attempting to integrate the jQuery File Uploader utility built by blueimp into a visualforce page that will be embedded into a custom object's page layout. I have the front-end done but now I'm a little stuck for getting the back-end working. I was going to have the form submit to an Apex REST Method, but the content-type multipart/form-data isn't supported. I've seen some workarounds on the web for uploading to external servers but I'm still having trouble getting the light bulb to go off for my use case; any help is greatly appreciated, thanks!

I am using an Apex trigger and asynchronous method to perform a callout to the JSON REST API for Wordpress. I continue to receive 500 Internal Server Error responses in my debug log when I edit a Salesforce record, but if I copy/paste the corresponding JSON into the Postman plug-in for Chrome the post is created as expected. Any help is appreciated, thanks!

 

trigger insertPost on Custom_Object__c (after insert, after update) {
    String theIds = '';
    for (Custom_Object__c c : Trigger.new) {
        if (theIds == '')
            theIds = c.Id;
        else
            theIds += '|' + c.Id;
    }
    //Make asynchronous web service callout to insert post
    if (theIds != '')
        WebServiceCallout.sendPost(theIds);
}

 

public class WebServiceCallout {
 
    @future (callout=true)
    public static void sendPost(String theIds) {
 
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        
        if(Test.isRunningTest()){
            Website_Settings__c wpSettings = new Website_Settings__c(Wordpress_URL__c = 'https://testing.com/', Wordpress_Username__c = 'Test', Wordpress_Password__c = 'Test');        
            insert wpSettings;
        }
        
        //Set Headers from Custom Settings & Visualforce
        Website_Settings__c wpSettings = Website_Settings__c.getInstance();
        if (wpSettings.Wordpress_URL__c!=null && wpSettings.Wordpress_Username__c!=null && wpSettings.Wordpress_Password__c!=null){
            
            //Set Endpoint
            String endpoint = wpSettings.Wordpress_URL__c;
            if (endpoint.endsWith('/'))
                req.setEndpoint(endpoint+'wp-json.php/posts/');
            else
                req.setEndpoint(endpoint+'/wp-json.php/posts/');
            
            //Set Method
            req.setMethod('POST');
            
            //Specify the required user name and password to access the endpoint
            String username = wpSettings.Wordpress_Username__c;
            String password = wpSettings.Wordpress_Password__c;
            Blob headerValue = Blob.valueOf(username + ':' + password);
            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader);
            
            //Specify Content-Type
            req.setHeader('Content-Type', 'application/json');
            
            //Specify Cache-Control
            req.setHeader('Cache-Control', 'no-cache');
            
            //Set Body
            objectToJSON.theId = theIds;
            objectToJSON jsonClass = new objectToJSON();
            req.setBody(jsonClass.jsonData());
            
            try {
                System.debug(req.getHeader('Authorization'));
                System.debug(req.getHeader('Content-Type'));
                System.debug(req.getBody());
                if (!Test.isRunningTest())    
                    res = http.send(req);
            }
            
            catch(System.CalloutException e) {
                System.debug('Callout error: '+ e);
                System.debug(res.toString());
                System.debug(req.getBody());
            }
        
        }
 
    }
 
}

 

public with sharing class objectToJSON {
    //Global variables
    public static String theId;
    public list<String> theIds;
    public list<jsonObjectData> allObjects{get;set;}
    
    public objectToJSON() { 
        //***This method queries the database for information and converts it to JSON***
        //If URL parameters are set then query the database
        if (ApexPages.currentPage()!=null)
            if (ApexPages.currentPage().getParameters().get('theId')!=null && ApexPages.currentPage().getParameters().get('theId')!='')
                theId = String.escapeSingleQuotes(ApexPages.currentPage().getParameters().get('theId'));
        if (theId.contains('|'))
            theIds = theId.split('\\|',-1);
        else{
            theIds = new list<String>();
            theIds.add(theId);
        }
        allObjects = new list<jsonObjectData>();
        list<Custom_Object__c> objects = [SELECT Id, Name, Description__c, A__c, B__c, C__c FROM Custom_Object__c WHERE Id IN :theIds LIMIT 10000];
        for (Custom_Object__c o : objects){
            allObjects.add(new jsonObjectData(o));          
        }
    }
    
    public String jsonData() {
        String jsonData = '[';
        Integer x=0;
        while (allObjects.size()>x) {
            if (x==0)
                jsonData += '{';
            else
                jsonData += ',{';
            jsonObjectData o = allObjects[x];
            jsonData += '\"title\":\"'+o.name.replace('\"','\\"')+'\",';
            jsonData += '\"status\":\"publish\",';
            jsonData += '\"type\":\"custom\",';
            jsonData += '\"content_raw\":\"'+o.content.replace('\"','\\"').replace('\n','')+'\",';
            jsonData += '\"excerpt_raw\":\"'+o.excerpt.replace('\"','\\"').replace('\n','')+'\",';
            jsonData += '\"comment_status\":\"closed\"';
            jsonData += '}';
            x++;
        }
        jsonData += ']';
        if (x==1){
//Remove array formatting for individual post jsonData = jsonData.substring(1); jsonData = jsonData.substring(0,jsonData.length()-1); } return jsonData; } public class jsonObjectData { //*****Wrapper Class***** //Global variables for wrapper class public String name{get;set;} public String content{get;set;} public String excerpt{get;set;} public jsonObjectData(Custom_Object__c o) { //***Constructor method to create a JSON object*** //Define content variables String a = ''; String b = ''; String c = ''; //Set content variables if (o.A__c!=null) a = String.valueOf(o.A__c); if (o.B__c!=null) b = String.valueOf(o.B__c); if (o.C__c!=null) c = String.valueOf(o.C__c); //Define & Set description variable String description = ''; if (o.Description__c!=null) description = String.valueOf(o.Description__c); //Set name name = o.Name; //Set content content = '<div class="custom"></div>\n<div class="row clearfix ">\n<div class="col col_1_2 ">\n<div class="inner">\n<div class="styled_table table_blue">\n<table>\n<thead>\n<tr>\n<th>Custom</th>\n<th> </th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>A</td>\n<td>'+a+'</td>\n</tr>\n<tr>\n<td>B</td>\n<td>'+b+'</td>\n</tr>\n<tr>\n<td>C</td>\n<td>'+c+'</td>\n</tr>\n</tbody>\n</table>\n</div>\n</div>\n</div>\n</div>\n'; //Set excerpt excerpt = '<p>'+description+'</p>\n'; } } }

 

Hi there,

 

So I'm trying to use the Salesforce AJAX proxy to load chatter profile images to avoid tainting my canvas due to the cross-domain issue of these images being stored on c.na1.content.force.com as opposed to c.na1.visual.force.com. I've just about done it except that I'm not sure how to decipher the text response the proxy returns and convert it into an image.

 

Here's a stripped-down version of my code:

 

sforce.connection.remoteFunction({
          url : SERVER_URL,
          requestHeaders : {
              'Authorization' : 'Bearer ' + SESSION_ID
          },
          onSuccess : function(response) {
                //alert(response);
                img.src=response;
          }
});  

To get an idea of the kind of text response I'm receiving you can do a view-source on the anonymous chatter image located at "/profilephoto/005/T" (Chrome users may have to manually type 'view-source:' before the URL)

 

I'm wondering if I might need to go through some sort of blob & base64 encoding/decoding in order to accomplish this. Your advice is greatly appreciated; thanks.

 

 

Having some issues getting my Visualforce page to play nicely with PrintFriendly. The iFrame/modal tool pops up as expected, but then when I click the PDF button I am given an error. I believe this may be due to the fact that Salesforce is a password-protected platform.

 

However, I've tried the /secur/frontdoor.jsp workaround using both methods of entry (session id and straight login credentials) but neither seemed to do the trick. I believe the PrintFriendly service may not be willing to wait for the javascript on SF's server to redirect me to my VFpage.

 

Has anyone integrated with PrintFriendly before that could provide some guidance? It would be much appreciated!

 

PS A little background here-I am using the Google Visualization API to generate an interactive chart; thus I cannot use the renderAs attribute as this would just produce a static PDF of the initial landing page. I've pondered creating parameter(s) for all the different possible customizations but this would be very cumbersome as there are many, plus the number of possible customizations will increase over time.

 

Thanks again!

Just a quick question confirming my understanding of Salesforce's Governor Limits regarding mass emails.

 

My client wishes to send mass emails out in batches containing 25-40 external addresses per email to comply with industry regulations. My understanding is that since the total number of emails sent will not exceed 1,000 and the total number of external addresses emailed will not exceed 1,000 I should be okay from an Email governor limit standpoint.

 

My question is whether I should be concerned about the 25 concurrent API calls governor limit; I believe this limit would apply to my situation-can anyone confirm this and whether there are any other governor limits I should be taking into consideration?

 

Much appreciated!

Been beating my head against a wall all day over this-I am using the jquery plug-in fullCalendar within my Salesforce VFPage and have been unable to call Apex variables from within the javascript that constructs the calendar.

 

When I use the typical notation of {!someVariable} then the calendar just flat-out doesn't render. After some searching I came across the strategy to utilize a separate VFpage and controller extension to create a JSON feed that passes the event data.

 

I tried this method, but still nothing-the calendar does render, but no event pops up within it. Even after I hardcoded a bunch of values for testing purposes I still had no luck. Below you will find the VFPage of my calendar page along with the VFPage and controller extension of the JSON feed pages-any help would be GREATLY appreciated, thanks guys.

 

Calendar VFPage: 

 

<apex:page standardController="Event" title="Appointments">
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'cupertino/theme.css')}" />
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.css')}" />
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.print.css')}" media="print" />
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'jquery/jquery-1.5.2.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'jquery/jquery-ui-1.8.11.custom.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'fullcalendar/gcal.js')}"></script>
<script src="/soap/ajax/23.0/connection.js" type="text/javascript"></script> 
<script src="/soap/ajax/23.0/apex.js" type="text/javascript"></script>
<script type="text/javascript">         
    $(document).ready( function(){
  
        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();        
        
        var calendar = $('#calendar').fullCalendar({
            theme: true,
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            defaultView: 'agendaWeek',
            selectable: true,
            selectHelper: true,
            allDaySlot: true,
            aspectRatio: 1.75,
            minTime: 7,
            maxTime: 20,
            //weekMode: 'variable',
            editable: false,
            eventClick: function(event) {
                // opens events in a popup window
                window.open(event.url, 'gcalevent', 'width=700,height=600');
                return false;
            },  
            eventSources: [
                    {
                    // U.S. holidays
                    url: 'https://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
                    color: '#6B6B6B'
                    }
                ],  
            events: '/apex/queryToJSON?evId=a58U0000008MhIzIBL'
        });
    });
</script>
<apex:form >

<apex:pageBlock >
<div id="calendar" style="width: 820px; float: left;"></div>
<br style="clear: both;" />
<br />
<apex:commandButton action="{!Save}" value="Done" />
<apex:commandButton action="{!Cancel}" value="Cancel" />
<br />
<br />
</apex:pageBlock>
</apex:outputPanel>
</apex:form>
</apex:page>

 

JSON Feed VFPage: 

 

<apex:page controller="queryToJSON" 
contentType="application/x-JavaScript; charset=utf-8" showHeader="false" standardStylesheets="false" sidebar="false">[<apex:repeat value="{!allEvents}" var="ev" >{
"title":{!ev.name},
"start": {!ev.start},
"end": {!ev.stop},
"allDay": false,
"color": "#36C",
"url":{!ev.url}
}
</apex:repeat>]
</apex:page>

 

JSON Feed Controller:

 

public class queryToJSON {

        public custEvent__c thisEvent;
        public fullCalendarEvent allEvents{get;set;}

         public queryToJSON() { 
        if (ApexPages.currentPage().getParameters().get('evId')!=null){
                String evId = ApexPages.currentPage().getParameters().get('evId');
                thisEvent = [SELECT Id, Customer_Name__r.Name from custEvent__c where Id = :evId LIMIT 1];
                allEvents = new fullCalendarEvent(thisEvent);
        }
                
     }
     
     public class fullCalendarEvent {
        
        public String name{get;set;}
        public String url{get;set;}
        public String start{get;set;}
        public String stop{get;set;}
        
        public fullCalendarEvent(custEvent__c thisEvent) {
                name = JSON.serialize(thisEvent.Customer_Name__r.Name);
                url = JSON.serialize('/'+thisEvent.Id);
                start = JSON.serialize(datetime.now());
                stop = JSON.serialize(datetime.now().addDays(2));
        }
        
     }
    
}

 

So I have an inputText component on my Visualforce page that dynamically edits my SOQL query for every onkeyup and also rerenders a table whose values are based upon the SOQL query. My issue is best explained with an example:

 

If a user wanted to search for "Salesforce" he/she would obviously type out S, then a, then l, etc. Since the SOQL query is edited with each keyup the table below continually rerenders as the user types. In certain scenarios such as this one, this can be a major problem.

 

Assume that a search term for Salesforce would return no records, leaving the table empty. However, a search of Sales would return many records, say 350.

 

Once the user finishes typing the second 's' the "Sales" query begins accumulating several records, but the user is simultaneously typing new letters-f, o, r, etc. Each of these remaining letters lead to SOQL queries that return 0 results (Salesf gives 0 results, Salesfo gives 0 results, etc.) and thus are completed quickly. The final result is that even though the ultimate search term "Salesforce" should return 0 records, the table is actually populating with the results of the search term "Sales" because, given the high number of pulls from the database, this SOQL query actually completed after the other SOQL queries finished.

 

I have found solutions for a similar issue with AJAX such as the one here. The problem is that these all require utilizing Javascript and the setTimeout function to cause the server to pause before searching the database (the assumption here is that this allows the user to finish typing his/her ultimate search term). Unfortunately, Salesforce seems to ignore the setTimeout javascript function as any sort of sleep/wait method could potentially throw off their multi-tenant architecture.

 

Does anyone have any good ideas I could utilize to overcome this issue that don't involve some sort of a sleeper method? Note: I have already noted that if I add a limit to my SOQL query this issue can be resolved, but unfortunately my client demands there be no limit size to the search results...

I have been beating my head against the wall trying to get a dynamic reRender to work on my visualforce page. Essentially my VFPage embeds via iFrames a separate VFpage that displays a table. I want the user to be able to select from a picklist the number of tables he/she wishes to be displayed (1-5). Upon changing the # of tables the VFpage should be refreshed to display the corresponding number of iFrames. This is all working properly so far.

 

Here is my issue-the VFpage embedded via iFrames contains dynamic content as well and I would like this information to be preserved should another table be added to the page; thus, I want the onchange event on my table # picklist to cause a dynamic reRender that will only do a partial page refresh of the iFrames formerly not displayed while leaving the visible iFrames untouched. Hopefully this makes sense but I will post my VFPage and Controller extension as well for you to look at; thanks so much!

 

VFPage:

 

<apex:page standardController="Quantitativo__c" extensions="MultQuantAnal">
<div align="center">
<h1 style="font-size:16pt"><apex:outputText value="Quantitative Analysis"></apex:outputText></h1>
</div>
<apex:form >
<div align="center">
<br/>
<apex:outputText >Tabels:&nbsp;</apex:outputText>
<apex:selectList id="chooseTables" value="{!numTables}" size="1">
          <apex:selectOption itemValue="1" itemLabel="1"/>
          <apex:selectOption itemValue="2" itemLabel="2"/>
          <apex:selectOption itemValue="3" itemLabel="3"/>
          <apex:selectOption itemValue="4" itemLabel="4"/>
          <apex:selectOption itemValue="5" itemLabel="5"/>
<apex:actionSupport event="onchange" reRender="{!PanelRef}"/>
</apex:selectList>
</div>
<br/>
<apex:outputPanel id="one">
<apex:iframe height="250" rendered="{!numTables>=1}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="two">
<apex:iframe height="250" rendered="{!numTables>=2}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="three">
<apex:iframe height="250" rendered="{!numTables>=3}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="four">
<apex:iframe height="250" rendered="{!numTables>=4}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="five">
<apex:iframe height="250" rendered="{!numTables==5}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
</apex:form>
</apex:page>

 

Controller Extension:

 

public class MultQuantAnal {

    public Integer numTables{get;set;}
    
    public void setnumTables(String numVar) {
        this.numTables = Integer.valueOf(numVar);
    }

    public MultQuantAnal(ApexPages.StandardController controller) {
        this.numTables=1;
    }

    public String getPanelRef(){
        if (numTables==1){
            return 'one,two,three,four,five';
        }
        else if (numTables==2){
            return 'two,three,four,five';
        }
        else if (numTables==3){
            return 'three,four,five';
        }
        else if (numTables==4){
            return 'four,five';
        }
        else {
            return 'five';
        }
    }
}

 

I've created a Visualforce edit page with a custom save method and a custom save&new method. Unfortunately it seems only some of my fields are saved while others are not. I've read a few posts about this but unfortunately none of the solutions worked for me-any help you can provide would be greatly appreciated, thanks!

 

VFPage:

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABPEdit" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/>
</div>
<apex:pageBlock >
<apex:pageBlockButtons >
<apex:commandButton action="{!SaveRecord}" value="Salvar"/>
<apex:commandButton action="{!SaveAndNew}" value="Salvar & Nova"/>
<apex:commandButton action="{!Cancel}" value="Cancelar"/>
</apex:pageBlockButtons>
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField value="{!Janela_de_Acesso__c.Name}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1">
<apex:panelGrid columns="3" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(this.options[this.selectedIndex].text);">
<apex:selectOptions value="{!items}"/>
<apex:actionFunction immediate="true" name="searchServer" action="{!runSearch}" reRender="Available,Over">
<apex:param assignTo="{!sObjectDesc}" name="pesq" value="" />
</apex:actionFunction>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="para:" for="SearchBox"/>
<apex:inputText id="SearchBox" value="{!searchText}"/>
</apex:pageBlockSectionItem>
<apex:commandButton action="{!runSearch}" reRender="Available,Over" value="Pesquisar"/>
</apex:panelGrid>
<apex:outputPanel id="Over">
<apex:outputText rendered="{!overMax}" value="A consulta retornou mais de 100 registros. Somente as 100 primeiras linhas são exibidas. Por favor, refine os critérios da busca." style="text-align:center;color:red"/>
</apex:outputPanel>
<apex:panelGrid columns="3" style="text-align: center; vertical-align: middle;">
<apex:panelGroup style="padding-right:3px;align:center">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<br/>
<apex:selectList title="Membros Disponíveis" multiselect="true" size="14" required="false" id="Available" value="{!selected}">
<apex:selectOptions value="{!searchResults}"/>
</apex:selectList>
</apex:panelGroup>
<apex:panelGroup >
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<apex:outputLabel value="Adicionar"/>
<br/>
<apex:commandButton action="{!DoSelect}" value=">>" rerender="Available,Selected"/>
<br/>
<apex:commandButton action="{!DoUnselect}" value="<<" rerender="Available,Selected"/>
<br/>
<apex:outputLabel value="Excluir"/>
</apex:panelGroup>
<apex:panelGroup style="align:center;">
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
<br/>
<apex:selectList title="Membros Selecionados" multiselect="true" size="14" required="false" id="Selected" value="{!unselected}">
<apex:selectOptions value="{!selectResults}"/>
</apex:selectList>
</apex:panelGroup>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>

 

Controller:

public class JDABPEdit {
    
   // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public Boolean overMax=false;
    public String searchObject;
    public Janela_de_Acesso__c j;
    public Janela_de_Acesso__c l;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public List<SelectOption> selectResult = new List<SelectOption>();
    public String searchText {get;set;}
    public String sObjectDesc {get;set;}
    public List<String> selected {get; set;}
    public List<String> unselected {get; set;}
    
    //Constructor to apply fields
    public JDABPEdit(ApexPages.StandardController controller) {
        l = (Janela_de_Acesso__c) controller.getRecord();        
        j = [SELECT Id, Name, Status__c, Data_Inicial__c, Data_Final__c, sObjectIds__c, sObjectDesc__c from Janela_de_Acesso__c WHERE Id = :l.Id];
        List<String> sobjectIdList = new List<String>();
        List<String> sobjectDescList = new List<String>();
        for (String k : j.sObjectIds__c.split(';',0)){
            sobjectIdList.add(k);
        }
        for (String m : j.sObjectDesc__c.split(';',0)){
            m=m.replace('Business Plan :: ','');
            m=m.replace('Perfil :: ','');
            m=m.replace('Usuário :: ','');
            sobjectDescList.add(m);
        }        
        for (Integer i=0; i<sobjectIdList.size(); i++){
            selectResult.add(new SelectOption(sobjectIdList[i],sobjectDescList[i]));
        }
        j.sObjectIds__c='';
        j.sObjectDesc__c='';
        searchText = '';
        sObjectDesc = 'Business Plans';
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name, Business_Plan_Conta__r.Name from ' + searchObject + ' order by Name limit 100';
        runQuery();        
    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Business Plans','Business Plans'));
        options.add(new SelectOption('Perfis','Perfis'));
        options.add(new SelectOption('Usuários','Usuários'));
        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    public List<SelectOption> getSelectResults() {
        return selectResult;
    }
    
    // runs the actual query
    public void runQuery() {    
        try {
          results = Database.query(soql);
          if (results.size()==100){
            overMax=true;
          }    
          else {
            overMax=false;
          }   
          searchResult.clear(); 
          for (sObject r : results){
              If (sObjectDesc.contains('Business Plans')){
                  Business_Plan__c BPr = (Business_Plan__c) r;
                  searchResult.add(new SelectOption(BPr.Id,BPr.Name+' :: '+BPr.business_plan_conta__r.Name));  
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }
              Else If (sObjectDesc.contains('Perfis')){
                  Profile Pr = (Profile) r;
                  searchResult.add(new SelectOption(Pr.Id,Pr.Name));
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }
              Else If (sObjectDesc.contains('Usuários')){
                  User Ur = (User) r;
                  searchResult.add(new SelectOption(Ur.Id,Ur.Name));
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }        
          }         
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ocorreu um erro ao efetuar a busca, por favor, tente novamente'));
          }
 
  }

  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
    If (sObjectDesc.contains('Business Plans')){
        searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc.contains('Perfis')){
        searchObject='Profile';
    }
    Else If (sObjectDesc.contains('Usuários')){
        searchObject='User';
    }
    soql = 'select Id, Name from ' + searchObject;
    If (sObjectDesc.contains('Business Plans')){
        soql = soql.replace('select Id, Name from','select Id, Name, Business_Plan_Conta__r.Name from');
        soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\' or business_plan_conta__r.name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\'';
    }
    Else {
        if (!searchText.equals('')){
          soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\'';   
        }
    }
    soql += ' order by Name limit 100';  
    // run the query again
    runQuery(); 
    return null;
  }
  
  public PageReference doSelect() {
        for (String s: selected) {
            for (Integer i=0; i<searchResult.size(); i++){
                if (searchResult[i].getValue()==s){
                    selectResult.add(new SelectOption(s,searchResult[i].getLabel()));
                    searchResult.remove(i);
                    i--;
                }
            }
        }
        return null;
    }

    public PageReference doUnSelect() {
        for (String s: unselected) {
            for (Integer i=0; i<selectResult.size(); i++){
                if (selectResult[i].getValue()==s){
                    searchResult.add(new SelectOption(s,selectResult[i].getLabel()));
                    selectResult.remove(i);
                    i--;
                }
            }
        }
        return null;
    }   
        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {       
            for (selectOption s : selectResult){
                j.sObjectIds__c += s.getValue()+';';
                if (s.getValue().startswith(Label.BP_Id)){
                    j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.Perfil_Id)){
                    j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.User_Id)){
                    j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';';
                }
            }
        Update j;
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }
    
    public Boolean getOverMax(){
        return overMax;
    }    
    
    //Override Save Functionality
    public PageReference SaveRecord() {
            for (selectOption s : selectResult){
                j.sObjectIds__c += s.getValue()+';';
                if (s.getValue().startswith(Label.BP_Id)){
                    j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.Perfil_Id)){
                    j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.User_Id)){
                    j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';';
                }
            }
        Update j;
        PageReference pr = new PageReference('/'+j.Id);
        pr.setRedirect(true);
        return pr;
    }

}

 

I have a Visualforce page that emulates the functionality of the standard Salesforce Public Group edit page (Setup>>Manage Users>>Public Groups>>Edit) and it's (finally!) fully functional; however, there is one small edit I have been asked to make that I'm having difficulty with.  My reading and experience have shown that all required fields (at top of page) must be filled in order for the selectList functionality below to work; unfortunately I have been given the strict requirement of leaving the Name field blank and when I do this, as expected, the Add/Remove buttons do not work properly.  I've even tried leaving a blank space as the default value but this does not help (Currently the default has been left as '|'); it seems I must have text in the inputField textbox for the page to function properly. Anyone know how to overcome this issue? Thanks!

 

VFPage:

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABP" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/>
<apex:commandButton action="{!SaveRecord}" value="Salvar"/>
<apex:commandButton action="{!SaveAndNew}" value="Salvar & Nova"/>
<apex:commandButton action="{!Cancel}" value="Cancelar"/>
</div>
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}" />
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1">
<apex:panelGrid columns="2" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(this.options[this.selectedIndex].text);">
<apex:selectOptions value="{!items}"/>
<apex:actionFunction immediate="true" name="searchServer" action="{!runSearch}" reRender="Available,Over">
<apex:param assignTo="{!sObjectDesc}" name="pesq" value="" />
</apex:actionFunction>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="for:" for="SearchBox"/>
<apex:inputText id="SearchBox"  onkeyup="searchServer2(this.value);">
<apex:actionFunction immediate="true" name="searchServer2" action="{!runSearch}" reRender="Available,Over">
<apex:param assignTo="{!searchText}" name="searchB" value="" />
</apex:actionFunction>
</apex:inputText>
</apex:pageBlockSectionItem>
</apex:panelGrid>
<apex:outputPanel id="Over">
<apex:outputText rendered="{!overMax}" value="A consulta retornou mais de 100 registros. Somente as 100 primeiras linhas são exibidas. Por favor, refine os critérios da busca." style="text-align:center;color:red"/>
</apex:outputPanel>
<apex:panelGrid columns="3" style="text-align: center; vertical-align: middle;">
<apex:panelGroup style="padding-right:3px;align:center">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<br/>
<apex:selectList title="Membros Disponíveis" multiselect="true" size="14" required="false" id="Available" value="{!selected}">
<apex:selectOptions value="{!searchResults}"/>
</apex:selectList>
</apex:panelGroup>
<apex:panelGroup >
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
<apex:outputLabel value="Adicionar"/>
<br/>
<apex:commandButton action="{!DoSelect}" value=">>" rerender="Available,Selected"/>
<br/>
<apex:commandButton action="{!DoUnselect}" value="<<" rerender="Available,Selected"/>
<br/>
<apex:outputLabel value="Excluir"/>
</apex:panelGroup>
<apex:panelGroup style="align:center;">
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
<br/>
<apex:selectList title="Membros Selecionados" multiselect="true" size="14" required="false" id="Selected" value="{!unselected}">
<apex:selectOptions value="{!selectResults}"/>
</apex:selectList>
</apex:panelGroup>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
<div align="center">
<apex:commandButton action="{!SaveRecord}" value="Salvar"/>
<apex:commandButton action="{!SaveAndNew}" value="Salvar & Nova"/>
<apex:commandButton action="{!Cancel}" value="Cancelar"/>
</div>
</apex:form>
</apex:page>

 

Controller:

public class JDABP {    
    
    // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public Boolean overMax=false;
    public String searchObject;
    public Janela_de_Acesso__c j;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public List<SelectOption> selectResult = new List<SelectOption>();
    public String searchText {get;set;}
    public String sObjectDesc {get;set;}
    public List<String> selected {get; set;}
    public List<String> unselected {get; set;}
    
    //Constructor to apply fields
    public JDABP(ApexPages.StandardController controller) {
        j = (Janela_de_Acesso__c) controller.getRecord();
        j.Name='|';
        j.Status__c='Ativo';
        j.Data_Inicial__c=System.now();
        j.Data_Final__c=System.today()+30;        
        j.RecordTypeId = Label.Janela_de_Acesso_BP_RecordType;
        j.sObjectIds__c='';
        j.sObjectDesc__c='';
        searchText = '';
        sObjectDesc = 'Business Plans';
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name, Business_Plan_Conta__r.Name from ' + searchObject + ' order by Name limit 100';
        runQuery();

    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('Business Plans','Business Plans'));
        options.add(new SelectOption('Perfis','Perfis'));
        options.add(new SelectOption('Usuários','Usuários'));
        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    public List<SelectOption> getSelectResults() {
        return selectResult;
    }
    
    // runs the actual query
    public void runQuery() {    
        try {
          results = Database.query(soql);
          if (results.size()==100){
            overMax=true;
          }    
          else {
            overMax=false;
          }        
          searchResult.clear(); 
          for (sObject r : results){
              If (sObjectDesc.contains('Business Plans')){
                  Business_Plan__c BPr = (Business_Plan__c) r;
                  searchResult.add(new SelectOption(BPr.Id,BPr.Name+' :: '+BPr.business_plan_conta__r.Name));                    
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }
              Else If (sObjectDesc.contains('Perfis')){
                  Profile Pr = (Profile) r;
                  searchResult.add(new SelectOption(Pr.Id,Pr.Name));
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }
              Else If (sObjectDesc.contains('Usuários')){
                  User Ur = (User) r;
                  searchResult.add(new SelectOption(Ur.Id,Ur.Name));
                  for (SelectOption s: selectResult) {
                      for (Integer i=0; i<searchResult.size(); i++){
                          if (searchResult[i].getValue()==s.getValue()){
                              searchResult.remove(i);
                              i--;
                          }
                      }
                  }
              }        
          }           
        } catch (Exception e) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ocorreu um erro ao efetuar a busca, por favor, tente novamente'));
          }
 
  }

  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
    If (sObjectDesc.contains('Business Plans')){
        searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc.contains('Perfis')){
        searchObject='Profile';
    }
    Else If (sObjectDesc.contains('Usuários')){
        searchObject='User';
    }
    soql = 'select Id, Name from ' + searchObject;
    If (sObjectDesc.contains('Business Plans')){
        soql = soql.replace('select Id, Name from','select Id, Name, Business_Plan_Conta__r.Name from');
        soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\' or business_plan_conta__r.name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\'';
    }
    Else {
        if (!searchText.equals('')){
          soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\'';   
        }
    }
    soql += ' order by Name limit 100';  
    // run the query again
    runQuery(); 
    return null;
  }
  
  public PageReference doSelect() {
        for (String s: selected) {
            for (Integer i=0; i<searchResult.size(); i++){
                if (searchResult[i].getValue()==s){
                    selectResult.add(new SelectOption(s,searchResult[i].getLabel()));
                    searchResult.remove(i);
                    i--;
                }
            }
        }
        return null;
    }

    public PageReference doUnSelect() {
        for (String s: unselected) {
            for (Integer i=0; i<selectResult.size(); i++){
                if (selectResult[i].getValue()==s){
                    searchResult.add(new SelectOption(s,selectResult[i].getLabel()));
                    selectResult.remove(i);
                    i--;
                }
            }
        }
        return null;
    }
        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {
        try{
            for (selectOption s : selectResult){
                j.sObjectIds__c += s.getValue()+';';
                if (s.getValue().startswith(Label.BP_Id)){
                    j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.Perfil_Id)){
                    j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.User_Id)){
                    j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';';
                }
            }
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }
    
    public Boolean getOverMax(){
        return overMax;
    }
    
    //Override Save Functionality
    public PageReference SaveRecord() {
        try{
            for (selectOption s : selectResult){
                j.sObjectIds__c += s.getValue()+';';
                if (s.getValue().startswith(Label.BP_Id)){
                    j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.Perfil_Id)){
                    j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';';
                }
                else if (s.getValue().startswith(Label.User_Id)){
                    j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';';
                }
            }
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/'+j.Id);
        pr.setRedirect(true);
        return pr;
    }

}

 

 

I have a selectlist value that should be passed as a parameter to my controller (using Javascript) in order to rerender the search results of a dynamic SOQL query. I have looked through several forum posts on this site as well as external web resources but haven't had any luck so I thought I'd post my code and maybe someone will see what I've missed; thanks so much!

 

VF Page:

 

<apex:page standardController="Janela_de_Acesso__c" extensions="JDABP" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<div align="center">
<apex:messages styleClass="errorMsg"/>
<apex:commandButton action="{!Save}" value="Save"/>
<apex:commandButton action="{!SaveAndNew}" value="Save & New"/>
<apex:commandButton action="{!Cancel}" value="Cancel"/>
</div>
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}" />
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/>
</apex:pageBlockSection>
<!--document.getElementById("pesquisa").options[document.getElementById("pesquisa").selectedIndex].value
<script type="text/javascript">
      function doSearch() {
        searchServer(
          document.getElementById('searchBox').value,
          document.getElementById('pesquisa').options[document.getElementById('pesquisa').selectedIndex].value);
      }
</script>-->
 
<apex:actionFunction name="searchServer" action="{!runSearch}" rerender="Available">
    <apex:param name="searchB" value="" />
    <apex:param name="pesq" value="" />
</apex:actionFunction>

<apex:pageBlockSection title="Membros da Janela de Acesso" columns="1" id="Available_BPs">

<apex:panelGrid columns="2" cellpadding="5px">
<apex:pageBlockSectionItem labelStyle="vertical-align: middle" >
<apex:outputLabel value="Pesquisa:" for="SearchList"/>
<apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(
          document.getElementById('searchBox').value,
          this.options[this.selectedIndex].value);">
<apex:selectOptions value="{!items}" id="pesquisa2"/>
</apex:selectList>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem labelStyle="vertical-align: middle">
<apex:outputLabel value="for:" for="SearchBox"/>
<apex:inputText id="SearchBox" onkeyup="searchServer(
          document.getElementById('searchBox').value,
          document.getElementById('pesquisa').options[document.getElementById('pesquisa').selectedIndex].value);"/>
</apex:pageBlockSectionItem>
</apex:panelGrid>
<apex:panelGrid columns="2">
<apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/>
<apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/>
</apex:panelGrid>
<apex:panelGrid columns="3">
<apex:outputPanel id="Available">
<apex:selectList title="Membros Disponíveis" size="14" id="Available2">
<apex:selectOptions value="{!searchResults}" />
</apex:selectList>
</apex:outputPanel>
<apex:selectList title="Membros Selecionados" size="14" id="Selected"/>
</apex:panelGrid>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>

</apex:page>

 

Controller:

 

public class JDABP {    
    
    // the soql without the order and limit
    private String soql {get;set;}
    // the collection of contacts to display
    public List<sObject> results {get;set;}
    public String searchObject;
    public Janela_de_Acesso__c j;
    public List<SelectOption> searchResult = new List<SelectOption>();
    public String sObjectDesc = 'Business Plans';

    
    //Constructor to apply fields
    public JDABP(ApexPages.StandardController controller) {
        j = (Janela_de_Acesso__c) controller.getRecord();
        j.Name='|';
        j.Status__c='Ativo';
        j.Data_Inicial__c=System.now();
        j.Data_Final__c=System.today()+30;        
        //j.RecordTypeId = Label.Janela_de_Acesso_BP_RecordType;
        searchObject = 'Business_Plan__c';
        soql = 'select Id, Name from ' + searchObject + ' limit 100';
        runQuery();

    }
    
    public List<SelectOption> getItems() {
        List<SelectOption> options = new List<SelectOption>();
            options.add(new SelectOption('Business Plans','Business Plans'));
            options.add(new SelectOption('Perfis','Perfis'));
            options.add(new SelectOption('Usuários','Usuários'));

        return options;
    }     
    
    public List<SelectOption> getSearchResults() {
        return searchResult;
    }
    
    // runs the actual query
  public void runQuery() {    
    try {
      results = Database.query(soql);
      searchResult.clear(); 
      for (sObject r : results){
          If (sObjectDesc=='Business Plans'){
              Business_Plan__c BPr = (Business_Plan__c) r;
              searchResult.add(new SelectOption(BPr.name,BPr.name));
          }
          Else If (sObjectDesc=='Perfis'){
              Profile Pr = (Profile) r;
              searchResult.add(new SelectOption(Pr.Name,Pr.Name));
          }
          Else {
              User Ur = (User) r;
              searchResult.add(new SelectOption(Ur.Name,Ur.Name));
          }         
      }
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, soql+' '+e.getMessage()));
    }
 
  }
 
  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {
 
    String searchText = Apexpages.currentPage().getParameters().get('searchB');
    sObjectDesc = Apexpages.currentPage().getParameters().get('pesq');
    If (sObjectDesc=='Business Plans'){
    searchObject='Business_Plan__c';
    }
    Else If (sObjectDesc=='Perfis'){
    searchObject='Profile';
    }
    Else {
    searchObject='User';
    }
 
    soql = 'select Id, Name from ' + searchObject + ' limit 100';
    if (!searchText.equals(''))
      soql += ' and Name LIKE \''+String.escapeSingleQuotes(searchText)+'%\'';
    
 
    // run the query again
    runQuery();
 
    return null;
  }

        
    //Override Save & New Functionality
    public PageReference SaveAndNew() {
        try{
            insert j;
        } catch (DMLException e) {return null;}
        PageReference pr = new PageReference('/apex/JDABP');
        pr.setRedirect(true);
        return pr;
    }

}

 

Thanks again!

Hello all,

 

So I've been trying to develop a VF page that displays my environment's profiles alongside checkboxes in a pageBlockTable.  If a profile is selected, I would like it to appear below in a second pageBlockTable (I'll be adding other, cooler functionality later but I need to get this working first! :-D )

 

The first table loads correctly but for some reason my second table is not being loaded with values once they are selected; it appears like the page refreshes as it is supposed to, but no values are appended to the second table. I've been looking over the code but I just can't see where I've gone wrong so I thought a fresh set of eyes might help.  Here is my VF page and controller code-thanks very much!

 

P.S. Sorry about having some of the code in a different language! :-P

 

VF Page:

 

<apex:page standardController="Janela_de_Acesso__c" extensions="JDAPerfil" sidebar="false">
<apex:sectionHeader title="Janela de Acesso"/>
<apex:form >
<apex:pageBlock >
<apex:pageBlockSection title="Informações" columns="2">
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Name}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
<apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/>
</apex:pageBlockSection>
<apex:pageBlockSection title="Perfils Disponíveis" columns="1">   
<apex:pageBlockTable value="{!myPerfils}" var="perfil">
<apex:column >
<apex:facet name="header">
<apex:inputCheckbox >
<apex:actionSupport event="onclick" action="{!GetSelected}" onsubmit="checkAll(this)" rerender="Selected_Profiles"/>
</apex:inputCheckbox>
</apex:facet>
<apex:inputCheckbox value="{!perfil.isSelected}" id="checkedone">
<apex:actionSupport event="onclick" action="{!GetSelected}" rerender="Selected_Profiles"/>
</apex:inputCheckbox>
</apex:column>
<apex:column headerValue="{!$ObjectType.Profile.Fields.Name.Label}" value="{!perfil.pro.Name}" />
</apex:pageBlockTable>
</apex:pageBlockSection>
<apex:pageBlockSection Title="Perfils Selecionados" id="Selected_Profiles">
<apex:pageBlockTable value="{!SelectedProfiles}" id="table" var="profile">
<apex:column value="{!profile.Name}" headerValue="{!$ObjectType.Profile.Fields.Name.Label}" />
</apex:pageBlockTable>
</apex:pageBlockSection>        
</apex:pageBlock>
</apex:form>
<script>
function checkAll(cb)
{
    var inputElem = document.getElementsByTagName("input");
    for(var i=0; i<inputElem.length; i++)
    {
        if(inputElem[i].id.indexOf("checkedone")!=-1)
            inputElem[i].checked = cb.checked;
    }
}    
</script>
</apex:page>

 

Controller:

 

public class JDAPerfil {
    
    public class profilewrapper
    {
        public Profile pro{get;set;}
        public Boolean isSelected{get;set;}
        public profilewrapper(Profile a){
            pro = a;   
            isSelected = false;
        }
    }
    
    List<profilewrapper> perfils = new List<profilewrapper>();
    List<Profile> selectedProfiles = new List<Profile>();
    
    public JDAPerfil(ApexPages.StandardController controller) {
    
    }
    
    public List<profilewrapper> getMyPerfils() {
        for (Profile p : [select Id, Name, Description from Profile where Name like '%X%']){
            perfils.add(new profilewrapper(p));
        }    
        return perfils;
    }
    
    public pageReference GetSelected(){
        selectedProfiles.clear();
        for(profilewrapper prowrapper : perfils){
            if(prowrapper.isSelected == true){
                selectedProfiles.add(prowrapper.pro);
            }
        }
        return null;    
    }   
        
    public List<Profile> getSelectedProfiles(){
        if(selectedProfiles.size()>0){
            return selectedProfiles;
        }
        else {
            return null;
        }
    }    

}

 

 

 

 

I have two triggers-the first populates an object based on an XML document; the second kicks off an approval process based upon some of the fields populated by the first. The approval process sends out a VF email template that references some of the fields populated by the first trigger in this fashion - {!Relatedto.field__c} For some reason, these field values are not appearing in the email sent out to the first approver-however; they DO appear in all emails sent to the next approver once the first has given his/her approval.  Could these be because the trigger has not yet fully completed saving the fields when the first email is sent and does so while SF waits for the first-level approver's response? I'm quite confused about this issue so any help you can provide would be much appreciated-below are the two triggers and the VF email template (Note: Some of the code that isn't HTML friendly might be cut-off by the forum); thanks!

 

trigger fillApprovers on Loan_Application__c (before insert, before update) {
    list<Loan_Application__c> theLoanApps = new list<Loan_Application__c>();
    //Append all batched Loan Applications to a Loan App list (Bulkifying the trigger)
    for (Loan_Application__c aLoanApp:trigger.new){
        theLoanApps.add(aLoanApp);
    }
    //Populate the fields in each loan app contained within the list
    for (Integer i=0; i<theLoanApps.size(); i++){
        //Check that the fields are not already populated by ensuring name field is null
        if (theLoanApps[i].Name__c==null){
        //Utilize Dynamic Apex to dynamically create the query that returns the XML document to be parsed
        list<Document> docResult = [SELECT Body FROM Document WHERE Name LIKE :'LoanApp'+theLoanApps[i].ID_Number__c];
        //Convert the body (of type Blob) of the document resulting from the SOQL query to a string
        String xml = docResult[0].Body.toString();
        //Create a Dom.Document from the xml string
        Dom.Document doc = new Dom.Document();
        doc.load(xml);
        //Define root element
        Dom.XMLNode loanApp = doc.getRootElement();
        //Populate list of approvers while simultaneously removing this information from the document
        list<String> approvers = new list<String>();
        while (loanApp.getChildElement('Approver',null) != null) {
            approvers.add(loanApp.getChildElement('Approver',null).getText());
            loanApp.removeChild(loanApp.getChildElement('Approver',null));
        }
        //Repeat the while loop logic above for the other fields using if statements
        if (loanApp.getChildElement('OrderDate',null) != null) {
            String orderDate = loanApp.getChildElement('OrderDate',null).getText();
            theLoanApps[i].Date__c = orderDate;
        }
        if (loanApp.getChildElement('Name',null) != null) {
            String name = loanApp.getChildElement('Name',null).getText();
            theLoanApps[i].Name__c = name;
        }
        if (loanApp.getChildElement('Address',null) != null) {
            String address = loanApp.getChildElement('Address',null).getText();
            theLoanApps[i].Address__c = address;
        }
        if (loanApp.getChildElement('Score',null) != null) {
            String score = loanApp.getChildElement('Score',null).getText();
            theLoanApps[i].Credit_Score__c = score;
        }
        if (loanApp.getChildElement('History',null) != null) {
            String history = loanApp.getChildElement('History',null).getText();
            theLoanApps[i].Credit_History__c = history;
        }
        if (loanApp.getChildElement('Notes',null) != null) {
            String notes = loanApp.getChildElement('Notes',null).getText();
            theLoanApps[i].Notes__c = notes;
        }
        //Iterate through approvers list, updating the corresponding fields of the loan application
        //Depending on the approvers list size, some of the loan app's custom approver fields may be left blank
        if (approvers.size()>=1) {
            theLoanApps[i].Approver1__c=[SELECT Id FROM User WHERE Name = :approvers[0]][0].Id;
            if (approvers.size()>=2) {
                theLoanApps[i].Approver2__c=[SELECT Id FROM User WHERE Name = :approvers[1]][0].Id;
                if (approvers.size()>=3) {
                    theLoanApps[i].Approver3__c=[SELECT Id FROM User WHERE Name = :approvers[2]][0].Id;
                    if (approvers.size()==4) {
                        theLoanApps[i].Approver4__c=[SELECT Id FROM User WHERE Name = :approvers[3]][0].Id;
                    }
                }
            }
        }
        }
    }
}

 

 

 

 

 

 

trigger Approval_Process on Loan_Application__c (after insert, after update) {
    //Bulkify the trigger
    for (Loan_Application__c loanapp : Trigger.new){
    //Check that the loan app is not currently awaiting approval
    if (loanapp.Approval_Status__c!='Submitted for Approval' && loanapp.Approval_Status__c!='Approved'){
    //Override Scenario
    if (loanapp.Name__c=='Johnny Good'){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Single Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id==null && loanapp.Approver3__r.Id==null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Double Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id==null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Triple Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id!=null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Quadruple Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id!=null && loanapp.Approver4__r.Id!=null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    }
    }
}

 

 

 

 

 

 

<messaging:emailTemplate subject="Loan application awaiting your approval" recipientType="User" relatedToType="Loan_Application__c">
<messaging:HtmlEmailBody >
The following loan application has been submitted for your approval:<br/><br/>
Application ID: {!Relatedto.ID_Number__c}<br/>
Application Date: {!Relatedto.Date__c}<br/>
Applicant Name: {!Relatedto.Name__c}<br/>
Applicant Address: {!Relatedto.Address__c}<br/>
Application Credit Score: {!Relatedto.Credit_Score__c}<br/>
Application Credit History: {!Relatedto.Credit_History__c}<br/>
Application Notes: {!Relatedto.Notes__c}<br/><br/>
Please submit your response at your next earliest convenience-thank you.
</messaging:HtmlEmailBody>
</messaging:emailTemplate>

I have two triggers-the first populates an object "loan application" from an XML document stored in my organization.  The second takes some of the values (Specifically Approver1, Approver2, Approver3, and Approver4) and sees if they are null or not.  Based on this, the second trigger knows what approval process must be fired off-additionally, there is a special case in which an alternate protocol is followed should the loan application have "Johnny Good" stored in its name field.  The first trigger works beautifully but the second is not starting any approval processes-I've double-checked to make sure the logic matches the Approval Process entry criteria; any ideas? Thanks!

 

trigger fillApprovers on Loan_Application__c (before insert, before update) {
    list<Loan_Application__c> theLoanApps = new list<Loan_Application__c>();
    //Append all batched Loan Applications to a Loan App list (Bulkifying the trigger)
    for (Loan_Application__c aLoanApp:trigger.new){
        theLoanApps.add(aLoanApp);
    }
    //Populate the fields in each loan app contained within the list
    for (Integer i=0; i<theLoanApps.size(); i++){
        //Utilize Dynamic Apex to dynamically create the query that returns the XML document to be parsed
        list<Document> docResult = [SELECT Body FROM Document WHERE Name LIKE :'LoanApp'+theLoanApps[i].ID_Number__c];
        //Convert the body (of type Blob) of the document resulting from the SOQL query to a string
        String xml = docResult[0].Body.toString();
        //Create a Dom.Document from the xml string
        Dom.Document doc = new Dom.Document();
        doc.load(xml);
        //Define root element
        Dom.XMLNode loanApp = doc.getRootElement();
        //Populate list of approvers while simultaneously removing this information from the document
        list<String> approvers = new list<String>();
        while (loanApp.getChildElement('Approver',null) != null) {
            approvers.add(loanApp.getChildElement('Approver',null).getText());
            loanApp.removeChild(loanApp.getChildElement('Approver',null));
        }
        //Repeat the while loop logic above for the other fields using if statements
        if (loanApp.getChildElement('OrderDate',null) != null) {
            String orderDate = loanApp.getChildElement('OrderDate',null).getText();
            theLoanApps[i].Date__c = orderDate;
        }
        if (loanApp.getChildElement('Name',null) != null) {
            String name = loanApp.getChildElement('Name',null).getText();
            theLoanApps[i].Name__c = name;
        }
        if (loanApp.getChildElement('Address',null) != null) {
            String address = loanApp.getChildElement('Address',null).getText();
            theLoanApps[i].Address__c = address;
        }
        if (loanApp.getChildElement('Score',null) != null) {
            String score = loanApp.getChildElement('Score',null).getText();
            theLoanApps[i].Credit_Score__c = score;
        }
        if (loanApp.getChildElement('History',null) != null) {
            String history = loanApp.getChildElement('History',null).getText();
            theLoanApps[i].Credit_History__c = history;
        }
        if (loanApp.getChildElement('Notes',null) != null) {
            String notes = loanApp.getChildElement('Notes',null).getText();
            theLoanApps[i].Notes__c = notes;
        }
        //Iterate through approvers list, updating the corresponding fields of the loan application
        //Depending on the approvers list size, some of the loan app's custom approver fields may be left blank
        if (approvers.size()>=1) {
            theLoanApps[i].Approver1__c=[SELECT Id FROM User WHERE Name = :approvers[0]][0].Id;
            if (approvers.size()>=2) {
                theLoanApps[i].Approver2__c=[SELECT Id FROM User WHERE Name = :approvers[1]][0].Id;
                if (approvers.size()>=3) {
                    theLoanApps[i].Approver3__c=[SELECT Id FROM User WHERE Name = :approvers[2]][0].Id;
                    if (approvers.size()==4) {
                        theLoanApps[i].Approver4__c=[SELECT Id FROM User WHERE Name = :approvers[3]][0].Id;
                    }
                }
            }
        }
    }
}

 

 

 

 

trigger Approval_Process on Loan_Application__c (after insert, after update) {
    //Bulkify the trigger
    for (Loan_Application__c loanapp : Trigger.new){
    //Override Scenario
    if (loanapp.Name__c=='Johnny Good'){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Single Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id==null && loanapp.Approver3__r.Id==null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Double Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id==null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Triple Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id!=null && loanapp.Approver4__r.Id==null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    //Quadruple Approver
    else if (loanapp.Approver1__r.Id!=null && loanapp.Approver2__r.Id!=null && loanapp.Approver3__r.Id!=null && loanapp.Approver4__r.Id!=null){
        Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();
        req.setObjectId(loanapp.Id);
        //Submit the approval request for processing
        Approval.ProcessResult result = Approval.process(req);
    }
    }
}

 

 

 

Note: I received a warning about non HTML friendly text being removed, both triggers save; but the second does not work at run time (no errors though) so if you notice a typo I think it's b/c the forum removed it....

 

 

 

 

I needed to come up with a way to override the standard "New" button for the Accounts object. The button now redirects the user to an invalid date page by default, but redirects back to the usual New Account page if my Apex class determines that the current month is within a particular range.  After succeeding in my goal I noticed that now if the user is attempting to enter a new account during a valid month and he/she is in fact brought to the New Account page, then the "Cancel" button here is no longer functioning properly.  I believe this has to do with the redirect I created but I am unsure-any help you can provide would be greatly appreciated!  Below you will find my VF Page and my Apex Class:

 

<apex:page standardController="Account" extensions="DateCheck" action="{!pageredir}">
<apex:sectionHeader title="Invalid Date"/>
<apex:outputPanel >
Unfortunately, you cannot create new accounts this month-please try again during a valid month.
</apex:outputPanel>
</apex:page>

 

public class DateCheck {

    public DateCheck(ApexPages.StandardController controller) {

    }

    public Pagereference pageredir(){

        Pagereference newPage = new Pagereference ('/001/e?retURL=/001/');

        Date dateToday = date.Today();

        Integer month = dateToday.month();

        newPage.getParameters().put('nooverride', '1');

        if(new Set<Integer>{1,2,3,10,11,12}.contains(month)) {

            return newPage;

         }

        else

            return null;

    }

}

 

Thanks!

 

 

P.S. On a similar note-I'd like to hide the Quick Create Sidebar menu since this circumvents my Apex code and allows the user to save a new account regardless of date-I know I can turn this off in Setup but does anyone know if there is a way to turn this off conditionally as I did with the "New" button's functionality?  Thanks!

I have been working on a script that automates pulling down my org's data/metadata into a subversion repository nightly.  I have completed the main objective utilizing Ant & the Force.com Migration Tool but have noticed in my tweaking that the package manifest file (package.xml) is not dynamic enough for my purposes.

 

I know from reading the Force.com Migration Tool Guide (http://www.salesforce.com/us/developer/docs/daas/salesforce_migration_guide.pdf)

that certain components cannot utilize the wildcard feature such as dashboards, documents, email templates, letterheads, and reports.  Likewise, I know that there are still several other components that you must first dot-qualify their object name as they are sub-components.

 

My question is as follows: is there a way to possibly create a dynamic package manifest file so that if a user were to create a new document or email template then such a change would be automatically detected during that night's backup and the corresponding change/file would be uploaded to my subversion repository?

 

Again, my initial glance at the Force.com Migration Tool Guide makes me think this is not possible and that a manual edit to the package.xml file would be necessary-but my optimism stems from drawing parallels between my desired task and the current functionality of the Force.com IDE tool.  Upon initially setting up a new Force.com project in the Eclipse IDE you are able to manually select which metadata components you would like included-as noted by JonP this is essentially a GUI for creating your package.xml file.  For existing projects, you have the option of later adding additional components that were either not originally included in your project or were created over the web interface after you set up your Eclipse project (exactly the scenario that affects my desired task) by utilizing the Add/Remove metadata components tool and then clicking the "Refresh from Server" button (depicted by circular arrows).  This refresh from server button proves there is a way to somehow poll your org and discover new metadata components not currently included in your package.xml file and if I could find a way to automate this process via the command line (and then have the differences updated in my existing package.xml) then I could create a dynamic package manifest file as I desire

 

This problem also exists in the inverted scenario where a user deletes certain components via the web interface that should then be replicated in the subversion repository (I must admit though that this issue does not concern me as much as allowing for new components to be brought in does).

Am I correct in thinking that there is no specific platform feature that must be used.  It's just that using more of the platform increases our scoring for this criteria?

I am using an Apex trigger and asynchronous method to perform a callout to the JSON REST API for Wordpress. I continue to receive 500 Internal Server Error responses in my debug log when I edit a Salesforce record, but if I copy/paste the corresponding JSON into the Postman plug-in for Chrome the post is created as expected. Any help is appreciated, thanks!

 

trigger insertPost on Custom_Object__c (after insert, after update) {
    String theIds = '';
    for (Custom_Object__c c : Trigger.new) {
        if (theIds == '')
            theIds = c.Id;
        else
            theIds += '|' + c.Id;
    }
    //Make asynchronous web service callout to insert post
    if (theIds != '')
        WebServiceCallout.sendPost(theIds);
}

 

public class WebServiceCallout {
 
    @future (callout=true)
    public static void sendPost(String theIds) {
 
        HttpRequest req = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        
        if(Test.isRunningTest()){
            Website_Settings__c wpSettings = new Website_Settings__c(Wordpress_URL__c = 'https://testing.com/', Wordpress_Username__c = 'Test', Wordpress_Password__c = 'Test');        
            insert wpSettings;
        }
        
        //Set Headers from Custom Settings & Visualforce
        Website_Settings__c wpSettings = Website_Settings__c.getInstance();
        if (wpSettings.Wordpress_URL__c!=null && wpSettings.Wordpress_Username__c!=null && wpSettings.Wordpress_Password__c!=null){
            
            //Set Endpoint
            String endpoint = wpSettings.Wordpress_URL__c;
            if (endpoint.endsWith('/'))
                req.setEndpoint(endpoint+'wp-json.php/posts/');
            else
                req.setEndpoint(endpoint+'/wp-json.php/posts/');
            
            //Set Method
            req.setMethod('POST');
            
            //Specify the required user name and password to access the endpoint
            String username = wpSettings.Wordpress_Username__c;
            String password = wpSettings.Wordpress_Password__c;
            Blob headerValue = Blob.valueOf(username + ':' + password);
            String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader);
            
            //Specify Content-Type
            req.setHeader('Content-Type', 'application/json');
            
            //Specify Cache-Control
            req.setHeader('Cache-Control', 'no-cache');
            
            //Set Body
            objectToJSON.theId = theIds;
            objectToJSON jsonClass = new objectToJSON();
            req.setBody(jsonClass.jsonData());
            
            try {
                System.debug(req.getHeader('Authorization'));
                System.debug(req.getHeader('Content-Type'));
                System.debug(req.getBody());
                if (!Test.isRunningTest())    
                    res = http.send(req);
            }
            
            catch(System.CalloutException e) {
                System.debug('Callout error: '+ e);
                System.debug(res.toString());
                System.debug(req.getBody());
            }
        
        }
 
    }
 
}

 

public with sharing class objectToJSON {
    //Global variables
    public static String theId;
    public list<String> theIds;
    public list<jsonObjectData> allObjects{get;set;}
    
    public objectToJSON() { 
        //***This method queries the database for information and converts it to JSON***
        //If URL parameters are set then query the database
        if (ApexPages.currentPage()!=null)
            if (ApexPages.currentPage().getParameters().get('theId')!=null && ApexPages.currentPage().getParameters().get('theId')!='')
                theId = String.escapeSingleQuotes(ApexPages.currentPage().getParameters().get('theId'));
        if (theId.contains('|'))
            theIds = theId.split('\\|',-1);
        else{
            theIds = new list<String>();
            theIds.add(theId);
        }
        allObjects = new list<jsonObjectData>();
        list<Custom_Object__c> objects = [SELECT Id, Name, Description__c, A__c, B__c, C__c FROM Custom_Object__c WHERE Id IN :theIds LIMIT 10000];
        for (Custom_Object__c o : objects){
            allObjects.add(new jsonObjectData(o));          
        }
    }
    
    public String jsonData() {
        String jsonData = '[';
        Integer x=0;
        while (allObjects.size()>x) {
            if (x==0)
                jsonData += '{';
            else
                jsonData += ',{';
            jsonObjectData o = allObjects[x];
            jsonData += '\"title\":\"'+o.name.replace('\"','\\"')+'\",';
            jsonData += '\"status\":\"publish\",';
            jsonData += '\"type\":\"custom\",';
            jsonData += '\"content_raw\":\"'+o.content.replace('\"','\\"').replace('\n','')+'\",';
            jsonData += '\"excerpt_raw\":\"'+o.excerpt.replace('\"','\\"').replace('\n','')+'\",';
            jsonData += '\"comment_status\":\"closed\"';
            jsonData += '}';
            x++;
        }
        jsonData += ']';
        if (x==1){
//Remove array formatting for individual post jsonData = jsonData.substring(1); jsonData = jsonData.substring(0,jsonData.length()-1); } return jsonData; } public class jsonObjectData { //*****Wrapper Class***** //Global variables for wrapper class public String name{get;set;} public String content{get;set;} public String excerpt{get;set;} public jsonObjectData(Custom_Object__c o) { //***Constructor method to create a JSON object*** //Define content variables String a = ''; String b = ''; String c = ''; //Set content variables if (o.A__c!=null) a = String.valueOf(o.A__c); if (o.B__c!=null) b = String.valueOf(o.B__c); if (o.C__c!=null) c = String.valueOf(o.C__c); //Define & Set description variable String description = ''; if (o.Description__c!=null) description = String.valueOf(o.Description__c); //Set name name = o.Name; //Set content content = '<div class="custom"></div>\n<div class="row clearfix ">\n<div class="col col_1_2 ">\n<div class="inner">\n<div class="styled_table table_blue">\n<table>\n<thead>\n<tr>\n<th>Custom</th>\n<th> </th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>A</td>\n<td>'+a+'</td>\n</tr>\n<tr>\n<td>B</td>\n<td>'+b+'</td>\n</tr>\n<tr>\n<td>C</td>\n<td>'+c+'</td>\n</tr>\n</tbody>\n</table>\n</div>\n</div>\n</div>\n</div>\n'; //Set excerpt excerpt = '<p>'+description+'</p>\n'; } } }

 

Having some issues getting my Visualforce page to play nicely with PrintFriendly. The iFrame/modal tool pops up as expected, but then when I click the PDF button I am given an error. I believe this may be due to the fact that Salesforce is a password-protected platform.

 

However, I've tried the /secur/frontdoor.jsp workaround using both methods of entry (session id and straight login credentials) but neither seemed to do the trick. I believe the PrintFriendly service may not be willing to wait for the javascript on SF's server to redirect me to my VFpage.

 

Has anyone integrated with PrintFriendly before that could provide some guidance? It would be much appreciated!

 

PS A little background here-I am using the Google Visualization API to generate an interactive chart; thus I cannot use the renderAs attribute as this would just produce a static PDF of the initial landing page. I've pondered creating parameter(s) for all the different possible customizations but this would be very cumbersome as there are many, plus the number of possible customizations will increase over time.

 

Thanks again!

I have completely built a customized site login/registration for my customer portal, but just have one outstanding issue.  When the user clicks forgot password, it emails them a new password.  Once they log back into the portal through the custom login page, it immediately redirects them to:  _ui/system/security/ChangePassword.

 

The problem is that I cannot customize this page.  


I also created a custom ChangePassword page and named it ChangeUserPassword and assigned it to the Login Setting ->  Change Password Page in my site.  But it does not use this page.  It always redirects to _ui/system/security/ChangePassword once the user logs back in.

 

I have also set the only Enabled VF Page to be the ChangeUserPassword page.  

 

Is this _ui/system/security/ChangePassword page not cusomizable?  

Hi all,

I have two topics that I want to subscribe to in my JS, but am having difficulty in doing so.  Any suggestions?

 

Topics:

topic/topic1

topic/topic2

 

How would I add topic2 as an additional subscripiton?

 

$.cometd.subscribe('topic/topic1', function(message) {
    reRender_Tables();
});

 

Hi,

 

I'm trying to create a controller extension for Campaigns and get the following error:


Compile Error: Incompatible types since an instance of SObject is never an instance of Campaign at line 7 column 32 

 

My extension class is the following:

public class CampaignControllerExtension {
    private ApexPages.standardController controller {get;set;}
    private Campaign currentTraining;
    
    public CampaignControllerExtension(ApexPages.StandardController stdController) {
        controller = stdController;
        this.currentTraining = (Campaign)stdController.getRecord();
    }
}

 Apparently there is an exception on Campaigns Sobject but I didn't find any clue on how to correct this.

 Any Ideas?

 

thanks,

Hi Guys,

 

I'm struggling to write an apex test class for my apex trigger. Please Bear in mind that this is the second thing i've ever written in APEX, however i do have other programming knowledge.

 

My Apex Trigger looks something like this:

 

trigger DisputeStatus on Dispute__c (before update) {

	// Get Trigger Object
	Dispute__c dispute = trigger.new[0];
	
	
	if((dispute.Un_Actioned_Conversations__c == 0) && (dispute.Resolved__c == true))
	{
		dispute.Status_of_Problem__c = 'Resolved';
		dispute.Resolved__c = true;
	} else if (dispute.Un_Actioned_Conversations__c > 0)
	{
		dispute.Status_of_Problem__c = 'Waiting for ACTION';
		dispute.Resolved__c = false;
	} else
	{
		dispute.Status_of_Problem__c = 'Waiting for RESPONSE';
		dispute.Resolved__c = false;
	}
}

 

Background information

 

An account object has these custom "Dispute" objects attached

 

A dispute object has custom "Conversation" objects attached

 

dispute.Un_Actioned_Conversations__c // is a roll up summary counting a boolean field in conversation 

 

However i have no idea how to write an APEX test class. I understand that it's essentially a unit test and should test the all the scope of the trigger. I've had a go, using tutorials, and produced the following code:

 

@isTest
private class testDisputeStatus {

    static testMethod void myUnitTest() {
        Dispute__c dispute = new Dispute__c();

		        
        dispute.Un_Actioned_Conversations__c = 0;
        dispute.Resolved__c = false;

		insert dispute;
		
		dispute.Un_Actioned_Conversations__c = 1;
		
		update dispute;
		
		dispute.Resolved__c = true;
		
		update dispute;
		
		dispute.Un_Actioned_Conversations__c = 0;
		
		update dispute;
        
    }}

 However all i've managed to produce is : 

Field is not writeable: Dispute__c.Un_Actioned_Conversations__c

 I appreciate i'm probably doing this completely wrong however being pointed in the right direction would be appreciated.

 

Any ideas?

 

Been beating my head against a wall all day over this-I am using the jquery plug-in fullCalendar within my Salesforce VFPage and have been unable to call Apex variables from within the javascript that constructs the calendar.

 

When I use the typical notation of {!someVariable} then the calendar just flat-out doesn't render. After some searching I came across the strategy to utilize a separate VFpage and controller extension to create a JSON feed that passes the event data.

 

I tried this method, but still nothing-the calendar does render, but no event pops up within it. Even after I hardcoded a bunch of values for testing purposes I still had no luck. Below you will find the VFPage of my calendar page along with the VFPage and controller extension of the JSON feed pages-any help would be GREATLY appreciated, thanks guys.

 

Calendar VFPage: 

 

<apex:page standardController="Event" title="Appointments">
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'cupertino/theme.css')}" />
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.css')}" />
<link rel="stylesheet" type="text/css" href="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.print.css')}" media="print" />
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'jquery/jquery-1.5.2.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'jquery/jquery-ui-1.8.11.custom.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'fullcalendar/fullcalendar.min.js')}"></script>
<script type="text/javascript" src="{!URLFOR($Resource.fullcalendar, 'fullcalendar/gcal.js')}"></script>
<script src="/soap/ajax/23.0/connection.js" type="text/javascript"></script> 
<script src="/soap/ajax/23.0/apex.js" type="text/javascript"></script>
<script type="text/javascript">         
    $(document).ready( function(){
  
        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();        
        
        var calendar = $('#calendar').fullCalendar({
            theme: true,
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            defaultView: 'agendaWeek',
            selectable: true,
            selectHelper: true,
            allDaySlot: true,
            aspectRatio: 1.75,
            minTime: 7,
            maxTime: 20,
            //weekMode: 'variable',
            editable: false,
            eventClick: function(event) {
                // opens events in a popup window
                window.open(event.url, 'gcalevent', 'width=700,height=600');
                return false;
            },  
            eventSources: [
                    {
                    // U.S. holidays
                    url: 'https://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic',
                    color: '#6B6B6B'
                    }
                ],  
            events: '/apex/queryToJSON?evId=a58U0000008MhIzIBL'
        });
    });
</script>
<apex:form >

<apex:pageBlock >
<div id="calendar" style="width: 820px; float: left;"></div>
<br style="clear: both;" />
<br />
<apex:commandButton action="{!Save}" value="Done" />
<apex:commandButton action="{!Cancel}" value="Cancel" />
<br />
<br />
</apex:pageBlock>
</apex:outputPanel>
</apex:form>
</apex:page>

 

JSON Feed VFPage: 

 

<apex:page controller="queryToJSON" 
contentType="application/x-JavaScript; charset=utf-8" showHeader="false" standardStylesheets="false" sidebar="false">[<apex:repeat value="{!allEvents}" var="ev" >{
"title":{!ev.name},
"start": {!ev.start},
"end": {!ev.stop},
"allDay": false,
"color": "#36C",
"url":{!ev.url}
}
</apex:repeat>]
</apex:page>

 

JSON Feed Controller:

 

public class queryToJSON {

        public custEvent__c thisEvent;
        public fullCalendarEvent allEvents{get;set;}

         public queryToJSON() { 
        if (ApexPages.currentPage().getParameters().get('evId')!=null){
                String evId = ApexPages.currentPage().getParameters().get('evId');
                thisEvent = [SELECT Id, Customer_Name__r.Name from custEvent__c where Id = :evId LIMIT 1];
                allEvents = new fullCalendarEvent(thisEvent);
        }
                
     }
     
     public class fullCalendarEvent {
        
        public String name{get;set;}
        public String url{get;set;}
        public String start{get;set;}
        public String stop{get;set;}
        
        public fullCalendarEvent(custEvent__c thisEvent) {
                name = JSON.serialize(thisEvent.Customer_Name__r.Name);
                url = JSON.serialize('/'+thisEvent.Id);
                start = JSON.serialize(datetime.now());
                stop = JSON.serialize(datetime.now().addDays(2));
        }
        
     }
    
}

 

So I have an inputText component on my Visualforce page that dynamically edits my SOQL query for every onkeyup and also rerenders a table whose values are based upon the SOQL query. My issue is best explained with an example:

 

If a user wanted to search for "Salesforce" he/she would obviously type out S, then a, then l, etc. Since the SOQL query is edited with each keyup the table below continually rerenders as the user types. In certain scenarios such as this one, this can be a major problem.

 

Assume that a search term for Salesforce would return no records, leaving the table empty. However, a search of Sales would return many records, say 350.

 

Once the user finishes typing the second 's' the "Sales" query begins accumulating several records, but the user is simultaneously typing new letters-f, o, r, etc. Each of these remaining letters lead to SOQL queries that return 0 results (Salesf gives 0 results, Salesfo gives 0 results, etc.) and thus are completed quickly. The final result is that even though the ultimate search term "Salesforce" should return 0 records, the table is actually populating with the results of the search term "Sales" because, given the high number of pulls from the database, this SOQL query actually completed after the other SOQL queries finished.

 

I have found solutions for a similar issue with AJAX such as the one here. The problem is that these all require utilizing Javascript and the setTimeout function to cause the server to pause before searching the database (the assumption here is that this allows the user to finish typing his/her ultimate search term). Unfortunately, Salesforce seems to ignore the setTimeout javascript function as any sort of sleep/wait method could potentially throw off their multi-tenant architecture.

 

Does anyone have any good ideas I could utilize to overcome this issue that don't involve some sort of a sleeper method? Note: I have already noted that if I add a limit to my SOQL query this issue can be resolved, but unfortunately my client demands there be no limit size to the search results...

I have been beating my head against the wall trying to get a dynamic reRender to work on my visualforce page. Essentially my VFPage embeds via iFrames a separate VFpage that displays a table. I want the user to be able to select from a picklist the number of tables he/she wishes to be displayed (1-5). Upon changing the # of tables the VFpage should be refreshed to display the corresponding number of iFrames. This is all working properly so far.

 

Here is my issue-the VFpage embedded via iFrames contains dynamic content as well and I would like this information to be preserved should another table be added to the page; thus, I want the onchange event on my table # picklist to cause a dynamic reRender that will only do a partial page refresh of the iFrames formerly not displayed while leaving the visible iFrames untouched. Hopefully this makes sense but I will post my VFPage and Controller extension as well for you to look at; thanks so much!

 

VFPage:

 

<apex:page standardController="Quantitativo__c" extensions="MultQuantAnal">
<div align="center">
<h1 style="font-size:16pt"><apex:outputText value="Quantitative Analysis"></apex:outputText></h1>
</div>
<apex:form >
<div align="center">
<br/>
<apex:outputText >Tabels:&nbsp;</apex:outputText>
<apex:selectList id="chooseTables" value="{!numTables}" size="1">
          <apex:selectOption itemValue="1" itemLabel="1"/>
          <apex:selectOption itemValue="2" itemLabel="2"/>
          <apex:selectOption itemValue="3" itemLabel="3"/>
          <apex:selectOption itemValue="4" itemLabel="4"/>
          <apex:selectOption itemValue="5" itemLabel="5"/>
<apex:actionSupport event="onchange" reRender="{!PanelRef}"/>
</apex:selectList>
</div>
<br/>
<apex:outputPanel id="one">
<apex:iframe height="250" rendered="{!numTables>=1}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="two">
<apex:iframe height="250" rendered="{!numTables>=2}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="three">
<apex:iframe height="250" rendered="{!numTables>=3}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="four">
<apex:iframe height="250" rendered="{!numTables>=4}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
<apex:outputPanel id="five">
<apex:iframe height="250" rendered="{!numTables==5}" frameborder="false" src="/apex/QuantAnal"/>
</apex:outputPanel>
</apex:form>
</apex:page>

 

Controller Extension:

 

public class MultQuantAnal {

    public Integer numTables{get;set;}
    
    public void setnumTables(String numVar) {
        this.numTables = Integer.valueOf(numVar);
    }

    public MultQuantAnal(ApexPages.StandardController controller) {
        this.numTables=1;
    }

    public String getPanelRef(){
        if (numTables==1){
            return 'one,two,three,four,five';
        }
        else if (numTables==2){
            return 'two,three,four,five';
        }
        else if (numTables==3){
            return 'three,four,five';
        }
        else if (numTables==4){
            return 'four,five';
        }
        else {
            return 'five';
        }
    }
}

 

Hi, 

 

I'm wondering if anyone else has run into this issue. We have a managed package that includes a global component that users can use in their own visualforce pages.  The component has a public controller and it used to work in spring 11. Since the summer 11 upgrade we get a controller not visible error when we try to execute actions on the page. I've setup a really simple example to demonstrate the problem. 

 

Install this package:

https://login.salesforce.com/packaging/installPackage.apexp?p0=04tA0000000Rv4x

 

 

Or you can create your own. The key is, it has to be a managed package with a namespace.

 

In the package there's a class SimpleCalss:

 

public class SimpleClass{

    public PageReference blankAction(){
        return null; 
    }
}

And a simple component that uses the class: 

<apex:component controller="SimpleClass" access="global">

    test
    <apex:form >
        <apex:commandButton action="{!blankAction}" value="NOOP" />
    </apex:form>

</apex:component>

 If you create a page in the organization that you installed the manage package in that uses the component like this:

 

<apex:page showHeader="false" sidebar="false">
        <body>
            <mpackage:SimpleComponent />
        </body>
</apex:page>

 

Then view the page and execute the blank action on the page you'll get an mpackage.SimpleClass not visible error.  

 

I have a case open with support (05605800) that went to R&D and they've told me this was also the case in spring 11. I can't prove that it wasn't since I no longer have access to a spring 11 organization but I know for certain that this worked in Spring. 

 

Just wanted to see if anyone else had noticed this behavior

 

Thanks!

Scott

 

From the Case object, we have a custom button that creates an RMA with case and account information filled in and then opens the new RMA record. It works fine in the normal salesforce.com.

 

In the Service Cloud Console, we have Accounts, Cases, and RMA's. If we create new Cases or new RMA's from the Account, the new records get create in new subtabs to the account.

 

But if we launch our CaseToRMA page from the case in a Service Cloud Console subtab, it results in a whole new instance of saleforce.com running in the original case tab. What we want is for the new RMA to open in a new subtab under the account and to leave the case open.

 

CasetoRMA class

 

public class CaseToRMA {
    public Case c {get; set;}
    public RMA__c rma {get; set;}
public CaseToRMA () { c = [ select c.Id, c.CaseNumber, c.Account.ShippingCountry, c.Account.ShippingPostalCode, c.Account.ShippingState, c.Account.ShippingCity, c.Account.ShippingStreet, c.Account.Name, c.AccountId from Case c where id = : apexPages.currentPage().getParameters().get('id')];
List<Settings__c> cs = [ select RMA_Warehouse__c from Settings__c]; RMA__c rma = new RMA__c( ZipPostalCode__c = c.Account.ShippingPostalCode, Warehouse__c = (cs.size() > 0) ? cs[0].RMA_Warehouse__c : null, Street__c = c.Account.ShippingStreet, StreetTextArea__c = c.Account.ShippingStreet, RMADate__c = system.today(), Country__c = c.Account.ShippingCountry, City__c = c.Account.ShippingCity, Case__c = c.Id, Account__c = c.AccountId, AccountName__c = c.Account.Name, Reference__c = c.CaseNumber); }

public PageReference NewRMA() {
insert rma;
return new PageReference('/' + rma.id);
}

 

 

 

 VisualForce Page

<!-- Old way -->
<apex:page controller="CaseToRMA" action="{!newRMA}" >
<!-- Attempt at opening in a new tab
<apex:page controller="CaseToRMA" action="{!newRMA}" >
    <apex:includeScript value="/support/console/20.0/integration.js"/>
    <script type="text/javascript">
        function init() {
                //First find the ID of the primary tab to put the new subtab in
            sforce.console.getEnclosingPrimaryTabId(openSubtab);
        }
        var openSubtab = function openSubtab(result) {
                //Now that we've got the primary tab ID, we can open a new subtab in it
            var primaryTabId = result.id;
            sforce.console.openSubtab(primaryTabId , '/' + rma.id, false,
                rma.Name, null, null);
        };
    </script>
    <body onLoad="Init()"/>
-->
</apex:page>

 If someone has a working example of this, it would be great.

 

 

Is it possible to customize the /_ui/system/security/ChangePassword page (fonts/colors/remove headers)?

 

Is it possible to place the change password fields into a custom VisualForce page.

 

I think I can create my own visual force page/custom controller and use the setPassword() function, but if there is an easier way I'd like to use it.

  • February 25, 2010
  • Like
  • 0