function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
SoozeeSoozee 

VisualForce Email Template Error

I'm trying to create my first Visualforce email template that will be used in a workflow rule when a field is updated with a specific value.  

I feel like I'm pretty close, but I am getting the following error when trying to save the Email Template:

 

Error: <messaging:emailTemplate> cannot contain <apex:form>.

 

But, when I take the <apex:form> tags out, I get this error:

 

Error: c:travelregistry_email_template_component must occur between <apex:form></apex:form> tags

 

Here is the VisualForce Email Template code:

 

<messaging:emailTemplate subject="Travel Itinerary for : {!Relatedto.Trip_Name__c}"  recipientType="User" relatedToType="Travel_Registry__c">

<messaging:htmlEmailBody >

<p>Your itinerary for: {!relatedto.trip_name__c} is below.  <br />
<br /></p>

<c:TravelRegistry_Email_Template_Component TRID="{!RelatedTo.ID}"/>

</messaging:htmlEmailBody>

</messaging:emailTemplate>

 Here is the Component Code:

 

<apex:component controller="Travel_Itinerary_Print_Controller_Ext" access="global">
<apex:attribute name="TRID" type="ID" assignTo="{!TravelId}" description="Travel ID for the email template"/>


<c:TravelRegistry_Page_Header_For_Email />

   
        <table width="100%">           
            <tr>
                <td>
                    &nbsp;&nbsp;&nbsp;<font size="+1">Travel Itinerary for {!TripName}</font>
                    <apex:inputText id="TripId" value="{!TripId}" rendered="false"/>                                        
                </td>
            </tr>
            <tr>
                <td>    
                    <apex:messages />                                   
                </td>
            </tr>
        </table>
        <table width="100%">
            
            <tr>
                <td colspan="2">
                    <apex:dataTable value="{!AccommodationsList}" var="accommodations">  
                                        
                                 <apex:column >     
                                    <apex:facet name="header" >
                                        Location Name 
                                    </apex:facet>
                                    {!Accommodations.Nickname}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Accommodation Type 
                                    </apex:facet>
                                    {!Accommodations.AccommodationsType}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Start Date 
                                    </apex:facet>
                                    {!Accommodations.StartDate}                                                                       
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                         End Date 
                                    </apex:facet>
                                    {!Accommodations.EndDate}                                                                        
                                 </apex:column>
                                 
                           </apex:dataTable>                          
                  
                          <apex:dataTable value="{!FlightList}" var="flight">
                                                                     
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Airline 
                                    </apex:facet>
                                    {!flight.Airline}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Flight # 
                                    </apex:facet>
                                    {!flight.FlightNumber}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Departure Date 
                                    </apex:facet>
                                    {!flight.StartDate}                                                                 
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" > 
                                        Departure Airport
                                    </apex:facet>
                                    {!flight.DepartureAirportCode}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Arrival Airport
                                    </apex:facet>
                                    {!flight.ArrivalAirportCode}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Overnight?
                                    </apex:facet>
                                    {!flight.OvernightFlight}                                                                        
                                 </apex:column>
                                 
                           </apex:dataTable>                              
                          
                           <apex:dataTable value="{!OtherList}" var="other">
                                         
                                 <apex:column >     
                                    <apex:facet name="header" >
                                        Type 
                                    </apex:facet>
                                    {!other.RecordTypeName}                                                                        
                                 </apex:column>
                                 
                                 <apex:column >     
                                    <apex:facet name="header" >
                                        Carrier Name 
                                    </apex:facet>
                                    {!other.Nickname}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Departure City 
                                    </apex:facet>
                                    {!other.DepartureCity}                                                                        
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                        Departure Date 
                                    </apex:facet>
                                    {!other.StartDate}                                                                     
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" >
                                         Arrival City 
                                    </apex:facet>
                                   {!other.ArrivalCity}                                                                   
                                 </apex:column>
                                 <apex:column >    
                                    <apex:facet name="header" > 
                                        Arrival Date
                                    </apex:facet>
                                    {!other.EndDate}                                                                        
                                 </apex:column>
                           </apex:dataTable>
            </td>
           </tr>
        
        </table>
             

</apex:component>

 And, finally the Controller Code:

 

public without sharing class Travel_Itinerary_Print_Controller_Ext {
	
	Private string email;
	public Id TravelId {get;set;}
	public String TripId {get;set;}
	public String TripName {get;set;}
	public List<ItineraryWrapperDTO> AccommodationsList {get;set;}
	public List<ItineraryWrapperDTO> FlightList {get;set;}
	public List<ItineraryWrapperDTO> OtherList {get;set;}
	
	
	public class ItineraryWrapperDTO {
         private Travel_Itinerary__c itinerarySf;
         
         public ItineraryWrapperDTO (Travel_Itinerary__c itSfObj) {
         	this.itinerarySf = itSfObj; 
         }    	
    	 public String Nickname {
    		get{if(itinerarySf != null){
	    			if(itinerarySf.Nickname__c != null){
	    				return itinerarySf.Nickname__c;
	    			}else{return ' ';}
    			}else{return null;}
    		}
    	 }
    	 public String Id {
    		get{return (itinerarySf != null) ? itinerarySf.Id : null;}
    	 }     	 
    	 public String AccommodationsType {
    		get{return (itinerarySf != null) ? itinerarySf.Accommodations_Type__c : null;}
    	 }
    	 public String Airline {
    		get{if(itinerarySf != null){
	    			 if(itinerarySf.Airline__c != null){
	    			 	return itinerarySf.Airline__c;}
	    			 else{return '';}
    			}else{return null;}}
    	 }
    	 public String RecordTypeName {
    		get{return (itinerarySf != null) ? itinerarySf.RecordType.DeveloperName : null;}
    	 }
    	 
    	 public String ArrivalAirportCode {
    		get{return (itinerarySf != null) ? itinerarySf.Arrival_Airport_Code__c : null;}
    	 }
    	 public String ArrivalCity {
    		get{return (itinerarySf != null) ? itinerarySf.Arrival_City__c : null;}
    	 }
    	 public String City {
    		get{return (itinerarySf != null) ? itinerarySf.City__c : null;}
    	 }
    	 public String Country{
    		get{return (itinerarySf != null) ? itinerarySf.Country__c : null;}
    	 }
    	 public String DepartureAirportCode {
    		get{return (itinerarySf != null) ? itinerarySf.Departure_Airport_Code__c : null;}
         }
    	 public String DepartureCity {
    		get{return (itinerarySf != null) ? itinerarySf.Departure_City__c : null;}
    	 }
    	 public String EndDate {
    		get{return (itinerarySf != null && itinerarySF.End_Date__c != null) ? itinerarySf.End_Date__c.format() : null;}
    	 }
    	 public String FlightNumber {
    		get{return (itinerarySf != null) ? itinerarySf.Flight_Number__c : null;}
    	 }
    	 public String MobilePhone {
    		get{return (itinerarySf != null) ? itinerarySf.Mobile_Phone__c : null;}
    	 }
    	 public String OvernightFlight {
    		get{if(itinerarySf != null){
	    			if(itinerarySf.OverNight_Flight__c == true){
	    				return 'Yes';
	    			}else{
	    				return 'No';
	    			}
    			}else{return null;}
    		}    		
    	 }
    	 public String PostalCode {
    		get{return (itinerarySf != null) ? itinerarySf.Postal_Code__c : null;}
    	 }
    	 public String PrimaryPhone {
    		get{return (itinerarySf != null) ? itinerarySf.Primary_Phone__c : null;}
    	 }
    	 public String StartDate {
    		get{return (itinerarySf != null && itinerarySf.Start_Date__c != null) ? itinerarySf.Start_Date__c.format() : null;}
    	 }
    	 public boolean getReadOnly() {
    		return (itinerarySf != null) ? itinerarySf.Read_Only__c : null;
    	 }
    	 public String WorkPhone {
    		get{return (itinerarySf != null) ? itinerarySf.Work_Phone__c : null;}
    	 }
	}

	public Travel_Itinerary_Print_Controller_Ext(){
		Map<Id,Travel_Itinerary__c> studentItineraryMap = new Map<Id,Travel_Itinerary__c>();
			
		FlightList = new List<ItineraryWrapperDTO>();
		OtherList = new List<ItineraryWrapperDTO>();
		AccommodationsList = new List<ItineraryWrapperDTO>();
			
	if (travelId!=null){
				
			Travel_Registry__c thisTrip = [SELECT Id, recordType.Name, person_travelling__r.Id, person_travelling__r.name, Trip_Name__c from Travel_Registry__c where Id = :travelId limit 1];
			if(thisTrip.Trip_Name__c != null){
				TripName = thisTrip.Trip_Name__c;					
			}			
			
			List<Travel_Itinerary__c> StudentItinerary = [SELECT Id, Overnight_Flight__c, RecordType.DeveloperName, Accommodations_Type__c, Airline__c, Arrival_Airport_Code__c, Arrival_Airport_Code_Lookup__c, Arrival_City__c, City__c, Country__c, Departure_Airport_Code__c, Departure_Airport_Code_Lookup__c, Departure_City__c, Display_Name__c, Edited_By_Student__c, End_Date__c, Flight_Number__c, Mobile_Phone__c, Nickname__c, Personal_Travel__c, Postal_Code__c, Primary_Phone__c, Read_Only__c, Start_Date__c, State_Province__c, Status__c, Street_1__c, Street_2__c, Street_3__c, Work_Phone__c, travel_registry__r.travel_type__c FROM Travel_Itinerary__c where travel_registry__r.Id = :travelId];
			if(StudentItinerary.size()>0){
				for(Travel_Itinerary__c si : StudentItinerary){
					studentItineraryMap.put(si.Id,si);
					
					if(si.RecordType.DeveloperName == 'Flight'){
							FlightList.add(new ItineraryWrapperDTO(si));
					}else if(si.RecordType.DeveloperName == 'Rail' || si.RecordType.DeveloperName == 'Boat' || si.RecordType.DeveloperName == 'Bus' || si.RecordType.DeveloperName == 'Car' || si.RecordType.DeveloperName == 'Other'){
							OtherList.add(new ItineraryWrapperDTO(si));
					}else if(si.RecordType.DeveloperName == 'Accommodations'){
							AccommodationsList.add(new ItineraryWrapperDTO(si));
					}
				}
			}
		}
	}
}

 Any help or guidance you can give me is greatly appreciated!

 

Best Answer chosen by Admin (Salesforce Developers) 
SoozeeSoozee

I was able to resolve this issue with the help of Salesforce support.

 

There was a <apex:inputField> tag in my component that I had to remove in order to make it work.

The inputfield requires the <apex:form> tag, but the email template cannot contain the apex:form tag.

All Answers

nbknbk

can you confirm on below queries

Is the issue coming while saving the email template (compilation)?

 

The code you written have no mistakes. can you change api version and Encoding format..of the email template and save the template

SoozeeSoozee

Yes, I get the error when I try to save the Email Template.

 

I will try to change API.  Not sure how to change encoding format?

SoozeeSoozee

Updated API to 29.0 and changed encoding to UTF, but I am still getting the errors.

 

Thanks for your help!

SoozeeSoozee

I was able to resolve this issue with the help of Salesforce support.

 

There was a <apex:inputField> tag in my component that I had to remove in order to make it work.

The inputfield requires the <apex:form> tag, but the email template cannot contain the apex:form tag.

This was selected as the best answer