• IanM1963
  • NEWBIE
  • 50 Points
  • Member since 2011

  • Chatter
    Feed
  • 2
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 12
    Questions
  • 12
    Replies

Hi,

 

I can find plenty of places where static resources are used to house images for VisualForce pages which are then rendered as pdf no problem. However, has anyone tried using a URL field in a custom object when that URL points to an Amazon S3 storage?

 

This is my VF page at the top...

 

<apex:page standardStylesheets="false"   standardController="pb__InventoryItem__c" renderAs="pdf" >

<apex:variable var="inv" value="{!pb__InventoryItem__c}"/> 

 

You can see I'm creating a variable so I can access various fields from my custom object...

 

Just one of the image tags here...

 

<apex:image url="{!inv.pb__Image1__c}" width="100%" height="425px" />

 When I let it render as HTML all images appear no problem. The URL that is returned is ok and everything works until I renderAs PDF and the images break. Is there any way around this? I can't see creating static resources for every image as being a solution. Especially as there is everything in the S3 storage area. All I need to do is to be able to render out to PDF!

 

Also, does anyone know if it's easy enough to render a Google map out to PDF from a VF page?

 

Thanks in advance. I'd really appreciate any help as this is quite an urgent job. Very frustrating when you have got the page working apart from rendering to PDF.

 

Regards,

Ian

 

Hi,

 

I've been searching around and it seems that Apex/SFDC isn't able to transmit files via FTP.

 

Is this still the case? Is there no way that I could set up a schedule job in SalesForce to create a csv file of data from a custom object for example then transmit said data to another server via FTP?

 

It looks like there are 3rd party applications that can do this but I've been asked if I can come up with a solution.. I'm quite new to Apex (about a year) and this is the first requirement I've had for this feature.

 

I'd be grateful for any pointers/assistance you could give me.

 

Thanks and regards,

 

Ian

Hi, I know this will have been posted before but I have quite a complicated issue here (for me cos I'm new to Force dev) that I'd like to share with you guys to see if there is anything I am missing.

 

I have a requirement for a bulk upload of records from another system that will be uploaded using the DataLoader from a csv file. No problem so far, have that covered and working.

 

The problem is that there may or may not be lookup field values in the file rows that can be used to form relationships within the SalesForce system and if so they need hooking up on import.

 

So this means that somehow, for every line of the import record I need to look at an Account record to see if certain values match. If not I then need to link the import record to know values for dummy Account objects marked as "UNKNOWN".

 

The spec is they want a trigger to do this and I have come up with three possible solutions, all of which run into Governor Limits pretty quickly. I cannot find a way of having any more than 99 records in the import file at a time?

 

OK so here is my code for each solution. I'd like you to cast your eyes on the code and see if there is anything simple that I have missed that would allow me to do this without running into the Governor Limits.

 

Here's the code...

 

First idea I had was to use a MAP so I would get a list of Accounts in one hit. From there I'd go for a match on Account Id. Unfortunately I have only one AccountId in the file(possibly). The other numbers are from a legacy system so I can only match on those which means using SOQL?

 

trigger customUpload on Custom__c (before insert, before update) 
{
	

// Map for THE MAP WAY //

Map<Id,Account> accountMap = new Map<Id, Account>([select Id,  Customer_Number__c from Account]);




	
	for (Custom__c customObj : trigger.new)
	{
				
		
		/*###################################################################################################################################################################################*/
		/*																																																																																										*/
		/*THE MAP WAY - it only solves on problem partially in that we can easily look for a match on Id in the MAP. However, we can only have a MAP of the form <Id,SOBject> in other 
		/* words, we can only use an actual Id to search on Account key field. We only have a key field for one attribute which is Lookup1__c or Lookup1 in the import file. Another issue is that this works
		/* by relying on catching exceptions which are thrown when no match shown. Don't like doing that but still works.
		/
		/* SOLUTION if using this method would be to ensure that instead of Lookup2 and Lookup3 in the import file we actually have SalesForce Ids as Lookups that we can use to get matches from the 
		/* map using those Account Numbers for Lookup1 and 2 e.g. instead of Lookup2__c matching on Account.Customer_Number__c we match on Lookup__c (an Account number due to it being a lookup). I do not know if this is possible though...
		/*   
		/* AT 100 ROWS ON INPUT FILE THIS FAILS WITH TOO MANY SOQL QUERIES                                                                                                                   */
		/*###################################################################################################################################################################################*/
		
		
		try
		{
			Account Lookup1Match = accountMap.get(customObj.Lookup1__c);
			
		}
		catch (Exception e)
		{
			Lookup1Unknown();
		}
		
		
		// Cannot use this technique for the the other two because these are not SalesForce Ids and we can only build a map with an Id and an SObject to enable searches like this as far as I am aware.
		// Thus we have to resort to using SOQL queries...
		
		// Get the Account with the matching Lookup2__c to Account.Lookup2__c
		List<Account> Lookup2Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup2__c];
			if (Lookup2Match.size() == 0)
			{
				Lookup2Unknown();
			}
		// Get the Account with the matching Lookup3_RID to the Account.Lookup3__c
		List<Account> Lookup3Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup3__c];
			if (Lookup3Match.size() == 0)
			{
				Lookup3Unknown();
			}	
	
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}	
	
	
	
}

 So I thought I'd try the SOQL way.... Just look for a match using SOQL for every line in the import file...

 

trigger testingUpload on Custom__c (before insert, before update) 
{
	






	
	for (Custom__c customObj : trigger.new)
	{
		// Get the Account with the matching Lookup1 to Account Id...
		
		
		/*###################################################################################################################################################################################*/
		/*THE SOQL WAY - runs into SOQL limits very quickly due to invoking the 3 queries for every line in file to insert */
		/* 
		/* FOR 100 LINES IN THE INPUT FILE THIS FAILS BY GOING OVER THE 100 LIMIT ON SOQL QUERIES.                                                                                */
		/*###################################################################################################################################################################################*/
	
		
		
		


		// Get the Account with the matching Lookup1__c to Id on Account...
		List<Account> Lookup1Match = [Select Id from Account where Id = :customObj.Lookup1__c];
			if (Lookup1Match.size() == 0)
			{
				Lookup1Unknown();
			}
		
		// Get the Account with the matching Lookup2__c to Account.Lookup2__c
		List<Account> Lookup2Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup2__c];
			if (Lookup2Match.size() == 0)
			{
				Lookup2Unknown();
			}
		// Get the Account with the matching Lookup3_RID to the Account.Lookup3__c
		List<Account> Lookup3Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup3__c];
			if (Lookup3Match.size() == 0)
			{
				Lookup3Unknown();
			}
		
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}
	
	
	
	
}

 As you can see, it runs into the 100 query limit pretty quick...

 

So then I thought I'd try the CODE way. Basically get an Account list in one hit using SOQL then loop through the list for every line in the input file. Yes I know, very innefficient! :-\

 

trigger testingUpload on Custom__c (before insert, before update) 
{
	

List<Account> accountList = new List<Account>([select Id,  Customer_Number__c from Account]);




	
	for (Custom__c customObj : trigger.new)
	{
		// Get the Account with the matching Lookup1 to Account Id...
		
		
		/*###################################################################################################################################################################################*/
		/*THE CODE WAY - runs into scripting lines over 200,0000 */
		/*###################################################################################################################################################################################*/
	
		
		for (Account acct : accountList) 
			{
				
				
				if (customObj.Lookup1__c == acct.Lookup1__c)
				{
					
					customObj.Lookup1__c = acct.Id;				
				}
				else 				
				{
					
					lesseeUnknown();
				}
				
				
				if (customObj.Lookup2__c == acct.Lookup2__c)
				{

					customObj.Lookup2__c = acct.Id;				
				}
				else
				{
					
					shipperUnknown();
				}
				
				
				
				if (customObj.Lookup3__c == acct.Lookup3__c)
				{
					
					customObj.Lookup3__c = acct.Id;
				}
				else
				{
					Lookup3Unknown();
				}
			}
		
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}
	
	
	
	
}

 I would be very grateful if someone could point me in the right direction with this one. It seems I can get code that works but not for many input file lines... The requirement is to eventually automate this process you see so the uploads are done unattended.

 

My thoughts are that it's asking a trigger to do a lot of work BUT this is what the client specified. I value your thoughts on this.

 

Thanks and regards,

 

Ian

Hi,

 

I have a query in SOQL that returns a number of nested result sets (relationship query). When the number of rows gets beyond 25 the page loading gets very very slow. So I decided to try and age the results, say 20 at a time. I did a bit of reading and Googling and noticed that you can use ApexPages.StandardSetController and Database.QueryLocator to page results which looks perfect for what I want.

 

However, I have been unable to make much sense of it thus far for the reasons below...

 

  1. The query will not take bind variables - it just replies with MALFORMED_QUERY: Colleague_Availability__r where Date__c >= :weekstarting and Date__c < :weekending) ^ ERROR at Row:1:Column:164 unexpected token: ':'
  2. When I temporarily hard code the dates in, the paging will simply not work! I have tried rerender and everything but the viewState is not loaded with any fresh data whenever the command link for "next" is pressed.

Here is my code...

 

public ApexPages.StandardSetController con {
        get {
        string qry = 'Select Id, Name,Worker_First_Name__c, UK_Mobile_Number__c, (Select Id, Name, Availability__c, Date__c, Confirmed__c from Colleague_Availability__r where Date__c >= :weekstarting and Date__c < :weekending) from  Colleague__c where Id in (select Colleague__c from Junction__c where Site__c =: siteId and Status__c = \'Active\' and Home__c = \'Home\') and isdeleted = false order by Name asc';
            if (con == null) {
                con = new ApexPages.StandardSetController(Database.getQueryLocator(qry));
                con.setPageSize(5);
            }
            return con;
        }
        set;
    }

 And the VF Code here...

 

<apex:pageBlock mode="edit" id="theBlock" rendered="{!RenderPage}" >
        <apex:pageBlockButtons id="btns">
            <apex:commandButton onclick="return goPrev();" value="<< Prev" id="prev"   />
            <apex:commandButton onclick="return goNext();" value="Next >>" id="next"   />
             <apex:commandLink immediate="true" rerender="theBlock" action="{!previous}" rendered="{!hasPrevious}" >Previous</apex:commandlink>
            <apex:commandLink immediate="true" rerender="theBlock" action="{!next}" rendered="{!hasNext}" >Next</apex:commandlink>
        </apex:pageBlockButtons>

 

This is getting rather urgent that I arrive at a solution. Do you think I'd be better trying to get it to page the data with my own code? If so how would I do my own pager?

 

Is there any other way of speeding up loading of data in this VF page? It takes over 5 seconds to load with 60 records, sometime longer.

 

As far as I know I have used all the tricks in the book to make it load faster. The query itself is fast, just seems that the page is very very slow at loading nested data?

 

Thanks in advance for any help/advice you can give me.

 

Ian

 

Hi,

 

Can anyone help me with this simple query?

 

When I hard code the WhatId it works perfectly - here's the code...

 

Account acc =  [Select Id, PersonContactId, IsPersonAccount, Primary_Service__r.Name, Primary_Service__r.Id, Source_of_Data__c, Reason_for_Contact__c, People_Status__c, PersonMailingStreet, PersonMailingCity, PersonMailingState , PersonMailingPostalCode, PersonMailingCountry, PersonMobilePhone, PersonHomePhone, Gender__c, Age__c, DOB_Estimated__c, Marital_Status__c, Commitment_Type__c, Commitment_Date__c From Account where Id =  limit 1];

 However, I want it to be (unsurprisingly) dynamic. I thought something like this should work:

 

for(Task task : trigger.new){
		
		


		//Id wId = task.WhatId;
		Account acc =  [Select Id, PersonContactId, IsPersonAccount, Primary_Service__r.Name, Primary_Service__r.Id, Source_of_Data__c, Reason_for_Contact__c, People_Status__c, PersonMailingStreet, PersonMailingCity, PersonMailingState , PersonMailingPostalCode, PersonMailingCountry, PersonMobilePhone, PersonHomePhone, Gender__c, Age__c, DOB_Estimated__c, Marital_Status__c, Commitment_Type__c, Commitment_Date__c From Account where Id = task.WhatId  limit 1];


		task.Primary_Service__c = acc.Primary_Service__r.Name;
			task.Primary_Service_ID__c = acc.Primary_Service__r.Id;
			task.Source_of_Data__c = acc.Source_of_Data__c;
			task.Reason_for_Contact__c = acc.Reason_for_Contact__c;
			task.People_Status__c = acc.People_Status__c;
			task.Street__c = acc.PersonMailingStreet;
			task.City__c = acc.PersonMailingCity;
			task.State__c  = acc.PersonMailingState;
			task.PostCode__c = acc.PersonMailingPostalCode;
			task.Country__c = acc.PersonMailingCountry;
			task.Mobile__c = acc.PersonMobilePhone;
			task.Home_Phone__c = acc.PersonHomePhone;
			task.Gender__c = acc.Gender__c;
			task.Age__c = acc.Age__c;
			task.DOB_Estimated__c = acc.DOB_Estimated__c;
			task.Marital_Status__c = acc.Marital_Status__c;
			task.Commitment_Type__c = acc.Commitment_Type__c;
			task.Commitment_Date__c = acc.Commitment_Date__c;

	}

 Sorry, I left the hardcoded Id out of the first example but I'm sure you get the idea.

 

Why does a hard coded Id work and a bind variable not work?

 

Thanks in anticipation.

 

Ian

Hi,

I'm having fun with this problem at the moment. I'm running Unit Tests and this doesn't seem to make sense because the initial error: System.Query.Exception: List has no rows for assignment to SObject

I thought I had remedied by enclosing the code in a try{}Catch{} block. However, I re-run the test and it still comes up with the same problem!

Here's my code:


Method in code…

 

public void dropInPool()
    {
    
           
        Id shiftId = ApexPages.CurrentPage().getParameters().get('shiftId');
        Id siteId = ApexPages.CurrentPage().GetParameters().get('siteId');
	
		
		
		try
		{
			targetShift = [select Id, Site_Plan__c,Colleague_Availability__c, Site_Plan__r.Account__c, Site_Plan__r.Account__r.Name, Colleague_Availability__r.Colleague__c, Colleague_Availability__r.Colleague__r.Name, Colleague_Availability__r.Colleague__r.Worker_First_Name__c, Colleague_Availability__r.Colleague__r.UK_Mobile_Number__c, Colleague_Availability__r.Availability__c, Shift_Start_Time__c, Account__c from Colleague_Shift__c where Site_Plan__r.Account__c  = :siteId and Id = :shiftId];
		
		
		
		        if (targetShift.Colleague_Availability__c != null)
		        {
		            try
		            {
		             
		                 oldAvailability = [select OldValue from Colleague_Availability__History 
		                                         where Field = 'Availability__c' 
		                                         and ParentId = :targetShift.Colleague_Availability__c order by CreatedDate desc limit 1];
		                                         
		                 tempAvailability = [select Availability__c, Confirmed__c from Colleague_Availability__c where Id = :targetShift.Colleague_Availability__c and Date__c = :convDate];
		                 tempAvailability.Availability__c = (String) oldAvailability.OldValue;
		                 tempAvailability.Confirmed__c = false;
		              }
		              catch (Exception e)
		              {
		                  oldAvailability = null;
		                  tempAvailability = [select Availability__c, Confirmed__c from Colleague_Availability__c where Id = :targetShift.Colleague_Availability__c and Date__c = :convDate];
		                  tempAvailability.Availability__c = 'NONE';
		                  tempAvailability.Confirmed__c = false;  
		              }
		            update tempAvailability;
		            targetShift.Colleague_Availability__c = null;
		            update targetShift;
		        }
		        	dailyShifts = null;
		        }
		catch (Exception e)
		{
			ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Cannot find Id! The Shift Id or Site Id has been lost somehow. Cannot move this Colleague, please try again.'));
		}
    }

And here's the testmethod...

 

private static testmethod void dropInPoolTest()
    {
	Test.setCurrentPage(new PageReference('/apex/shiftPlanningWithColleagueCreate'));
      
     	ShiftControllerWithColleagueCreate myController = new ShiftControllerWithColleagueCreate();
 
       Date testDate = Date.today();
       String sDate = String.valueOf(testDate);
       
       // Create a Site.
       
       Account myTestAccount = new Account();
       myTestAccount.Name = 'The test Account';
       insert myTestAccount;

       // Create a Site Plan.
       
       Site_Plan__c mySitePlan = new Site_Plan__c();
       mySitePlan.Account__c = myTestAccount.Id;
       mySitePlan.PlanDate__c = testDate;
       insert mySitePlan;
       
       // Create a Colleague.
       
       Colleague__c testColleague = new Colleague__c(Name = 'Test Colleague');
        insert testColleague;
  
        Junction__c myTestJunction = new Junction__c(Site__c=myTestAccount.Id, Colleague__c=testColleague.Id, Home__c='Home');
        insert myTestJunction;
       

            // Now create a week's availability for the Colleague
            List<Colleague_Availability__c> myAvList = new List<Colleague_Availability__c>();
            
            
            for (Integer i = 0; i <=7; i++)
            {
                myAvList.add(new Colleague_Availability__c(Name='testAvailability' + i, Availability__c = '09:00', Colleague__c = testColleague.Id, Date__c = testDate));
            }
            
            insert myAvList;
            Colleague_Shift__c testShiftWeAreBookedOn = new Colleague_Shift__c(Shift_Start_Time__c = '08:00', StartTime__c = testDate, Site_Plan__c = mySitePlan.Id, Colleague_Availability__c = myAvList[0].Id);
            insert testShiftWeAreBookedOn;

            // Now set the parameters for the method...

            ApexPages.CurrentPage().getParameters().put('shiftId', testShiftWeAreBookedOn.Id);
            ApexPages.CurrentPage().getParameters().put('siteId', null);
      
            // Now test the method...
            
            myController.dropInPool();
            
            System.AssertEquals(null,myController.targetShift.Colleague_Availability__c);
            System.AssertEquals(false, myController.tempAvailability.Confirmed__c);
 
    }

  I would massively appreciate it if anyone can see something that's causing this - I just can't see what the issue is. I thought the try - catch would have sorted it!


Hi,

 

Does anyone know how to do this? I thought it would be quite straightforward. I set up two datatables and two different queries in my controller but one (the second column) just doesn't show anything.

Is there a standard approach to displaying two lists of objects in two columns in VisualForce?

 

I can post code later but not sure how much it would help because I've described what I've done.

 

Regards,

 

Ian

Hi,

 

I have a page with a drop down where users can select an ID basically that is passed as a parameter back to the controller.

 

Now it all works fine and displays records as it should when the user selects a valid entry. However, when the user selects "none"

 

then the query runs and returns no rows and flashes no rows on the screen. Then it runs AGAIN with the PREVIOUS selection and gets some results!

 

How is this possible??

 

Basically it looks like the query is always runnning twice and picking up the last successful value. So even if I change things like to cycle through weeks of records, it does it then reverts back to the one before...

 

 

<p>Working on forward and back buttons to allow cycling through successive weeks...</p>
<br />
<br /><br />
<table id="t1"><tr><td><h2 class="left">Week Commencing:</h2> <apex:inputField value="{!proxyObject.closeDate}" id="theStartDate" styleClass="left"    /> </td>
                   <td><h2 class="left">Site: </h2><apex:selectList id="theSite"  size="1"   styleclass="left">
                        <apex:selectOptions value="{!ClientSites}"></apex:selectOptions>
                        

                    </apex:selectList>
                    </td>
</tr>
<apex:actionStatus startText="Retrieving records..." id="status"   startStyle="color:red;font-size:20px;"  />
<apex:pageMessages id="errors" />
</table>
<apex:pageBlock mode="edit" id="theBlock">
<apex:pageBlockButtons >
<apex:commandButton value="<< Prev" id="prev" rerender="theBlock,errors" />
<apex:commandButton value="Go" id="theGo" onclick="goToSite();" rerender="theBlock,errors"/>
<apex:commandButton onclick="goNext();" value="Next >>" id="next" rerender="theBlock,errors" />

</apex:pageBlockButtons>

<apex:outputPanel rendered="{!IF(siteId == null, false, true)}" >
    <apex:pageBlockTable value="{!calendars}" var="aColleague" id="theTable"  >
        <apex:column styleClass="cyan" >
                        <apex:facet name="header">
                <b>SiteId</b>
            </apex:facet>
           {!aColleague.Colleague__r.Account__c}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>ColleagueId</b>
            </apex:facet>
            {!aColleague.Colleague__r.Id}
        </apex:column>
        <apex:column styleClass="cyan" >
                        <apex:facet name="header">
                <b>Last Name</b>
            </apex:facet>
           {!aColleague.Colleague__r.Name}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>First Name</b>
            </apex:facet>
            {!aColleague.Colleague__r.Worker_First_Name__c}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>Mobile No.</b>
            </apex:facet>
            {!aColleague.Colleague__r.UK_Mobile_Number__c}
            
        </apex:column>
        <apex:column styleClass="grey">
        <apex:facet name="header">
            <b>Status</b>
        </apex:facet>
        
        <apex:inputField styleClass="{!aColleague.Status__c}" value="{!aColleague.Status__c}" onchange="changeClass(this);" />
            
        </apex:column>
        <apex:column rendered="false" >
            <apex:facet name="header">
                <b>Wk. Comm</b>
            </apex:facet>
            <apex:outputText value="{0,date,dd'/'MM'/'yyyy}">
            <apex:param value="{!aColleague.Wk_Com__c}" /> 
            </apex:outputText>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Sun</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Sunday__c}" value="{!aColleague.Sunday__c}" onchange="changeClass(this);" />
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Mon</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Monday__c}" value="{!aColleague.Monday__c}" onchange="changeClass(this);" />
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Tue</b>
            </apex:facet>
                <apex:inputField styleClass="{!aColleague.Tuesday__c}" value="{!aColleague.Tuesday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Wed</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Wednesday__c}" value="{!aColleague.Wednesday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Thu</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Thursday__c}" value="{!aColleague.Thursday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Fri</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Friday__c}" value="{!aColleague.Friday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Sat</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Saturday__c}" value="{!aColleague.Saturday__c}" onchange="changeClass(this);"/>
        </apex:column>

    </apex:pageBlockTable>
 </apex:outputPanel>   
            
              <apex:pageBlock title="Debug" id="debug" rendered="false">
      <apex:outputText value="{!debugSoql}" />           
  </apex:pageBlock>
       </apex:pageBlock>
   
   <script type="text/javascript">
    jQuery.noConflict();
    function doSave(sel,etc) {
    myFunc(sel.value,etc.value);
     
}
</script>

<script type="text/javascript">
    
jQuery.noConflict();
    function changeClass(myElement)
        {      
                 jQuery(myElement).removeAttr('class');
                 jQuery(myElement).addClass(myElement.value);
           }
           
        
    
</script>

<script>
function goNext()
        {    
            var j$ = jQuery.noConflict();
               
            
             var wkComm = j$("#theCal\\:theForm\\:theStartDate").val();
             var siteId = j$("#theCal\\:theForm\\:theSite").val();
               nextMonth(siteId, wkComm);
           }
</script>
<script>
function goToSite()
        {    
            var j$ = jQuery.noConflict();
            var wkComm = j$("#theCal\\:theForm\\:theStartDate").val();
             var siteId = j$("#theCal\\:theForm\\:theSite").val();
             
               goSite(siteId,wkComm);
           }
</script>


       <apex:actionFunction name="myFunc" action="{!saveCalendars}" rerender="theBlock" >       
       <apex:param name="site" value="" />
       <apex:param name="wkcom" value="" />
       
       </apex:actionFunction> 
       
              <apex:actionFunction name="nextMonth" action="{!next}" rerender="theBlock" >       
       <apex:param name="siteId" value="" />
       
       
       </apex:actionFunction> 
       <apex:actionFunction name="goSite" action="{!doSearch}" rerender="theBlock" status="status" >    
           <apex:param name="siteId" value="" />
           <apex:param name="wkComm" value="" />
       </apex:actionFunction>       
    </apex:form>

</apex:page>

 

Here is the code...

 

public  class CalendarController 
{

    
public List<Colleague_Calendar__c> calendars {get; private set;}

   public String soql{get; set;}
   public String siteId{get; set;}
   private Date convDate {get; set;}
   
   public CalendarController()
    {
       calendars = null;

    }

   public void getWeeklyCalendars() 
   {  
        
           
           try 
           {
               calendars = Database.query(soql); 
               System.debug('Size of result:' + calendars.size());
               if (calendars.size() == 0)
               {
                   calendars = null;
               }
           }
           catch (Exception e)
           {
               
               ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please choose site from the pick list!'));
            }
            
    }
    
 
 
 
 
 
 
 /********************************************************************/
 
 public PageReference doSearch() {
       
         
        
        try 
        {       
            
                siteId = ApexPages.CurrentPage().GetParameters().get('siteId'); //'001A000000i5LScIAM';//
                String tempDate = ApexPages.currentPage().getParameters().get('wkComm');
                convDate = XMLStringToDate(tempDate);
                soql =  'select  Colleague__r.Account__c, Colleague__r.Name,Colleague__r.Worker_First_Name__c,Colleague__r.UK_Mobile_Number__c, Status__c, Wk_Com__c, Monday__c, Tuesday__c, Wednesday__c, Thursday__c, Friday__c, Saturday__c, Sunday__c from Colleague_Calendar__c where Colleague__r.Account__c = :siteId and Wk_Com__c = :convDate and Colleague__r.Account__c != null  order by Colleague__r.Name asc';
                System.debug('Site in Search: ' + siteId);
              
          

            getWeeklyCalendars();
        }catch (Exception e)
           {
               
               ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please choose site and date from the pick list!'));
            }
        
        
        return null;
   
 }
 
 
 
 
 public PageReference next() {
        return null;
    }
 
 
 
 
 
 public List<selectOption> getClientSites() 
    {
        List<selectOption> options = new List<selectOption>();
        // We don't need this at the moment, remember TODO: test for invalid Id! 
         options.add(new selectOption('', '- None -')); 
        
        for (Account sites : [select Id, Name from Account])
        {
            options.add(new selectOption(sites.Id, sites.Name));
        }
        
        return options;
    }
 
 public static Date XMLstringToDate(String s)
        {
          //XML Date String is in the format dd/mm/yyyy
          String[] stringDate = s.split('/');
          Integer d =  Integer.valueOf(stringDate[0]);
          Integer m = Integer.valueOf(stringDate[1]);
          Integer y = Integer.valueOf(stringDate[2]);
          return date.newInstance(y,m,d);
        }
 
 // Workaround for getting a SalesForce style date picker...
    
   Opportunity o = new Opportunity();
   public Opportunity getProxyObject() { return o; }
 
 
 


    public String debugSoql { get; set; }

    public PageReference saveCalendars() {
        return null;
    }
     
   

}

 

 

I really hope someone can help with this. I've been looking at it for 12 hours :-(

 

Hi,

 

I seem to be struggling with finding a good starting point to getting  drag and drop functionality persisting back to the database in a Visualforce page.

 

I have a few questions regarding this based upon what I have found searching around for stuff.

 

  • Is drag and drop native to VisualForce yet? I saw a couple of posts hinting at the possibility.
  • If it is, then how do I go about implementing it? I can find plenty of PHP based examples but none in VisualForce.

My use case is that I want to be able to pull a list of start times and people from the database then allow the user to drag and drop a person from one start time to another and this then be saved back to the database upon dropping.

 

I have looked at so many different things now, as a newbie to SF I am getting very confused and I'm not sure  where to start. Do I need to use the Ajax Toolkit? I'd like to be able to use VisualForce directly but if not how about JQuery?

 

I really need some advice from you more experienced developers here as to the best way of cracking this.

 

Ian

 

 

Hi,

 

I'm new to this, sorry if this has already been covered but I'm getting very dismayed by this not working.

 

What I need to do is have an action associated with a selection from my selectList on my VF page that will go off and use the selectedOption as an Id in a query.

 

For example the selectList has a list of accounts (Sites) and I want the user to select an account, fire the action that will then display that account on screen to the user.

 

I just keep getting the "System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: [] "

 

error message.

 

Here is the code from the VF page

 

 

<apex:selectList id="sites"  size="1" title="Manager">
                        <apex:selectOptions value="{!ClientSites}"></apex:selectOptions>
                        <apex:actionSupport event="onchange" action="{!saveCalendars}">
                        <apex:param name="site" value="{!theSite}" assignTo="{!theSite}" />
                        </apex:actionSupport>
                    </apex:selectList>

 

 

And here is the code I'm trying to get to work...

 

public Id theSite {get; set;}
   
    public PageReference saveCalendars()
    {
       
       
        theSite = ApexPages.currentPage().getParameters().get('site');
       
       
        Client_Site__c siteToUpdate =
        new Client_Site__c(Id = theSite);
        System.debug('This is the ID : ' + theSite);
        update siteToUpdate;
        return null;
       
       
    }

I really hope someone can help me with tis. Just cannot see why it won't work? The onlty thing I can think of is a timing thing with rendering etc.

 

Does anyone have suggestions on how I can fix this please?

 

Thanks in advance,

 

Ian

Hi,

 

I posted this in the newbies forum too. Apologies if I have broken any protocols but I am really stumped with this and as you may imagine, when learning a new technology it is quite important that any examples work as expected.

 

The problem I have is that I don't know if it's something I have done or simply because the negative test cases doesn't work in the example?

 

First of all here is the code I'm talking about - it's in the testing section of the MileageTracker - Negative Test Case.

 

 

static testMethod void runNegativeTestCase() 
  	{
  		System.debug('Inserting 501 miles... negative test case');
  		
  		Mileage__c testMiles3 = new Mileage__c(Miles__c = 501, Date__c = System.today());
  		
  		try 
  		{
  			insert testMiles3;
  		} catch (DmlException e)
  			{
  				
				  			//Assert Error Message  
				    
				   System.assert(e.getMessage().contains('Insert failed. First exception '+
				      'on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, '+
				      'Mileage request exceeds daily limit(500): [Miles__c]'), 
				         e.getMessage()); 
				
				//Assert Field  
				    
				   System.assertEquals(Mileage__c.Miles__c, e.getDmlFields(0)[0]);
				
				//Assert Status Code  
				    
				   System.assertEquals('FIELD_CUSTOM_VALIDATION_EXCEPTION', 
				                        e.getDmlStatusCode(0));
				        
  			}
  	}

 

 

The problem I have is that when I run the test I get the following - see linked image...

 

Negative Test Case Mileage Tracker

 

 

Thanks in advance for your help.

 

Kind regards,

 

Ian

 

Hi,

 

I'm greatly enjoying my journey into developing Force applications. I am new to this but not to programming in general.

 

I am doing the MileageTracker work book and everything was fine until I started work on the Unit Tests.

 

My negative tests are in a try catch block identical to the tutorial - I even copied and pasted the code - it saves ok but when I run the test the test fails. I know the code should throw an exception but it is as though it is not being caught?

 

Here is what I see in the debug log...

=======================

00:18:50.419 (419341000)|EXCEPTION_THROWN|[99]|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []
00:18:50.419 (419562000)|FATAL_ERROR|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []

Class.MileageTrackertestSuite.runNegativeTestCases: line 99, column 13
External entry point

 

======================

 

So, my question is, has anyone else encountered this and how do I overcome it and get a green light on the test?

 

Many thanks,

 

Ian

Hi,

 

I can find plenty of places where static resources are used to house images for VisualForce pages which are then rendered as pdf no problem. However, has anyone tried using a URL field in a custom object when that URL points to an Amazon S3 storage?

 

This is my VF page at the top...

 

<apex:page standardStylesheets="false"   standardController="pb__InventoryItem__c" renderAs="pdf" >

<apex:variable var="inv" value="{!pb__InventoryItem__c}"/> 

 

You can see I'm creating a variable so I can access various fields from my custom object...

 

Just one of the image tags here...

 

<apex:image url="{!inv.pb__Image1__c}" width="100%" height="425px" />

 When I let it render as HTML all images appear no problem. The URL that is returned is ok and everything works until I renderAs PDF and the images break. Is there any way around this? I can't see creating static resources for every image as being a solution. Especially as there is everything in the S3 storage area. All I need to do is to be able to render out to PDF!

 

Also, does anyone know if it's easy enough to render a Google map out to PDF from a VF page?

 

Thanks in advance. I'd really appreciate any help as this is quite an urgent job. Very frustrating when you have got the page working apart from rendering to PDF.

 

Regards,

Ian

 

Hi, I know this will have been posted before but I have quite a complicated issue here (for me cos I'm new to Force dev) that I'd like to share with you guys to see if there is anything I am missing.

 

I have a requirement for a bulk upload of records from another system that will be uploaded using the DataLoader from a csv file. No problem so far, have that covered and working.

 

The problem is that there may or may not be lookup field values in the file rows that can be used to form relationships within the SalesForce system and if so they need hooking up on import.

 

So this means that somehow, for every line of the import record I need to look at an Account record to see if certain values match. If not I then need to link the import record to know values for dummy Account objects marked as "UNKNOWN".

 

The spec is they want a trigger to do this and I have come up with three possible solutions, all of which run into Governor Limits pretty quickly. I cannot find a way of having any more than 99 records in the import file at a time?

 

OK so here is my code for each solution. I'd like you to cast your eyes on the code and see if there is anything simple that I have missed that would allow me to do this without running into the Governor Limits.

 

Here's the code...

 

First idea I had was to use a MAP so I would get a list of Accounts in one hit. From there I'd go for a match on Account Id. Unfortunately I have only one AccountId in the file(possibly). The other numbers are from a legacy system so I can only match on those which means using SOQL?

 

trigger customUpload on Custom__c (before insert, before update) 
{
	

// Map for THE MAP WAY //

Map<Id,Account> accountMap = new Map<Id, Account>([select Id,  Customer_Number__c from Account]);




	
	for (Custom__c customObj : trigger.new)
	{
				
		
		/*###################################################################################################################################################################################*/
		/*																																																																																										*/
		/*THE MAP WAY - it only solves on problem partially in that we can easily look for a match on Id in the MAP. However, we can only have a MAP of the form <Id,SOBject> in other 
		/* words, we can only use an actual Id to search on Account key field. We only have a key field for one attribute which is Lookup1__c or Lookup1 in the import file. Another issue is that this works
		/* by relying on catching exceptions which are thrown when no match shown. Don't like doing that but still works.
		/
		/* SOLUTION if using this method would be to ensure that instead of Lookup2 and Lookup3 in the import file we actually have SalesForce Ids as Lookups that we can use to get matches from the 
		/* map using those Account Numbers for Lookup1 and 2 e.g. instead of Lookup2__c matching on Account.Customer_Number__c we match on Lookup__c (an Account number due to it being a lookup). I do not know if this is possible though...
		/*   
		/* AT 100 ROWS ON INPUT FILE THIS FAILS WITH TOO MANY SOQL QUERIES                                                                                                                   */
		/*###################################################################################################################################################################################*/
		
		
		try
		{
			Account Lookup1Match = accountMap.get(customObj.Lookup1__c);
			
		}
		catch (Exception e)
		{
			Lookup1Unknown();
		}
		
		
		// Cannot use this technique for the the other two because these are not SalesForce Ids and we can only build a map with an Id and an SObject to enable searches like this as far as I am aware.
		// Thus we have to resort to using SOQL queries...
		
		// Get the Account with the matching Lookup2__c to Account.Lookup2__c
		List<Account> Lookup2Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup2__c];
			if (Lookup2Match.size() == 0)
			{
				Lookup2Unknown();
			}
		// Get the Account with the matching Lookup3_RID to the Account.Lookup3__c
		List<Account> Lookup3Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup3__c];
			if (Lookup3Match.size() == 0)
			{
				Lookup3Unknown();
			}	
	
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}	
	
	
	
}

 So I thought I'd try the SOQL way.... Just look for a match using SOQL for every line in the import file...

 

trigger testingUpload on Custom__c (before insert, before update) 
{
	






	
	for (Custom__c customObj : trigger.new)
	{
		// Get the Account with the matching Lookup1 to Account Id...
		
		
		/*###################################################################################################################################################################################*/
		/*THE SOQL WAY - runs into SOQL limits very quickly due to invoking the 3 queries for every line in file to insert */
		/* 
		/* FOR 100 LINES IN THE INPUT FILE THIS FAILS BY GOING OVER THE 100 LIMIT ON SOQL QUERIES.                                                                                */
		/*###################################################################################################################################################################################*/
	
		
		
		


		// Get the Account with the matching Lookup1__c to Id on Account...
		List<Account> Lookup1Match = [Select Id from Account where Id = :customObj.Lookup1__c];
			if (Lookup1Match.size() == 0)
			{
				Lookup1Unknown();
			}
		
		// Get the Account with the matching Lookup2__c to Account.Lookup2__c
		List<Account> Lookup2Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup2__c];
			if (Lookup2Match.size() == 0)
			{
				Lookup2Unknown();
			}
		// Get the Account with the matching Lookup3_RID to the Account.Lookup3__c
		List<Account> Lookup3Match = [Select Id from Account where Customer_Number__c = :customObj.Lookup3__c];
			if (Lookup3Match.size() == 0)
			{
				Lookup3Unknown();
			}
		
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}
	
	
	
	
}

 As you can see, it runs into the 100 query limit pretty quick...

 

So then I thought I'd try the CODE way. Basically get an Account list in one hit using SOQL then loop through the list for every line in the input file. Yes I know, very innefficient! :-\

 

trigger testingUpload on Custom__c (before insert, before update) 
{
	

List<Account> accountList = new List<Account>([select Id,  Customer_Number__c from Account]);




	
	for (Custom__c customObj : trigger.new)
	{
		// Get the Account with the matching Lookup1 to Account Id...
		
		
		/*###################################################################################################################################################################################*/
		/*THE CODE WAY - runs into scripting lines over 200,0000 */
		/*###################################################################################################################################################################################*/
	
		
		for (Account acct : accountList) 
			{
				
				
				if (customObj.Lookup1__c == acct.Lookup1__c)
				{
					
					customObj.Lookup1__c = acct.Id;				
				}
				else 				
				{
					
					lesseeUnknown();
				}
				
				
				if (customObj.Lookup2__c == acct.Lookup2__c)
				{

					customObj.Lookup2__c = acct.Id;				
				}
				else
				{
					
					shipperUnknown();
				}
				
				
				
				if (customObj.Lookup3__c == acct.Lookup3__c)
				{
					
					customObj.Lookup3__c = acct.Id;
				}
				else
				{
					Lookup3Unknown();
				}
			}
		
	
	}
	
	public void Lookup1Unknown()
	{
		system.debug('Lookup1Unknown');
	}
	
	public void Lookup2Unknown()
	{
		system.debug('Lookup2Unknown');
	}
	
	public void Lookup3Unknown()
	{
		system.debug('Lookup3Unknown');
	}
	
	
	
	
}

 I would be very grateful if someone could point me in the right direction with this one. It seems I can get code that works but not for many input file lines... The requirement is to eventually automate this process you see so the uploads are done unattended.

 

My thoughts are that it's asking a trigger to do a lot of work BUT this is what the client specified. I value your thoughts on this.

 

Thanks and regards,

 

Ian

Hi,

 

Can anyone help me with this simple query?

 

When I hard code the WhatId it works perfectly - here's the code...

 

Account acc =  [Select Id, PersonContactId, IsPersonAccount, Primary_Service__r.Name, Primary_Service__r.Id, Source_of_Data__c, Reason_for_Contact__c, People_Status__c, PersonMailingStreet, PersonMailingCity, PersonMailingState , PersonMailingPostalCode, PersonMailingCountry, PersonMobilePhone, PersonHomePhone, Gender__c, Age__c, DOB_Estimated__c, Marital_Status__c, Commitment_Type__c, Commitment_Date__c From Account where Id =  limit 1];

 However, I want it to be (unsurprisingly) dynamic. I thought something like this should work:

 

for(Task task : trigger.new){
		
		


		//Id wId = task.WhatId;
		Account acc =  [Select Id, PersonContactId, IsPersonAccount, Primary_Service__r.Name, Primary_Service__r.Id, Source_of_Data__c, Reason_for_Contact__c, People_Status__c, PersonMailingStreet, PersonMailingCity, PersonMailingState , PersonMailingPostalCode, PersonMailingCountry, PersonMobilePhone, PersonHomePhone, Gender__c, Age__c, DOB_Estimated__c, Marital_Status__c, Commitment_Type__c, Commitment_Date__c From Account where Id = task.WhatId  limit 1];


		task.Primary_Service__c = acc.Primary_Service__r.Name;
			task.Primary_Service_ID__c = acc.Primary_Service__r.Id;
			task.Source_of_Data__c = acc.Source_of_Data__c;
			task.Reason_for_Contact__c = acc.Reason_for_Contact__c;
			task.People_Status__c = acc.People_Status__c;
			task.Street__c = acc.PersonMailingStreet;
			task.City__c = acc.PersonMailingCity;
			task.State__c  = acc.PersonMailingState;
			task.PostCode__c = acc.PersonMailingPostalCode;
			task.Country__c = acc.PersonMailingCountry;
			task.Mobile__c = acc.PersonMobilePhone;
			task.Home_Phone__c = acc.PersonHomePhone;
			task.Gender__c = acc.Gender__c;
			task.Age__c = acc.Age__c;
			task.DOB_Estimated__c = acc.DOB_Estimated__c;
			task.Marital_Status__c = acc.Marital_Status__c;
			task.Commitment_Type__c = acc.Commitment_Type__c;
			task.Commitment_Date__c = acc.Commitment_Date__c;

	}

 Sorry, I left the hardcoded Id out of the first example but I'm sure you get the idea.

 

Why does a hard coded Id work and a bind variable not work?

 

Thanks in anticipation.

 

Ian

Hi,

 

Does anyone know how to do this? I thought it would be quite straightforward. I set up two datatables and two different queries in my controller but one (the second column) just doesn't show anything.

Is there a standard approach to displaying two lists of objects in two columns in VisualForce?

 

I can post code later but not sure how much it would help because I've described what I've done.

 

Regards,

 

Ian

Hi,

 

I have a page with a drop down where users can select an ID basically that is passed as a parameter back to the controller.

 

Now it all works fine and displays records as it should when the user selects a valid entry. However, when the user selects "none"

 

then the query runs and returns no rows and flashes no rows on the screen. Then it runs AGAIN with the PREVIOUS selection and gets some results!

 

How is this possible??

 

Basically it looks like the query is always runnning twice and picking up the last successful value. So even if I change things like to cycle through weeks of records, it does it then reverts back to the one before...

 

 

<p>Working on forward and back buttons to allow cycling through successive weeks...</p>
<br />
<br /><br />
<table id="t1"><tr><td><h2 class="left">Week Commencing:</h2> <apex:inputField value="{!proxyObject.closeDate}" id="theStartDate" styleClass="left"    /> </td>
                   <td><h2 class="left">Site: </h2><apex:selectList id="theSite"  size="1"   styleclass="left">
                        <apex:selectOptions value="{!ClientSites}"></apex:selectOptions>
                        

                    </apex:selectList>
                    </td>
</tr>
<apex:actionStatus startText="Retrieving records..." id="status"   startStyle="color:red;font-size:20px;"  />
<apex:pageMessages id="errors" />
</table>
<apex:pageBlock mode="edit" id="theBlock">
<apex:pageBlockButtons >
<apex:commandButton value="<< Prev" id="prev" rerender="theBlock,errors" />
<apex:commandButton value="Go" id="theGo" onclick="goToSite();" rerender="theBlock,errors"/>
<apex:commandButton onclick="goNext();" value="Next >>" id="next" rerender="theBlock,errors" />

</apex:pageBlockButtons>

<apex:outputPanel rendered="{!IF(siteId == null, false, true)}" >
    <apex:pageBlockTable value="{!calendars}" var="aColleague" id="theTable"  >
        <apex:column styleClass="cyan" >
                        <apex:facet name="header">
                <b>SiteId</b>
            </apex:facet>
           {!aColleague.Colleague__r.Account__c}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>ColleagueId</b>
            </apex:facet>
            {!aColleague.Colleague__r.Id}
        </apex:column>
        <apex:column styleClass="cyan" >
                        <apex:facet name="header">
                <b>Last Name</b>
            </apex:facet>
           {!aColleague.Colleague__r.Name}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>First Name</b>
            </apex:facet>
            {!aColleague.Colleague__r.Worker_First_Name__c}
        </apex:column>
        <apex:column styleClass="cyan">
            <apex:facet name="header">
                <b>Mobile No.</b>
            </apex:facet>
            {!aColleague.Colleague__r.UK_Mobile_Number__c}
            
        </apex:column>
        <apex:column styleClass="grey">
        <apex:facet name="header">
            <b>Status</b>
        </apex:facet>
        
        <apex:inputField styleClass="{!aColleague.Status__c}" value="{!aColleague.Status__c}" onchange="changeClass(this);" />
            
        </apex:column>
        <apex:column rendered="false" >
            <apex:facet name="header">
                <b>Wk. Comm</b>
            </apex:facet>
            <apex:outputText value="{0,date,dd'/'MM'/'yyyy}">
            <apex:param value="{!aColleague.Wk_Com__c}" /> 
            </apex:outputText>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Sun</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Sunday__c}" value="{!aColleague.Sunday__c}" onchange="changeClass(this);" />
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Mon</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Monday__c}" value="{!aColleague.Monday__c}" onchange="changeClass(this);" />
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Tue</b>
            </apex:facet>
                <apex:inputField styleClass="{!aColleague.Tuesday__c}" value="{!aColleague.Tuesday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Wed</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Wednesday__c}" value="{!aColleague.Wednesday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Thu</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Thursday__c}" value="{!aColleague.Thursday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Fri</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Friday__c}" value="{!aColleague.Friday__c}" onchange="changeClass(this);"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">
                <b>Sat</b>
            </apex:facet>
            <apex:inputField styleClass="{!aColleague.Saturday__c}" value="{!aColleague.Saturday__c}" onchange="changeClass(this);"/>
        </apex:column>

    </apex:pageBlockTable>
 </apex:outputPanel>   
            
              <apex:pageBlock title="Debug" id="debug" rendered="false">
      <apex:outputText value="{!debugSoql}" />           
  </apex:pageBlock>
       </apex:pageBlock>
   
   <script type="text/javascript">
    jQuery.noConflict();
    function doSave(sel,etc) {
    myFunc(sel.value,etc.value);
     
}
</script>

<script type="text/javascript">
    
jQuery.noConflict();
    function changeClass(myElement)
        {      
                 jQuery(myElement).removeAttr('class');
                 jQuery(myElement).addClass(myElement.value);
           }
           
        
    
</script>

<script>
function goNext()
        {    
            var j$ = jQuery.noConflict();
               
            
             var wkComm = j$("#theCal\\:theForm\\:theStartDate").val();
             var siteId = j$("#theCal\\:theForm\\:theSite").val();
               nextMonth(siteId, wkComm);
           }
</script>
<script>
function goToSite()
        {    
            var j$ = jQuery.noConflict();
            var wkComm = j$("#theCal\\:theForm\\:theStartDate").val();
             var siteId = j$("#theCal\\:theForm\\:theSite").val();
             
               goSite(siteId,wkComm);
           }
</script>


       <apex:actionFunction name="myFunc" action="{!saveCalendars}" rerender="theBlock" >       
       <apex:param name="site" value="" />
       <apex:param name="wkcom" value="" />
       
       </apex:actionFunction> 
       
              <apex:actionFunction name="nextMonth" action="{!next}" rerender="theBlock" >       
       <apex:param name="siteId" value="" />
       
       
       </apex:actionFunction> 
       <apex:actionFunction name="goSite" action="{!doSearch}" rerender="theBlock" status="status" >    
           <apex:param name="siteId" value="" />
           <apex:param name="wkComm" value="" />
       </apex:actionFunction>       
    </apex:form>

</apex:page>

 

Here is the code...

 

public  class CalendarController 
{

    
public List<Colleague_Calendar__c> calendars {get; private set;}

   public String soql{get; set;}
   public String siteId{get; set;}
   private Date convDate {get; set;}
   
   public CalendarController()
    {
       calendars = null;

    }

   public void getWeeklyCalendars() 
   {  
        
           
           try 
           {
               calendars = Database.query(soql); 
               System.debug('Size of result:' + calendars.size());
               if (calendars.size() == 0)
               {
                   calendars = null;
               }
           }
           catch (Exception e)
           {
               
               ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please choose site from the pick list!'));
            }
            
    }
    
 
 
 
 
 
 
 /********************************************************************/
 
 public PageReference doSearch() {
       
         
        
        try 
        {       
            
                siteId = ApexPages.CurrentPage().GetParameters().get('siteId'); //'001A000000i5LScIAM';//
                String tempDate = ApexPages.currentPage().getParameters().get('wkComm');
                convDate = XMLStringToDate(tempDate);
                soql =  'select  Colleague__r.Account__c, Colleague__r.Name,Colleague__r.Worker_First_Name__c,Colleague__r.UK_Mobile_Number__c, Status__c, Wk_Com__c, Monday__c, Tuesday__c, Wednesday__c, Thursday__c, Friday__c, Saturday__c, Sunday__c from Colleague_Calendar__c where Colleague__r.Account__c = :siteId and Wk_Com__c = :convDate and Colleague__r.Account__c != null  order by Colleague__r.Name asc';
                System.debug('Site in Search: ' + siteId);
              
          

            getWeeklyCalendars();
        }catch (Exception e)
           {
               
               ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please choose site and date from the pick list!'));
            }
        
        
        return null;
   
 }
 
 
 
 
 public PageReference next() {
        return null;
    }
 
 
 
 
 
 public List<selectOption> getClientSites() 
    {
        List<selectOption> options = new List<selectOption>();
        // We don't need this at the moment, remember TODO: test for invalid Id! 
         options.add(new selectOption('', '- None -')); 
        
        for (Account sites : [select Id, Name from Account])
        {
            options.add(new selectOption(sites.Id, sites.Name));
        }
        
        return options;
    }
 
 public static Date XMLstringToDate(String s)
        {
          //XML Date String is in the format dd/mm/yyyy
          String[] stringDate = s.split('/');
          Integer d =  Integer.valueOf(stringDate[0]);
          Integer m = Integer.valueOf(stringDate[1]);
          Integer y = Integer.valueOf(stringDate[2]);
          return date.newInstance(y,m,d);
        }
 
 // Workaround for getting a SalesForce style date picker...
    
   Opportunity o = new Opportunity();
   public Opportunity getProxyObject() { return o; }
 
 
 


    public String debugSoql { get; set; }

    public PageReference saveCalendars() {
        return null;
    }
     
   

}

 

 

I really hope someone can help with this. I've been looking at it for 12 hours :-(

 

Hi,

 

I'm new to this, sorry if this has already been covered but I'm getting very dismayed by this not working.

 

What I need to do is have an action associated with a selection from my selectList on my VF page that will go off and use the selectedOption as an Id in a query.

 

For example the selectList has a list of accounts (Sites) and I want the user to select an account, fire the action that will then display that account on screen to the user.

 

I just keep getting the "System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: [] "

 

error message.

 

Here is the code from the VF page

 

 

<apex:selectList id="sites"  size="1" title="Manager">
                        <apex:selectOptions value="{!ClientSites}"></apex:selectOptions>
                        <apex:actionSupport event="onchange" action="{!saveCalendars}">
                        <apex:param name="site" value="{!theSite}" assignTo="{!theSite}" />
                        </apex:actionSupport>
                    </apex:selectList>

 

 

And here is the code I'm trying to get to work...

 

public Id theSite {get; set;}
   
    public PageReference saveCalendars()
    {
       
       
        theSite = ApexPages.currentPage().getParameters().get('site');
       
       
        Client_Site__c siteToUpdate =
        new Client_Site__c(Id = theSite);
        System.debug('This is the ID : ' + theSite);
        update siteToUpdate;
        return null;
       
       
    }

I really hope someone can help me with tis. Just cannot see why it won't work? The onlty thing I can think of is a timing thing with rendering etc.

 

Does anyone have suggestions on how I can fix this please?

 

Thanks in advance,

 

Ian

Hi,

 

I posted this in the newbies forum too. Apologies if I have broken any protocols but I am really stumped with this and as you may imagine, when learning a new technology it is quite important that any examples work as expected.

 

The problem I have is that I don't know if it's something I have done or simply because the negative test cases doesn't work in the example?

 

First of all here is the code I'm talking about - it's in the testing section of the MileageTracker - Negative Test Case.

 

 

static testMethod void runNegativeTestCase() 
  	{
  		System.debug('Inserting 501 miles... negative test case');
  		
  		Mileage__c testMiles3 = new Mileage__c(Miles__c = 501, Date__c = System.today());
  		
  		try 
  		{
  			insert testMiles3;
  		} catch (DmlException e)
  			{
  				
				  			//Assert Error Message  
				    
				   System.assert(e.getMessage().contains('Insert failed. First exception '+
				      'on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, '+
				      'Mileage request exceeds daily limit(500): [Miles__c]'), 
				         e.getMessage()); 
				
				//Assert Field  
				    
				   System.assertEquals(Mileage__c.Miles__c, e.getDmlFields(0)[0]);
				
				//Assert Status Code  
				    
				   System.assertEquals('FIELD_CUSTOM_VALIDATION_EXCEPTION', 
				                        e.getDmlStatusCode(0));
				        
  			}
  	}

 

 

The problem I have is that when I run the test I get the following - see linked image...

 

Negative Test Case Mileage Tracker

 

 

Thanks in advance for your help.

 

Kind regards,

 

Ian

 

Hi,

 

I'm greatly enjoying my journey into developing Force applications. I am new to this but not to programming in general.

 

I am doing the MileageTracker work book and everything was fine until I started work on the Unit Tests.

 

My negative tests are in a try catch block identical to the tutorial - I even copied and pasted the code - it saves ok but when I run the test the test fails. I know the code should throw an exception but it is as though it is not being caught?

 

Here is what I see in the debug log...

=======================

00:18:50.419 (419341000)|EXCEPTION_THROWN|[99]|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []
00:18:50.419 (419562000)|FATAL_ERROR|System.AssertException: Assertion Failed: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mileage request exceeds daily limit: 500: []

Class.MileageTrackertestSuite.runNegativeTestCases: line 99, column 13
External entry point

 

======================

 

So, my question is, has anyone else encountered this and how do I overcome it and get a green light on the test?

 

Many thanks,

 

Ian

Page 39 of Force.com_workbook v2. provides code for testing the class created in Tutorial 5.

No surprisingly, this test code itself is wrong, and running it fails.

How do I correct the code so that these two asserts will work correctly?

System.assert(e.getMessage().contains('Insert failed. First exception on row 0; '+
'first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, '+
'Mileage request exceeds daily limit(500): [Miles__c]'),
e.getMessage());

System.assertEquals(Mileage__c.Miles__c, e.getDmlFields(0)[0]);

I've already discovered that I can get the first assertion to work correctly if change "...daily limit(500): [Miles__c]')," to "daily limit: 500: []')," ... but I imagine that "Miles__c" should have some value that isn't being added in MileageUtil, but should?

And the second assertion, I have no idea how to fix....

-Brian.