• SCR
  • NEWBIE
  • 25 Points
  • Member since 2009

  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 9
    Questions
  • 25
    Replies

Hi - I have a Sites Page that the style in the Coposition Template is inconsistentlly applied.  When you first goto the Sites Home the styles are not applied, but when you use the search form to return some results the style is applied.  This happens in all of the related Sites Pages. Any ideas?

 

Thanks in advance. SCR

 

Sites VF Markup Home Page:

<apex:page showheader="false" action="{!initList}" controller="PublicJobSearchController" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <!-- Search by Department, Location and Keyword --> <apex:pageBlock title="Search Job Postings"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:outputText value="Department"/> <apex:selectList value="{!viewDepartmentName}" id="departmentViews" size="1" required="true"> <apex:selectOptions value="{!DepartmentViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Location"/> <apex:selectList value="{!viewLocationName}" id="locationViews" size="1" required="true"> <apex:selectOptions value="{!LocationViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Keyword"/> <apex:inputText value="{!searchPosition}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value=""/> <apex:commandButton value="Search" action="{!PopulateQuery}" reRender="JobList" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <!-- Search results --> <apex:pageBlock title="Search Results"> <apex:pageBlockTable id="JobList" value="{!Position}" var="Position__c" rendered="{!NOT(ISNULL(Position))}"> <apex:column > <apex:facet name="header"> <apex:outputText value="Position ID"/> </apex:facet> <apex:outputLink value="PublicJobDetails?id={!Position__c.id}" id="theLink">{!Position__c.name}</apex:outputLink> <!-- Position name field is linked to the job details page --> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Title"/> </apex:facet> <apex:outputText value="{! Position__c.Position_Type__r.Name}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Department"/> </apex:facet> <apex:outputText value="{!Position__c.Department__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Location"/> </apex:facet> <apex:outputText value="{!Position__c.Location_City_State_Country__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Job Description"/> </apex:facet> <apex:outputText value="{!Position__c.Job_Description__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Position Open Date"/> </apex:facet> <apex:outputText value="{!Position__c.Open_Position_Date__c}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:define> </apex:composition> </apex:page>

 

  • August 10, 2009
  • Like
  • 0

Hello - I am trying to figure out a way to check if a custom object record already exists or not when a Sites user either registers or logs into the Sites Page and attempts to create a new record (in this case Job Application).  The Custom Object is Candidate, and I want to accompish two things:

 

1) Check for an existing Candidate record in force.com based on the email address prompted for in the Job Application form (or perhaps the Username in the registration form); or

 

2) Allow a registered user to login and create a new Job Application record in force.com using their existing Candidate record (if they already applied for another position).

 

Currently a registered user can apply for a job position.  However, if the same user comes back to the site, logs in and applies for another position then a new Candidate record is created.  I would like to check if a Candidate record already exists and return all of the existing Candidate fields so as to avoid duplicate records and unnecessary data input.

 

Any help is greatly appreciated.

- SCR

 

The Controller Extension for the PublicJobApplication as it exists:

public class PublicJobApplicationExtension { // This controller extends the standard controller // overwrites the actions // creates a candidate record // creates attachment on the candidate record based on the uploaded file // creates a job application record that links the candidate record and the related position private final Candidate__c candidate; private ID positionid = ApexPages.currentPage().getParameters().get('jobid'); private Job_Application__c jobapplication {get; private set;} public Blob resume {get; set;} public String contentType {get; set;} public String fileName {get; set;} // Extends the standard controller for the candidate object public PublicJobApplicationExtension(ApexPages.StandardController stdController) { candidate = (Candidate__c)stdController.getRecord(); } public Position__c getPosition() { return [SELECT id, name, Position_type__r.Name, Job_Description__c FROM Position__c WHERE id = :positionid]; } public PageReference saveApplication() { // Creates the candidate record try { insert(candidate); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } jobapplication = new Job_Application__c(); jobapplication.Candidate__c = candidate.id; jobapplication.Position__c = positionid; // Creates an attachment to the candidate record if a resume file is uploaded if (resume != null) { Attachment attach = new Attachment(); attach.Body = resume; attach.Name = fileName; attach.ContentType = contentType; attach.ParentId = candidate.id; try { insert(attach); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } } // Creates the job application record to link the candidate and the related position try { insert(jobapplication); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } PageReference p = Page.PublicJobApplicationConfirmation; p.setRedirect(true); return p; } }

 

  • August 08, 2009
  • Like
  • 0
 

Hello all,

 

I am developing a related set of external VisualForce Site Pages, Job Search, Job Detail and New Job Application for a recruiting app.  The Pages functioned as expected when configured as external Sites Pages (without any user authentication).  When I configure them to be accessed via the Customer Portal/Sites with user registration required it fails to render any column data in either the Job Search results except for the first column of data when successfully logged into the site.  The first column of data is the Job Position ID (which is the Position__c.Name field in force.com rendered in VF as an apex:outputLink tag) which is also the Link to the Job Detail record for each item in the list view.  Similarly, even though you can click on the Job Position ID link and get to the Job Detail Page (and record), the only column data that in the result is again the Job Position ID.

 

Results for the Active Site Home Page with Customer Portal/Sites and user registration required

 

There are 6 columns defined in the VF markup for the Job Search Page (VF name: PublicJobs) for the Search Results Page Block Table and all 6 column headers appear across the first row in the following order (bolded headers denote their appearance in the Page):

 

Search Results (Page Block Title)

 

Position ID | Title | Department | Location | Job Description | Position Open Date

    ^

theLink

(the only

column

with data)

 

There are 10 columns defined in the VF markup for the Job Detail Page (VF name: PublicJobDetail) for the Job Detail Page Block Section and only 2 of the 10 appear as headers right aligned under the first column in the following order (bolded headers denote their appearance in the Page):

 

Job Detail (

Information

 

Position ID

Read ONLY TEXT  (the only column with data)

Location City/State/Country

READ ONLY TEXT

Position Type Name

READ ONLY TEXT

Department

READ ONLY TEXT

Start Date

READ ONLY TEXT

Programming Languages

READ ONLY TEXT

Job Description

READ ONLY TEXT

Responsibilities

READ ONLY TEXT

Educational Requirements

READ ONLY TEXT

 

Results for the Active Site Home Page without Customer Portal/Sites

 

All 6 column headers appear across the first row and all of the data expected is rendered (e.g. below)

 

Search Results (Page Block Title)

 

Position ID | Title | Department | Location | Job Description | Position Open Date

 

The expected Data for all columns and all records is returned in the Search Results

 

All 10 columns appear as headers right aligned under the first column and all of the data expected is rendered (e.g. below):

 

Position ID

All Expected Data in READ ONLY TEXT

Location City/State/Country

All Expected Data in READ ONLY TEXT

Position Type Name

All Expected Data in READ ONLY TEXT

Department

All Expected Data in READ ONLY TEXT

Start Date

All Expected Data in READ ONLY TEXT

Programming Languages

All Expected Data in READ ONLY TEXT

Job Description

All Expected Data in READ ONLY TEXT

Responsibilities

All Expected Data in READ ONLY TEXT

Educational Requirements

All Expected Data in READ ONLY TEXT

 

I have checked (and rechecked) the Public Access and other Settings for the Site Pages, as well as the Assigned Profile Settings for the Customer Portal to make sure the Customer Portal User Profile is Assigned and that the Objects are visible in the Customer Portal, etc.  Please see the related VF Sites Pages code below.  Any suggestions or help is greatly appreciated.  I have spent much time trying to figure this out before resorting to this post.  I am a newbie at Sites, so please be gentle.

 

Thanks,

SCR

 

VF and Apex Controller Code

 

PublicJobs VF Markup:

 

<apex:page showheader="false" action="{!initList}" controller="PublicJobSearchController" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <!-- Search by Department, Location and Keyword --> <apex:pageBlock title="Search Job Postings"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:outputText value="Department"/> <apex:selectList value="{!viewDepartmentName}" id="departmentViews" size="1" required="true"> <apex:selectOptions value="{!DepartmentViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Location"/> <apex:selectList value="{!viewLocationName}" id="locationViews" size="1" required="true"> <apex:selectOptions value="{!LocationViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Keyword"/> <apex:inputText value="{!searchPosition}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value=""/> <apex:commandButton value="Search" action="{!PopulateQuery}" reRender="JobList" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <!-- Search results --> <apex:pageBlock title="Search Results"> <apex:pageBlockTable id="JobList" value="{!Position}" var="Position__c" rendered="{!NOT(ISNULL(Position))}"> <apex:column > <apex:facet name="header"> <apex:outputText value="Position ID"/> </apex:facet> <apex:outputLink value="PublicJobDetails?id={!Position__c.id}" id="theLink">{!Position__c.name}</apex:outputLink> <!-- Position name field is linked to the job details page --> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Title"/> </apex:facet> <apex:outputText value="{! Position__c.Position_Type__r.Name}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Department"/> </apex:facet> <apex:outputText value="{!Position__c.Department__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Location"/> </apex:facet> <apex:outputText value="{!Position__c.Location_City_State_Country__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Job Description"/> </apex:facet> <apex:outputText value="{!Position__c.Job_Description__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Position Open Date"/> </apex:facet> <apex:outputText value="{!Position__c.Open_Position_Date__c}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:define> </apex:composition> </apex:page>

 

PublicJobDetails VF Markup:

<apex:page showheader="false" action="{!initList}" controller="PublicJobSearchController" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <!-- Search by Department, Location and Keyword --> <apex:pageBlock title="Search Job Postings"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:outputText value="Department"/> <apex:selectList value="{!viewDepartmentName}" id="departmentViews" size="1" required="true"> <apex:selectOptions value="{!DepartmentViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Location"/> <apex:selectList value="{!viewLocationName}" id="locationViews" size="1" required="true"> <apex:selectOptions value="{!LocationViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Keyword"/> <apex:inputText value="{!searchPosition}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value=""/> <apex:commandButton value="Search" action="{!PopulateQuery}" reRender="JobList" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <!-- Search results --> <apex:pageBlock title="Search Results"> <apex:pageBlockTable id="JobList" value="{!Position}" var="Position__c" rendered="{!NOT(ISNULL(Position))}"> <apex:column > <apex:facet name="header"> <apex:outputText value="Position ID"/> </apex:facet> <apex:outputLink value="PublicJobDetails?id={!Position__c.id}" id="theLink">{!Position__c.name}</apex:outputLink> <!-- Position name field is linked to the job details page --> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Title"/> </apex:facet> <apex:outputText value="{! Position__c.Position_Type__r.Name}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Department"/> </apex:facet> <apex:outputText value="{!Position__c.Department__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Location"/> </apex:facet> <apex:outputText value="{!Position__c.Location_City_State_Country__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Job Description"/> </apex:facet> <apex:outputText value="{!Position__c.Job_Description__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Position Open Date"/> </apex:facet> <apex:outputText value="{!Position__c.Open_Position_Date__c}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:define> </apex:composition> </apex:page>

SiteRegisterController Apex Class:

 

/** * An apex class that creates a portal user */ public class SiteRegisterController { // PORTAL_ACCOUNT_ID is the account on which the contact will be created on and then enabled as a portal user. // you need to add the account owner into the role hierarchy before this will work - please see Customer Portal Setup help for more information. private static Id PORTAL_ACCOUNT_ID = '0018000000V7oup'; public SiteRegisterController () { } public String username {get; set;} public String email {get; set;} public String password {get; set {password = value == null ? value : value.trim(); } } public String confirmPassword {get; set { confirmPassword = value == null ? value : value.trim(); } } public String communityNickname {get; set { communityNickname = value == null ? value : value.trim(); } } private boolean isValidPassword() { return password == confirmPassword; } public PageReference registerUser() { // it's okay if password is null - we'll send the user a random password in that case if (!isValidPassword()) { ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, Label.site.passwords_dont_match); ApexPages.addMessage(msg); return null; } User u = new User(); u.Username = username; u.Email = email; u.CommunityNickname = communityNickname; String accountId = PORTAL_ACCOUNT_ID; // lastName is a required field on user, but if it isn't specified, we'll default it to the username String userId = Site.createPortalUser(u, accountId, password); if (userId != null) { if (password != null && password.length() > 1) { return Site.login(username, password, null); } else { PageReference page = System.Page.SiteRegisterConfirm; page.setRedirect(true); return page; } } return null; } // Test method to bring this class's test coverage over the required 75% static testMethod void testRegistration() { SiteRegisterController controller = new SiteRegisterController(); controller.username = 'test@force.com'; controller.email = 'test@force.com'; controller.communityNickname = 'test'; // registerUser will always return null when the page isn't accessed as a guest user System.assert(controller.registerUser() == null); controller.password = 'abcd1234'; controller.confirmPassword = 'abcd123'; System.assert(controller.registerUser() == null); } }

 

  • August 03, 2009
  • Like
  • 0

I've got a VS Sites Page (PublicJobs) that links to a VS Sites Detail Page (PublicJobsDetails) when you click on the link for a selected item within a list, which then presents the detail for the selected item and provides an 'Apply' button that should direct you to another VS Sites Page (PublicJobApplication) to apply for the job poisiton selected.  The initial VS Sites Page (PublicJobs) renders no problem, as does the VS Sites Page (PublicJobDetails) it links to.  But I get the following error Page when I click the 'Apply' button on the Job Details Page:

 

  
Page Not Found: %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PublicJobApplication

 

Also very odd is that the URL in the addrress bar of the browser (in this case Fire Fox) has a gap in the string when this error Page is rendered:

 

http://stratasaas-developer-edition.na6.force.com/              PublicJobApplication?jobid=a018000000Mf2euAAB

 

Any help resolving this would be greatly appreciated.  Thanks in advance.  Code info below.

 

Code fragment in the VS Sites Page (PublicJobDetails) linking the PublicJobApplication VS Sites Page via a command button:

 

<apex:pageBlockButtons > <!-- Apply button linked to the job application page --> <apex:commandButton value="Apply" onclick="window.top.location='{!$Site.Prefix}/ PublicJobApplication?jobid={!Position__c.Id}'; return false;"/> </apex:pageBlockButtons>

 

VS Sites Page markup for PublicJobApplication:

 

<!-- This page uses the standard controller and extends it to overwrite the action buttons and file upload --> <apex:page standardController="Candidate__c" extensions="PublicJobApplicationExtension" title="Job Application" showHeader="false" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <apex:sectionHeader title="" subtitle="{!Position.name}"/> <!-- Breadcrum link back to the job details page --> <apex:commandLink value="<- Back to Job Details" onclick="top.history.go(-1);return false;" /> <!-- section to display the error mesages --> <apex:messages id="error" styleClass="errorMsg" layout="table" style="margin-top:1em;"/> <apex:pageBlock title="Job Application Form" mode="edit"> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!saveApplication}"/> <apex:commandButton value="Cancel" onclick="top.history.go(-1);return false;"/> </apex:pageBlockButtons> <!-- Job information in read only --> <apex:pageBlockSection title="Job Information" collapsible="false" columns="1"> <apex:outputField value="{!Position.name}"/> <apex:outputField value="{!Position.Position_type__r.Name}"/> <apex:outputField value="{!Position.Job_Description__c}" /> </apex:pageBlockSection> <!-- Candidate information editable--> <apex:pageBlockSection title="Candidate Information" collapsible="false" columns="1"> <apex:inputField value="{!Candidate__c.First_Name__c}"/> <apex:inputField value="{!Candidate__c.Last_Name__c}"/> <apex:inputField value="{!Candidate__c.Address__c}"/> <apex:inputField value="{!Candidate__c.City__c}"/> <apex:inputField value="{!Candidate__c.State_Province__c}"/> <apex:inputField value="{!Candidate__c.Postal_Code__c}"/> <apex:inputField value="{!Candidate__c.Country__c}"/> <apex:inputField value="{!Candidate__c.Email__c}"/> <apex:inputField value="{!Candidate__c.Phone__c}"/> <apex:inputField value="{!Candidate__c.Mobile__c}"/> <apex:inputField value="{!Candidate__c.Education__c}"/> <apex:inputField value="{!Candidate__c.Current_Employer__c}"/> <!-- Field to upload candidate resume --> <apex:pageBlockSectionItem > Upload your resume <apex:inputFile accept="doc, txt, pdf" filename="{!fileName}" contentType="{!contentType}" filesize="1000" size="50" value="{!resume}"/> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:define> </apex:composition> </apex:page>

 

VS Site Page Controller Extension:

 

public class PublicJobApplicationExtension { // This controller extends the standard controller // overwrites the actions // creates a candidate record // creates attachment on the candidate record based on the uploaded file // creates a job application record that links the candidate record and the related position private final Candidate__c candidate; private ID positionid = ApexPages.currentPage().getParameters().get('jobid'); private Job_Application__c jobapplication {get; private set;} public Blob resume {get; set;} public String contentType {get; set;} public String fileName {get; set;} // Extends the standard controller for the candidate object public PublicJobApplicationExtension(ApexPages.StandardController stdController) { candidate = (Candidate__c)stdController.getRecord(); } public Position__c getPosition() { return [SELECT id, name, Position_type__r.Name, Job_Description__c FROM Position__c WHERE id = :positionid]; } public PageReference saveApplication() { // Creates the candidate record try { insert(candidate); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } jobapplication = new Job_Application__c(); jobapplication.Candidate__c = candidate.id; jobapplication.Position__c = positionid; // Creates an attachment to the candidate record if a resume file is uploaded if (resume != null) { Attachment attach = new Attachment(); attach.Body = resume; attach.Name = fileName; attach.ContentType = contentType; attach.ParentId = candidate.id; try { insert(attach); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } } // Creates the job application record to link the candidate and the related position try { insert(jobapplication); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } PageReference p = Page.PublicJobApplicationConfirmation; p.setRedirect(true); return p; } }

 

  • July 30, 2009
  • Like
  • 0

Hello - I am working on the Developer Guide project and exercises and I'm not able to see one of the custom objects that I created which is housing data.  The project calls for building a custom application, the Recruiting App, for Universal Containers (the fictitious company).  There are 3 related objects that are the subject of my problems.  The Job Application object is a custom object that is a junction object between the Candidate and Position objects, which are Master Objects for the Job Application object.  Though I can see all of the object information for Job Application object through the Setup menu, it does not show up at all in the Apex Explorer or Force.com IDE Schema viewer.  I use the Apex Explorer and the Eclipse Force.com IDE to build and test SOQL queries and find fields and relationships I need to access in Apex Classes.  Is there some setting that some how got set to hide this information?  OR does anyone have any idea how I can resolve it? 

 

Additional information... I have followed the Load Instructions from the Code Share for this project for every chapter, which involves running an Ant Based Force.com Migration tool to load files and packages into the Force.com application before every chapter.  I found and fixed several unpublished errors with this Code Share project.  It seems to function fine in every other way, except I cannot see the Job Application relationship and fields from the Candidate and Position objects. Any help is greatly appreciated. Thanks,SCR

 

Message Edited by SCR on 07-25-2009 07:55 PM
Message Edited by SCR on 07-25-2009 07:57 PM
  • July 26, 2009
  • Like
  • 0

Hello - I am getting the following error when attempting to Save a record using a VisualForce Page (VisualForcExtension) and a Controller Extension (positionExtension):

 

System.NullPointerException: Attempt to de-reference a null object

                                                                                                                                                   

Class.positionExtension.Save: line 54, column 16 External entry point (line 54 column 16 is underlined in the following code fragment "return theController.save()")

 

The code from the positionExtension Apex Class:

public class positionExtension { public string positionTypeID {get; set;} public positionExtension(ApexPages.StandardController positionController) { this.position = (Position__c)positionController.getRecord(); } public List<selectOption> PositionTypeOptions {get { List<selectOption> positionTypes = new List<selectOption>(); for (Position_Type__c ptr : [select name from Position_Type__c pt where pt.Department__c = :position.Department__c order by Name ]) positionTypes.add(new selectOption(ptr.id, ptr.name)); if (position.Department__c != null) { positionTypes.add(new selectOption('other', 'Other')); } else { positionTypes.add(new selectOption('', 'Please select a department', true)); } return positionTypes; } private set;} public Position_Type__c newPositionType{ get{ if (newPositionType == null) { newPositionType = new Position_Type__c();} return newPositionType; } private set; } public void resetPositionType() { positionTypeID = null; } public PageReference Save() { if (positionTypeID == 'other') { try{ newPositionType.Department__c = position.Department__c; insert newPositionType; position.Position_Type__c = newPositionType.ID; } catch (DmlException e) { ApexPages.addMessages(e); } } else { position.Position_Type__c = positionTypeID; } return theController.save(); } private final Position__c position; private final ApexPages.StandardController theController; }

The markup from the Visualforce Page that calls the Apex Class:

 

<apex:page standardController="Position__c" extensions="positionExtension" > <apex:form > <apex:sectionHeader title="Add New Position"/> <apex:pageBlock mode="edit" id="thePageBlock"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}"/> </apex:pageBlockButtons> <apex:pageBlocksection title="Information"> <apex:inputField value="{!Position__c.Location__c}"/> <apex:inputField value="{!Position__c.Hiring_Manager__c}"/> <apex:inputField value="{!Position__c.Status__c}"/> <apex:inputField value="{!Position__c.Notification__c}"/> <apex:inputField value="{!Position__c.Start_Date__c}"/> </apex:pageBlocksection> <apex:actionRegion > <apex:pageblocksection columns="1" title="Department"> <apex:inputField value="{!Position__c.Department__c}"> <apex:actionSupport event="onchange" rerender="dependentPositionType" action="{!resetPositionType}" status="departmentStatus"/> <apex:actionStatus id="departmentStatus" startText="Fetching position types..."/> </apex:inputField> </apex:pageblockSection> </apex:actionRegion> <apex:pageblockSection id="dependentPositionType" columns="1"> <apex:pageBlockSectionItem > <apex:outputLabel value="Position Type" for="pt"/> <apex:panelGrid columns="2"> <apex:actionRegion > <apex:outputText value="{!Position__c.Position_Type__c}" rendered="false"/> <apex:selectList id="pt" value="{!positionTypeID}" size="1" disabled="{!ISNULL(Position__c.Department__c)}"> <apex:selectOptions value="{!PositionTypeOptions}"/> <apex:actionSupport event="onchange" rerender="dependentPositionType" status="typeStatus"/> </apex:selectList> </apex:actionRegion> <apex:actionStatus id="typeStatus" startText="updating form..."> <apex:facet name="stop"> <apex:inputField value="{!newPositionType.Name}" rendered="{!positionTypeId == 'other'}" required="true"/> </apex:facet> </apex:actionStatus> </apex:panelGrid> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Position Details"> <apex:inputField value="{!Position__c.Job_Description__c}"/> <apex:inputField value="{!Position__c.Responsibilities__c}"/> <apex:inputField value="{!Position__c.Programming_Languages__c}"/> <apex:inputField value="{!Position__c.Educational_Requirements__c}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

I would appreciate any ideas for resolving this problem.  Please go easy on newbie learning VF and Apex.

 

Thanks,

SCR

  • July 23, 2009
  • Like
  • 0

Hello - I am getting the following error when attempting to Save a record using a VisualForce Page (VisualForcExtension) and a Controller Extension (positionExtension):

 

System.NullPointerException: Attempt to de-reference a null object

                                                                                                                                                   

Class.positionExtension.Save: line 54, column 16 External entry point (line 54 column 16 is underlined in the following code fragment "return theController.save()";)

 

public class positionExtension { public string positionTypeID {get; set;} public positionExtension(ApexPages.StandardController positionController) { this.position = (Position__c)positionController.getRecord(); } public List<selectOption> PositionTypeOptions {get { List<selectOption> positionTypes = new List<selectOption>(); for (Position_Type__c ptr : [select name from Position_Type__c pt where pt.Department__c = :position.Department__c order by Name ]) positionTypes.add(new selectOption(ptr.id, ptr.name)); if (position.Department__c != null) { positionTypes.add(new selectOption('other', 'Other')); } else { positionTypes.add(new selectOption('', 'Please select a department', true)); } return positionTypes; } private set;} public Position_Type__c newPositionType{ get{ if (newPositionType == null) { newPositionType = new Position_Type__c();} return newPositionType; } private set; } public void resetPositionType() { positionTypeID = null; } public PageReference Save() { if (positionTypeID == 'other') { try{ newPositionType.Department__c = position.Department__c; insert newPositionType; position.Position_Type__c = newPositionType.ID; } catch (DmlException e) { ApexPages.addMessages(e); } } else { position.Position_Type__c = positionTypeID; } return theController.save(); } private final Position__c position; private final ApexPages.StandardController theController; }

 

The markup from the Visualforce Page that calls the Apex Class:

 

<apex:page standardController="Position__c" extensions="positionExtension" > <apex:form > <apex:sectionHeader title="Add New Position"/> <apex:pageBlock mode="edit" id="thePageBlock"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}"/> </apex:pageBlockButtons> <apex:pageBlocksection title="Information"> <apex:inputField value="{!Position__c.Location__c}"/> <apex:inputField value="{!Position__c.Hiring_Manager__c}"/> <apex:inputField value="{!Position__c.Status__c}"/> <apex:inputField value="{!Position__c.Notification__c}"/> <apex:inputField value="{!Position__c.Start_Date__c}"/> </apex:pageBlocksection> <apex:actionRegion > <apex:pageblocksection columns="1" title="Department"> <apex:inputField value="{!Position__c.Department__c}"> <apex:actionSupport event="onchange" rerender="dependentPositionType" action="{!resetPositionType}" status="departmentStatus"/> <apex:actionStatus id="departmentStatus" startText="Fetching position types..."/> </apex:inputField> </apex:pageblockSection> </apex:actionRegion> <apex:pageblockSection id="dependentPositionType" columns="1"> <apex:pageBlockSectionItem > <apex:outputLabel value="Position Type" for="pt"/> <apex:panelGrid columns="2"> <apex:actionRegion > <apex:outputText value="{!Position__c.Position_Type__c}" rendered="false"/> <apex:selectList id="pt" value="{!positionTypeID}" size="1" disabled="{!ISNULL(Position__c.Department__c)}"> <apex:selectOptions value="{!PositionTypeOptions}"/> <apex:actionSupport event="onchange" rerender="dependentPositionType" status="typeStatus"/> </apex:selectList> </apex:actionRegion> <apex:actionStatus id="typeStatus" startText="updating form..."> <apex:facet name="stop"> <apex:inputField value="{!newPositionType.Name}" rendered="{!positionTypeId == 'other'}" required="true"/> </apex:facet> </apex:actionStatus> </apex:panelGrid> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Position Details"> <apex:inputField value="{!Position__c.Job_Description__c}"/> <apex:inputField value="{!Position__c.Responsibilities__c}"/> <apex:inputField value="{!Position__c.Programming_Languages__c}"/> <apex:inputField value="{!Position__c.Educational_Requirements__c}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

I would appreciate any ideas for resolving this problem.  Please go easy on newbie learning VF and Apex.

 

Thanks,

SCR

  • July 23, 2009
  • Like
  • 0

I am new to Email Services and Apex and wanting to learn effective methods for testing classes that implement the Messaging.InboundEmailHandler.  Please refer me to any good material for learning test methods and best practices for conducting them.  Please see the class code (ProcessApplicant) and Initial Test method Apex Class.  I'm only getting 16% code coverage using the current test method.

 

Thanks,

SCR

/* * This class implements Message.InboundEmailHandler to accept inbound applications for a given position. * It results in a new Candidate (if one doesnt already exist) and Job Description record being created. * Any binary email attachments are automatically transfered to the Job Description as attachments on the Notes and Attachments related list. */ global class ProcessApplicant implements Messaging.InboundEmailHandler { private static final String PHONE_MATCH = 'Phone:'; global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope envelope) { // Indicates if the message processes successfully, permits an error response to be sent back to the user. Messaging.InboundEmailResult result = new Messaging.InboundEmailResult(); try { // Obtain the applicants name and the position they are applying for from the email. String firstName = email.fromname.substring(0,email.fromName.indexOf(' ')); String lastName = email.fromname.substring(email.fromName.indexOf(' ')); String positionName = email.subject; String emailBody = email.plainTextBody; String emailFrom = envelope.fromAddress; // Process the email information. processApplicantEmail(firstName, lastName, positionName, emailBody, emailFrom, email.binaryAttachments); // Success. result.success = true; } catch (Exception e) { // Return an email message to the user. result.success = false; result.message = 'An error occured processing your message. ' + e.getMessage(); } return result; } public static void processApplicantEmail(String firstName, String lastName, String positionName, String emailBody, String emailFrom, Messaging.InboundEmail.BinaryAttachment[] binaryAttachments) { // Obtain the applicants Phone number from the message body. integer phoneMatchIdx = emailBody.indexOf(PHONE_MATCH); if(phoneMatchIdx==-1) throw new ProcessApplicantException('Please state your phone number following Phone: in your message.'); String phoneNumber = emailBody.substring(phoneMatchIdx+PHONE_MATCH.length()); // Resolve the Id of the Position they are applying for. Id positionId; try { // Lookup the Position they are applying for by name. Position__c position = [select Id from Position__c where name = :positionName limit 1]; positionId = position.Id; } catch (Exception e) { // Record not found. throw new ProcessApplicantException('Sorry the position ' + positionName + ' does not currently exist.'); } // Candidate record for the applicant sending this email. Candidate__c candidate; try { // Attempt to read an existing Candidate by email address. Candidate__c[] candidates = [select Id from Candidate__c where email__c = :emailFrom]; candidate = candidates[0]; } catch (Exception e) { // Record not found, create a new Candidate record for this applicant. candidate = new Candidate__c(); candidate.email__c = emailFrom; candidate.first_name__c = firstName; candidate.last_name__c = lastName; candidate.phone__c = phoneNumber; insert candidate; } // Create the Job Application record. Job_Application__c jobApplication = new Job_Application__c(); jobApplication.Position__c = positionId; jobApplication.Candidate__c = candidate.id; insert jobApplication; // Store any email attachments and associate them with the Job Application record. if (binaryAttachments!=null && binaryAttachments.size() > 0) { for (integer i = 0 ; i < binaryAttachments.size() ; i++) { Attachment attachment = new Attachment(); attachment.ParentId = jobApplication.Id; attachment.Name = binaryAttachments[i].Filename; attachment.Body = binaryAttachments[i].Body; insert attachment; } } // Confirm receipt of the applicants email Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses( new String[] { emailFrom }); mail.setSubject('Your job application has been received'); mail.setPlainTextBody('Thank you for submitting your resume. Your application will be reviewed to determine if an interview will be scheduled.'); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } /* * Represents errors that have occured interpretting the incoming email message */ class ProcessApplicantException extends Exception { } }

 

 

//The ProcessApplicant Test: public class ProcessApplicantTest { public static testMethod void ProcessApplicantTest(){ System.debug('Im starting a method'); // Create a new email, envelope object and Attachment Messaging.InboundEmail email = new Messaging.InboundEmail(); Messaging.InboundEnvelope envelope = new Messaging.InboundEnvelope(); email.subject = 'test'; email.plainTextBody = 'Hello, this a test email body. for testing purposes only. Bye'; envelope.fromAddress = 'user@acme.com'; // setup controller object ProcessApplicant catcher = new ProcessApplicant(); catcher.handleInboundEmail(email, envelope); } }

 

  • July 21, 2009
  • Like
  • 0

I'm working my way (sequentially) through the Force.com Developer Guide and ran into a problem when I tried to run the ant script for Chapter 6.  I get the following command line error message(s):

 

BUILD FAILED:

 <<directory path info not included>>

 Failures:

tabs/Initialize_Users.tab(Initialize_Users):Not in package.xml

pages/initUsers.page(initUsers):<apex:pageBlockSectionItem> may have no more than two child components

 

Has anyone else seen this failure, or does nayone know of a fix or work-around?

 

Thanks,

SCR

 

  • June 30, 2009
  • Like
  • 0

Hello all,

 

   Was wondering if anyone out there knows of any free data loading tools (aside the standard SFDC data loader) that can replicate data and synching data, be able to schedule import/export jobs,  please let me know. Our organization exports and imports a very large amount of data on a quarterly basis, and we need a tool that can essentially automate this process. We tried IOD (Informatica on Demand) which was excellent, however since we are doing this just 4 times in the year, we could not justify the cost. I am curious to see if such a tool is out there. Any help would be greatly appreciated!

 

Thanks

 

Fahad

How can we compare Apex and OOPS ?
  • August 12, 2009
  • Like
  • 0

Hello - I am trying to figure out a way to check if a custom object record already exists or not when a Sites user either registers or logs into the Sites Page and attempts to create a new record (in this case Job Application).  The Custom Object is Candidate, and I want to accompish two things:

 

1) Check for an existing Candidate record in force.com based on the email address prompted for in the Job Application form (or perhaps the Username in the registration form); or

 

2) Allow a registered user to login and create a new Job Application record in force.com using their existing Candidate record (if they already applied for another position).

 

Currently a registered user can apply for a job position.  However, if the same user comes back to the site, logs in and applies for another position then a new Candidate record is created.  I would like to check if a Candidate record already exists and return all of the existing Candidate fields so as to avoid duplicate records and unnecessary data input.

 

Any help is greatly appreciated.

- SCR

 

The Controller Extension for the PublicJobApplication as it exists:

public class PublicJobApplicationExtension { // This controller extends the standard controller // overwrites the actions // creates a candidate record // creates attachment on the candidate record based on the uploaded file // creates a job application record that links the candidate record and the related position private final Candidate__c candidate; private ID positionid = ApexPages.currentPage().getParameters().get('jobid'); private Job_Application__c jobapplication {get; private set;} public Blob resume {get; set;} public String contentType {get; set;} public String fileName {get; set;} // Extends the standard controller for the candidate object public PublicJobApplicationExtension(ApexPages.StandardController stdController) { candidate = (Candidate__c)stdController.getRecord(); } public Position__c getPosition() { return [SELECT id, name, Position_type__r.Name, Job_Description__c FROM Position__c WHERE id = :positionid]; } public PageReference saveApplication() { // Creates the candidate record try { insert(candidate); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } jobapplication = new Job_Application__c(); jobapplication.Candidate__c = candidate.id; jobapplication.Position__c = positionid; // Creates an attachment to the candidate record if a resume file is uploaded if (resume != null) { Attachment attach = new Attachment(); attach.Body = resume; attach.Name = fileName; attach.ContentType = contentType; attach.ParentId = candidate.id; try { insert(attach); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } } // Creates the job application record to link the candidate and the related position try { insert(jobapplication); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } PageReference p = Page.PublicJobApplicationConfirmation; p.setRedirect(true); return p; } }

 

  • August 08, 2009
  • Like
  • 0
 

Hello all,

 

I am developing a related set of external VisualForce Site Pages, Job Search, Job Detail and New Job Application for a recruiting app.  The Pages functioned as expected when configured as external Sites Pages (without any user authentication).  When I configure them to be accessed via the Customer Portal/Sites with user registration required it fails to render any column data in either the Job Search results except for the first column of data when successfully logged into the site.  The first column of data is the Job Position ID (which is the Position__c.Name field in force.com rendered in VF as an apex:outputLink tag) which is also the Link to the Job Detail record for each item in the list view.  Similarly, even though you can click on the Job Position ID link and get to the Job Detail Page (and record), the only column data that in the result is again the Job Position ID.

 

Results for the Active Site Home Page with Customer Portal/Sites and user registration required

 

There are 6 columns defined in the VF markup for the Job Search Page (VF name: PublicJobs) for the Search Results Page Block Table and all 6 column headers appear across the first row in the following order (bolded headers denote their appearance in the Page):

 

Search Results (Page Block Title)

 

Position ID | Title | Department | Location | Job Description | Position Open Date

    ^

theLink

(the only

column

with data)

 

There are 10 columns defined in the VF markup for the Job Detail Page (VF name: PublicJobDetail) for the Job Detail Page Block Section and only 2 of the 10 appear as headers right aligned under the first column in the following order (bolded headers denote their appearance in the Page):

 

Job Detail (

Information

 

Position ID

Read ONLY TEXT  (the only column with data)

Location City/State/Country

READ ONLY TEXT

Position Type Name

READ ONLY TEXT

Department

READ ONLY TEXT

Start Date

READ ONLY TEXT

Programming Languages

READ ONLY TEXT

Job Description

READ ONLY TEXT

Responsibilities

READ ONLY TEXT

Educational Requirements

READ ONLY TEXT

 

Results for the Active Site Home Page without Customer Portal/Sites

 

All 6 column headers appear across the first row and all of the data expected is rendered (e.g. below)

 

Search Results (Page Block Title)

 

Position ID | Title | Department | Location | Job Description | Position Open Date

 

The expected Data for all columns and all records is returned in the Search Results

 

All 10 columns appear as headers right aligned under the first column and all of the data expected is rendered (e.g. below):

 

Position ID

All Expected Data in READ ONLY TEXT

Location City/State/Country

All Expected Data in READ ONLY TEXT

Position Type Name

All Expected Data in READ ONLY TEXT

Department

All Expected Data in READ ONLY TEXT

Start Date

All Expected Data in READ ONLY TEXT

Programming Languages

All Expected Data in READ ONLY TEXT

Job Description

All Expected Data in READ ONLY TEXT

Responsibilities

All Expected Data in READ ONLY TEXT

Educational Requirements

All Expected Data in READ ONLY TEXT

 

I have checked (and rechecked) the Public Access and other Settings for the Site Pages, as well as the Assigned Profile Settings for the Customer Portal to make sure the Customer Portal User Profile is Assigned and that the Objects are visible in the Customer Portal, etc.  Please see the related VF Sites Pages code below.  Any suggestions or help is greatly appreciated.  I have spent much time trying to figure this out before resorting to this post.  I am a newbie at Sites, so please be gentle.

 

Thanks,

SCR

 

VF and Apex Controller Code

 

PublicJobs VF Markup:

 

<apex:page showheader="false" action="{!initList}" controller="PublicJobSearchController" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <!-- Search by Department, Location and Keyword --> <apex:pageBlock title="Search Job Postings"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:outputText value="Department"/> <apex:selectList value="{!viewDepartmentName}" id="departmentViews" size="1" required="true"> <apex:selectOptions value="{!DepartmentViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Location"/> <apex:selectList value="{!viewLocationName}" id="locationViews" size="1" required="true"> <apex:selectOptions value="{!LocationViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Keyword"/> <apex:inputText value="{!searchPosition}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value=""/> <apex:commandButton value="Search" action="{!PopulateQuery}" reRender="JobList" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <!-- Search results --> <apex:pageBlock title="Search Results"> <apex:pageBlockTable id="JobList" value="{!Position}" var="Position__c" rendered="{!NOT(ISNULL(Position))}"> <apex:column > <apex:facet name="header"> <apex:outputText value="Position ID"/> </apex:facet> <apex:outputLink value="PublicJobDetails?id={!Position__c.id}" id="theLink">{!Position__c.name}</apex:outputLink> <!-- Position name field is linked to the job details page --> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Title"/> </apex:facet> <apex:outputText value="{! Position__c.Position_Type__r.Name}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Department"/> </apex:facet> <apex:outputText value="{!Position__c.Department__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Location"/> </apex:facet> <apex:outputText value="{!Position__c.Location_City_State_Country__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Job Description"/> </apex:facet> <apex:outputText value="{!Position__c.Job_Description__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Position Open Date"/> </apex:facet> <apex:outputText value="{!Position__c.Open_Position_Date__c}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:define> </apex:composition> </apex:page>

 

PublicJobDetails VF Markup:

<apex:page showheader="false" action="{!initList}" controller="PublicJobSearchController" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <!-- Search by Department, Location and Keyword --> <apex:pageBlock title="Search Job Postings"> <apex:pageBlockSection columns="1"> <apex:pageBlockSectionItem > <apex:outputText value="Department"/> <apex:selectList value="{!viewDepartmentName}" id="departmentViews" size="1" required="true"> <apex:selectOptions value="{!DepartmentViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Location"/> <apex:selectList value="{!viewLocationName}" id="locationViews" size="1" required="true"> <apex:selectOptions value="{!LocationViewNames}"/> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value="Keyword"/> <apex:inputText value="{!searchPosition}"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem > <apex:outputText value=""/> <apex:commandButton value="Search" action="{!PopulateQuery}" reRender="JobList" /> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <!-- Search results --> <apex:pageBlock title="Search Results"> <apex:pageBlockTable id="JobList" value="{!Position}" var="Position__c" rendered="{!NOT(ISNULL(Position))}"> <apex:column > <apex:facet name="header"> <apex:outputText value="Position ID"/> </apex:facet> <apex:outputLink value="PublicJobDetails?id={!Position__c.id}" id="theLink">{!Position__c.name}</apex:outputLink> <!-- Position name field is linked to the job details page --> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Title"/> </apex:facet> <apex:outputText value="{! Position__c.Position_Type__r.Name}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Department"/> </apex:facet> <apex:outputText value="{!Position__c.Department__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Location"/> </apex:facet> <apex:outputText value="{!Position__c.Location_City_State_Country__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Job Description"/> </apex:facet> <apex:outputText value="{!Position__c.Job_Description__c}"/> </apex:column> <apex:column > <apex:facet name="header"> <apex:outputText value="Position Open Date"/> </apex:facet> <apex:outputText value="{!Position__c.Open_Position_Date__c}"/> </apex:column> </apex:pageBlockTable> </apex:pageBlock> </apex:define> </apex:composition> </apex:page>

SiteRegisterController Apex Class:

 

/** * An apex class that creates a portal user */ public class SiteRegisterController { // PORTAL_ACCOUNT_ID is the account on which the contact will be created on and then enabled as a portal user. // you need to add the account owner into the role hierarchy before this will work - please see Customer Portal Setup help for more information. private static Id PORTAL_ACCOUNT_ID = '0018000000V7oup'; public SiteRegisterController () { } public String username {get; set;} public String email {get; set;} public String password {get; set {password = value == null ? value : value.trim(); } } public String confirmPassword {get; set { confirmPassword = value == null ? value : value.trim(); } } public String communityNickname {get; set { communityNickname = value == null ? value : value.trim(); } } private boolean isValidPassword() { return password == confirmPassword; } public PageReference registerUser() { // it's okay if password is null - we'll send the user a random password in that case if (!isValidPassword()) { ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.ERROR, Label.site.passwords_dont_match); ApexPages.addMessage(msg); return null; } User u = new User(); u.Username = username; u.Email = email; u.CommunityNickname = communityNickname; String accountId = PORTAL_ACCOUNT_ID; // lastName is a required field on user, but if it isn't specified, we'll default it to the username String userId = Site.createPortalUser(u, accountId, password); if (userId != null) { if (password != null && password.length() > 1) { return Site.login(username, password, null); } else { PageReference page = System.Page.SiteRegisterConfirm; page.setRedirect(true); return page; } } return null; } // Test method to bring this class's test coverage over the required 75% static testMethod void testRegistration() { SiteRegisterController controller = new SiteRegisterController(); controller.username = 'test@force.com'; controller.email = 'test@force.com'; controller.communityNickname = 'test'; // registerUser will always return null when the page isn't accessed as a guest user System.assert(controller.registerUser() == null); controller.password = 'abcd1234'; controller.confirmPassword = 'abcd123'; System.assert(controller.registerUser() == null); } }

 

  • August 03, 2009
  • Like
  • 0

I've got a VS Sites Page (PublicJobs) that links to a VS Sites Detail Page (PublicJobsDetails) when you click on the link for a selected item within a list, which then presents the detail for the selected item and provides an 'Apply' button that should direct you to another VS Sites Page (PublicJobApplication) to apply for the job poisiton selected.  The initial VS Sites Page (PublicJobs) renders no problem, as does the VS Sites Page (PublicJobDetails) it links to.  But I get the following error Page when I click the 'Apply' button on the Job Details Page:

 

  
Page Not Found: %20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PublicJobApplication

 

Also very odd is that the URL in the addrress bar of the browser (in this case Fire Fox) has a gap in the string when this error Page is rendered:

 

http://stratasaas-developer-edition.na6.force.com/              PublicJobApplication?jobid=a018000000Mf2euAAB

 

Any help resolving this would be greatly appreciated.  Thanks in advance.  Code info below.

 

Code fragment in the VS Sites Page (PublicJobDetails) linking the PublicJobApplication VS Sites Page via a command button:

 

<apex:pageBlockButtons > <!-- Apply button linked to the job application page --> <apex:commandButton value="Apply" onclick="window.top.location='{!$Site.Prefix}/ PublicJobApplication?jobid={!Position__c.Id}'; return false;"/> </apex:pageBlockButtons>

 

VS Sites Page markup for PublicJobApplication:

 

<!-- This page uses the standard controller and extends it to overwrite the action buttons and file upload --> <apex:page standardController="Candidate__c" extensions="PublicJobApplicationExtension" title="Job Application" showHeader="false" standardStylesheets="true"> <!-- The site template provides the layout and the style for the site --> <apex:composition template="{!$Site.Template}"> <apex:define name="body"> <apex:form > <apex:sectionHeader title="" subtitle="{!Position.name}"/> <!-- Breadcrum link back to the job details page --> <apex:commandLink value="<- Back to Job Details" onclick="top.history.go(-1);return false;" /> <!-- section to display the error mesages --> <apex:messages id="error" styleClass="errorMsg" layout="table" style="margin-top:1em;"/> <apex:pageBlock title="Job Application Form" mode="edit"> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!saveApplication}"/> <apex:commandButton value="Cancel" onclick="top.history.go(-1);return false;"/> </apex:pageBlockButtons> <!-- Job information in read only --> <apex:pageBlockSection title="Job Information" collapsible="false" columns="1"> <apex:outputField value="{!Position.name}"/> <apex:outputField value="{!Position.Position_type__r.Name}"/> <apex:outputField value="{!Position.Job_Description__c}" /> </apex:pageBlockSection> <!-- Candidate information editable--> <apex:pageBlockSection title="Candidate Information" collapsible="false" columns="1"> <apex:inputField value="{!Candidate__c.First_Name__c}"/> <apex:inputField value="{!Candidate__c.Last_Name__c}"/> <apex:inputField value="{!Candidate__c.Address__c}"/> <apex:inputField value="{!Candidate__c.City__c}"/> <apex:inputField value="{!Candidate__c.State_Province__c}"/> <apex:inputField value="{!Candidate__c.Postal_Code__c}"/> <apex:inputField value="{!Candidate__c.Country__c}"/> <apex:inputField value="{!Candidate__c.Email__c}"/> <apex:inputField value="{!Candidate__c.Phone__c}"/> <apex:inputField value="{!Candidate__c.Mobile__c}"/> <apex:inputField value="{!Candidate__c.Education__c}"/> <apex:inputField value="{!Candidate__c.Current_Employer__c}"/> <!-- Field to upload candidate resume --> <apex:pageBlockSectionItem > Upload your resume <apex:inputFile accept="doc, txt, pdf" filename="{!fileName}" contentType="{!contentType}" filesize="1000" size="50" value="{!resume}"/> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:define> </apex:composition> </apex:page>

 

VS Site Page Controller Extension:

 

public class PublicJobApplicationExtension { // This controller extends the standard controller // overwrites the actions // creates a candidate record // creates attachment on the candidate record based on the uploaded file // creates a job application record that links the candidate record and the related position private final Candidate__c candidate; private ID positionid = ApexPages.currentPage().getParameters().get('jobid'); private Job_Application__c jobapplication {get; private set;} public Blob resume {get; set;} public String contentType {get; set;} public String fileName {get; set;} // Extends the standard controller for the candidate object public PublicJobApplicationExtension(ApexPages.StandardController stdController) { candidate = (Candidate__c)stdController.getRecord(); } public Position__c getPosition() { return [SELECT id, name, Position_type__r.Name, Job_Description__c FROM Position__c WHERE id = :positionid]; } public PageReference saveApplication() { // Creates the candidate record try { insert(candidate); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } jobapplication = new Job_Application__c(); jobapplication.Candidate__c = candidate.id; jobapplication.Position__c = positionid; // Creates an attachment to the candidate record if a resume file is uploaded if (resume != null) { Attachment attach = new Attachment(); attach.Body = resume; attach.Name = fileName; attach.ContentType = contentType; attach.ParentId = candidate.id; try { insert(attach); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } } // Creates the job application record to link the candidate and the related position try { insert(jobapplication); } catch(System.DMLException e) { ApexPages.addMessages(e); return null; } PageReference p = Page.PublicJobApplicationConfirmation; p.setRedirect(true); return p; } }

 

  • July 30, 2009
  • Like
  • 0

I am creating a VF page on a standard controller. I'd like to create a button on the page that opens the new Record input screen (similar to the one on any tab home page). However, I can't find the correct action syntax for my commandButton.

 

Is this feature actually available for VF?

 

Many thanks,

Guy

Hi,

 

Is there any way I can migrate List Views to other sandbox or PROD org?

 

Thanks

 

Hello - I am working on the Developer Guide project and exercises and I'm not able to see one of the custom objects that I created which is housing data.  The project calls for building a custom application, the Recruiting App, for Universal Containers (the fictitious company).  There are 3 related objects that are the subject of my problems.  The Job Application object is a custom object that is a junction object between the Candidate and Position objects, which are Master Objects for the Job Application object.  Though I can see all of the object information for Job Application object through the Setup menu, it does not show up at all in the Apex Explorer or Force.com IDE Schema viewer.  I use the Apex Explorer and the Eclipse Force.com IDE to build and test SOQL queries and find fields and relationships I need to access in Apex Classes.  Is there some setting that some how got set to hide this information?  OR does anyone have any idea how I can resolve it? 

 

Additional information... I have followed the Load Instructions from the Code Share for this project for every chapter, which involves running an Ant Based Force.com Migration tool to load files and packages into the Force.com application before every chapter.  I found and fixed several unpublished errors with this Code Share project.  It seems to function fine in every other way, except I cannot see the Job Application relationship and fields from the Candidate and Position objects. Any help is greatly appreciated. Thanks,SCR

 

Message Edited by SCR on 07-25-2009 07:55 PM
Message Edited by SCR on 07-25-2009 07:57 PM
  • July 26, 2009
  • Like
  • 0

Hello - I am getting the following error when attempting to Save a record using a VisualForce Page (VisualForcExtension) and a Controller Extension (positionExtension):

 

System.NullPointerException: Attempt to de-reference a null object

                                                                                                                                                   

Class.positionExtension.Save: line 54, column 16 External entry point (line 54 column 16 is underlined in the following code fragment "return theController.save()")

 

The code from the positionExtension Apex Class:

public class positionExtension { public string positionTypeID {get; set;} public positionExtension(ApexPages.StandardController positionController) { this.position = (Position__c)positionController.getRecord(); } public List<selectOption> PositionTypeOptions {get { List<selectOption> positionTypes = new List<selectOption>(); for (Position_Type__c ptr : [select name from Position_Type__c pt where pt.Department__c = :position.Department__c order by Name ]) positionTypes.add(new selectOption(ptr.id, ptr.name)); if (position.Department__c != null) { positionTypes.add(new selectOption('other', 'Other')); } else { positionTypes.add(new selectOption('', 'Please select a department', true)); } return positionTypes; } private set;} public Position_Type__c newPositionType{ get{ if (newPositionType == null) { newPositionType = new Position_Type__c();} return newPositionType; } private set; } public void resetPositionType() { positionTypeID = null; } public PageReference Save() { if (positionTypeID == 'other') { try{ newPositionType.Department__c = position.Department__c; insert newPositionType; position.Position_Type__c = newPositionType.ID; } catch (DmlException e) { ApexPages.addMessages(e); } } else { position.Position_Type__c = positionTypeID; } return theController.save(); } private final Position__c position; private final ApexPages.StandardController theController; }

The markup from the Visualforce Page that calls the Apex Class:

 

<apex:page standardController="Position__c" extensions="positionExtension" > <apex:form > <apex:sectionHeader title="Add New Position"/> <apex:pageBlock mode="edit" id="thePageBlock"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}"/> </apex:pageBlockButtons> <apex:pageBlocksection title="Information"> <apex:inputField value="{!Position__c.Location__c}"/> <apex:inputField value="{!Position__c.Hiring_Manager__c}"/> <apex:inputField value="{!Position__c.Status__c}"/> <apex:inputField value="{!Position__c.Notification__c}"/> <apex:inputField value="{!Position__c.Start_Date__c}"/> </apex:pageBlocksection> <apex:actionRegion > <apex:pageblocksection columns="1" title="Department"> <apex:inputField value="{!Position__c.Department__c}"> <apex:actionSupport event="onchange" rerender="dependentPositionType" action="{!resetPositionType}" status="departmentStatus"/> <apex:actionStatus id="departmentStatus" startText="Fetching position types..."/> </apex:inputField> </apex:pageblockSection> </apex:actionRegion> <apex:pageblockSection id="dependentPositionType" columns="1"> <apex:pageBlockSectionItem > <apex:outputLabel value="Position Type" for="pt"/> <apex:panelGrid columns="2"> <apex:actionRegion > <apex:outputText value="{!Position__c.Position_Type__c}" rendered="false"/> <apex:selectList id="pt" value="{!positionTypeID}" size="1" disabled="{!ISNULL(Position__c.Department__c)}"> <apex:selectOptions value="{!PositionTypeOptions}"/> <apex:actionSupport event="onchange" rerender="dependentPositionType" status="typeStatus"/> </apex:selectList> </apex:actionRegion> <apex:actionStatus id="typeStatus" startText="updating form..."> <apex:facet name="stop"> <apex:inputField value="{!newPositionType.Name}" rendered="{!positionTypeId == 'other'}" required="true"/> </apex:facet> </apex:actionStatus> </apex:panelGrid> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Position Details"> <apex:inputField value="{!Position__c.Job_Description__c}"/> <apex:inputField value="{!Position__c.Responsibilities__c}"/> <apex:inputField value="{!Position__c.Programming_Languages__c}"/> <apex:inputField value="{!Position__c.Educational_Requirements__c}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

I would appreciate any ideas for resolving this problem.  Please go easy on newbie learning VF and Apex.

 

Thanks,

SCR

  • July 23, 2009
  • Like
  • 0

Hello - I am getting the following error when attempting to Save a record using a VisualForce Page (VisualForcExtension) and a Controller Extension (positionExtension):

 

System.NullPointerException: Attempt to de-reference a null object

                                                                                                                                                   

Class.positionExtension.Save: line 54, column 16 External entry point (line 54 column 16 is underlined in the following code fragment "return theController.save()";)

 

public class positionExtension { public string positionTypeID {get; set;} public positionExtension(ApexPages.StandardController positionController) { this.position = (Position__c)positionController.getRecord(); } public List<selectOption> PositionTypeOptions {get { List<selectOption> positionTypes = new List<selectOption>(); for (Position_Type__c ptr : [select name from Position_Type__c pt where pt.Department__c = :position.Department__c order by Name ]) positionTypes.add(new selectOption(ptr.id, ptr.name)); if (position.Department__c != null) { positionTypes.add(new selectOption('other', 'Other')); } else { positionTypes.add(new selectOption('', 'Please select a department', true)); } return positionTypes; } private set;} public Position_Type__c newPositionType{ get{ if (newPositionType == null) { newPositionType = new Position_Type__c();} return newPositionType; } private set; } public void resetPositionType() { positionTypeID = null; } public PageReference Save() { if (positionTypeID == 'other') { try{ newPositionType.Department__c = position.Department__c; insert newPositionType; position.Position_Type__c = newPositionType.ID; } catch (DmlException e) { ApexPages.addMessages(e); } } else { position.Position_Type__c = positionTypeID; } return theController.save(); } private final Position__c position; private final ApexPages.StandardController theController; }

 

The markup from the Visualforce Page that calls the Apex Class:

 

<apex:page standardController="Position__c" extensions="positionExtension" > <apex:form > <apex:sectionHeader title="Add New Position"/> <apex:pageBlock mode="edit" id="thePageBlock"> <apex:pageMessages /> <apex:pageBlockButtons > <apex:commandButton value="Save" action="{!save}"/> <apex:commandButton value="Cancel" action="{!cancel}"/> </apex:pageBlockButtons> <apex:pageBlocksection title="Information"> <apex:inputField value="{!Position__c.Location__c}"/> <apex:inputField value="{!Position__c.Hiring_Manager__c}"/> <apex:inputField value="{!Position__c.Status__c}"/> <apex:inputField value="{!Position__c.Notification__c}"/> <apex:inputField value="{!Position__c.Start_Date__c}"/> </apex:pageBlocksection> <apex:actionRegion > <apex:pageblocksection columns="1" title="Department"> <apex:inputField value="{!Position__c.Department__c}"> <apex:actionSupport event="onchange" rerender="dependentPositionType" action="{!resetPositionType}" status="departmentStatus"/> <apex:actionStatus id="departmentStatus" startText="Fetching position types..."/> </apex:inputField> </apex:pageblockSection> </apex:actionRegion> <apex:pageblockSection id="dependentPositionType" columns="1"> <apex:pageBlockSectionItem > <apex:outputLabel value="Position Type" for="pt"/> <apex:panelGrid columns="2"> <apex:actionRegion > <apex:outputText value="{!Position__c.Position_Type__c}" rendered="false"/> <apex:selectList id="pt" value="{!positionTypeID}" size="1" disabled="{!ISNULL(Position__c.Department__c)}"> <apex:selectOptions value="{!PositionTypeOptions}"/> <apex:actionSupport event="onchange" rerender="dependentPositionType" status="typeStatus"/> </apex:selectList> </apex:actionRegion> <apex:actionStatus id="typeStatus" startText="updating form..."> <apex:facet name="stop"> <apex:inputField value="{!newPositionType.Name}" rendered="{!positionTypeId == 'other'}" required="true"/> </apex:facet> </apex:actionStatus> </apex:panelGrid> </apex:pageBlockSectionItem> </apex:pageBlockSection> <apex:pageBlockSection title="Position Details"> <apex:inputField value="{!Position__c.Job_Description__c}"/> <apex:inputField value="{!Position__c.Responsibilities__c}"/> <apex:inputField value="{!Position__c.Programming_Languages__c}"/> <apex:inputField value="{!Position__c.Educational_Requirements__c}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>

 

I would appreciate any ideas for resolving this problem.  Please go easy on newbie learning VF and Apex.

 

Thanks,

SCR

  • July 23, 2009
  • Like
  • 0

I am new to Email Services and Apex and wanting to learn effective methods for testing classes that implement the Messaging.InboundEmailHandler.  Please refer me to any good material for learning test methods and best practices for conducting them.  Please see the class code (ProcessApplicant) and Initial Test method Apex Class.  I'm only getting 16% code coverage using the current test method.

 

Thanks,

SCR

/* * This class implements Message.InboundEmailHandler to accept inbound applications for a given position. * It results in a new Candidate (if one doesnt already exist) and Job Description record being created. * Any binary email attachments are automatically transfered to the Job Description as attachments on the Notes and Attachments related list. */ global class ProcessApplicant implements Messaging.InboundEmailHandler { private static final String PHONE_MATCH = 'Phone:'; global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope envelope) { // Indicates if the message processes successfully, permits an error response to be sent back to the user. Messaging.InboundEmailResult result = new Messaging.InboundEmailResult(); try { // Obtain the applicants name and the position they are applying for from the email. String firstName = email.fromname.substring(0,email.fromName.indexOf(' ')); String lastName = email.fromname.substring(email.fromName.indexOf(' ')); String positionName = email.subject; String emailBody = email.plainTextBody; String emailFrom = envelope.fromAddress; // Process the email information. processApplicantEmail(firstName, lastName, positionName, emailBody, emailFrom, email.binaryAttachments); // Success. result.success = true; } catch (Exception e) { // Return an email message to the user. result.success = false; result.message = 'An error occured processing your message. ' + e.getMessage(); } return result; } public static void processApplicantEmail(String firstName, String lastName, String positionName, String emailBody, String emailFrom, Messaging.InboundEmail.BinaryAttachment[] binaryAttachments) { // Obtain the applicants Phone number from the message body. integer phoneMatchIdx = emailBody.indexOf(PHONE_MATCH); if(phoneMatchIdx==-1) throw new ProcessApplicantException('Please state your phone number following Phone: in your message.'); String phoneNumber = emailBody.substring(phoneMatchIdx+PHONE_MATCH.length()); // Resolve the Id of the Position they are applying for. Id positionId; try { // Lookup the Position they are applying for by name. Position__c position = [select Id from Position__c where name = :positionName limit 1]; positionId = position.Id; } catch (Exception e) { // Record not found. throw new ProcessApplicantException('Sorry the position ' + positionName + ' does not currently exist.'); } // Candidate record for the applicant sending this email. Candidate__c candidate; try { // Attempt to read an existing Candidate by email address. Candidate__c[] candidates = [select Id from Candidate__c where email__c = :emailFrom]; candidate = candidates[0]; } catch (Exception e) { // Record not found, create a new Candidate record for this applicant. candidate = new Candidate__c(); candidate.email__c = emailFrom; candidate.first_name__c = firstName; candidate.last_name__c = lastName; candidate.phone__c = phoneNumber; insert candidate; } // Create the Job Application record. Job_Application__c jobApplication = new Job_Application__c(); jobApplication.Position__c = positionId; jobApplication.Candidate__c = candidate.id; insert jobApplication; // Store any email attachments and associate them with the Job Application record. if (binaryAttachments!=null && binaryAttachments.size() > 0) { for (integer i = 0 ; i < binaryAttachments.size() ; i++) { Attachment attachment = new Attachment(); attachment.ParentId = jobApplication.Id; attachment.Name = binaryAttachments[i].Filename; attachment.Body = binaryAttachments[i].Body; insert attachment; } } // Confirm receipt of the applicants email Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setToAddresses( new String[] { emailFrom }); mail.setSubject('Your job application has been received'); mail.setPlainTextBody('Thank you for submitting your resume. Your application will be reviewed to determine if an interview will be scheduled.'); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } /* * Represents errors that have occured interpretting the incoming email message */ class ProcessApplicantException extends Exception { } }

 

 

//The ProcessApplicant Test: public class ProcessApplicantTest { public static testMethod void ProcessApplicantTest(){ System.debug('Im starting a method'); // Create a new email, envelope object and Attachment Messaging.InboundEmail email = new Messaging.InboundEmail(); Messaging.InboundEnvelope envelope = new Messaging.InboundEnvelope(); email.subject = 'test'; email.plainTextBody = 'Hello, this a test email body. for testing purposes only. Bye'; envelope.fromAddress = 'user@acme.com'; // setup controller object ProcessApplicant catcher = new ProcessApplicant(); catcher.handleInboundEmail(email, envelope); } }

 

  • July 21, 2009
  • Like
  • 0