Now that you have the lay of land, you’ll explore three different examples of modifying the Project Guide. In the first example, you’ll replace the default “Specify people and equipment for the project” goal with a Microsoft Project Server– centric “Specify people and equipment from Microsoft Project Server,” including how to specify relevant views, and help files. In the second example, you’ll look at how to add a new goal area to the Project Guide. In the third and final customization example, you’ll create a goal task wizard, which shows you what you can accomplish with custom development work. You’ll work with Project Server embedded technologies, including the PDS, SOAP, XML, JavaScript, and Microsoft Project functions.
All files for these examples are available on the Web site for this book (http://www.projectserverexperts.com). You may also want to download the sample Project Guide files available in the article “Customizing the Microsoft Project Guide” in the Microsoft Project 2002 Software Development Kit (http://msdn.microsoft.com/library/en-us/pdr/PDR_Overview_3338.asp).
In this example, you change the default “Specify people and equipment for the project” goal with a Project Server–centric version. This will force Project Guide users to specify resources using the Build Team from Enterprise dialog box only.
Here are the steps required for changing or adding a goal to an existing goal area:
Modify the Project Guide XML content file.
Create a Web page for the goal task.
Create a Web page for the goal task help (if applicable).
Create scripts as needed for custom functionality.
Specify the Project Guide content file.
The first step in creating a custom Project Guide is to modify the Project Guide XML content file. The code for this example is shown in Listing 18-5.
Listing 18.5: Project Guide XML Content for the First Example
<GoalAreaTask> <TaskID> 11 </TaskID> <Title> Select Enterprise Resources </Title> <TaskName> Specify people and equipment from Microsoft Project Server </TaskName> <URL> file://C:\CustomPG\Project Server Book\EnterpriseTeamBuilder\EnterpriseTeamBuilder.htm </URL> <TaskHelp> <HelpName> More Information </HelpName> <URL> file://C:\CustomPG\Project Server Book\EnterpriseTeamBuilder\EnterpriseTeamBuilder_Help.htm </URL> </TaskHelp> <RelevantViews> <ViewType> 1 </ViewType> </RelevantViews> </GoalAreaTask>
Note | The URLs specified in Listing 18-5 are hard-coded to the local machine. Make sure to put the files in the same location or modify the URLs in the listing. |
I’ve covered all the items in Listing 18-5, so there shouldn’t be any surprises for you there. Pay attention to the note in this section that states files are hard-coded to the local machine in the example. You must put the files in the same location or modify the URLs in the code. When you deploy your customized Project Guide within an organization, you’ll most likely put these files on an internal Web server.
Note | Set the Web site holding the Project Guide pages as a Trusted Site in Internet Explorer. |
The code in Listing 18-6 presents an HTML page for the goal task. In this example are sections including the header, body header, task header, divMain section, and the divContent SidepaneData data section. I cover each of these in more detail in this section.
Listing 18.6: Enterprise Team Builder.htm
<html> <head> <meta http-equiv="content-type" content="text/html; charset=Windows-1252"> <script src="/books/2/89/1/html/2/file:\\C:\CustomPG\Project Server Book\EnterpriseTeamBuilder\EnterpriseTeamBuilder.js" language="JScript"> </script> <script src="/books/2/89/1/html/2/gbui://util.js" language="JScript"></script> <link rel="stylesheet" href="gbui://ProjIE.css" type="text/css" /> </head> <!-- The body should always have an onLoad call to handleResize() --> <body onLoad="handleResize(); setupView()"> <!-- Display the Task Header --> <script language="JScript"> // pDisplayTaskHeader should always be called before pSetupSidepane pDisplayTaskHeader(); pSetupSidepane(); </script> <div id=divMain onResize="handleResize();"> <div id=divContent > <p> Click the link below to bring up a list of all the resources on the Microsoft Project Server: </p> <p> <a href="#" onClick="EnterpriseTeamBuilder()"> Build Team from Enterprise...</a> </p> <p> In the dialog that is brought up, use filters to display the appropriate users, and click the <b>Add</b> button to add these users to the project. </p> <!-- Separator line --> <hr width=95% align=center> <p> <b>Generic Resources</b> </p> <p> If you are using generic resources in your templates, you might want to use the <b>Replace</b> button. Select the generic resource in the Project Team Resources list (right list) in the Build Team dialog. Then select the resource from the Enterprise Resource list (left list) who is to take over the work assigned to the generic resource. Finally, click the <b>Replace</b> button and the enterprise resource will now be assigned to all of the tasks previously assigned to the generic resource. </p> <p > <!-- pNavigate(goalAreaID, taskID, elementID) --> <!-- * goalAreaID - goal area to go back to --> <!-- * taskID - task ID to go back to (-1 for goal area menu) --> <!-- * elementID - 'GoBack' takes you back to the previous location --> <!-- In this instance we are going back to the Goal Area 2 main menu --> <a title="Done" href="#" onClick= "parent.navigate(2,-1,'GoBack')">Done</a> </p> <!-- Display the Task Footer --> <script language="JScript"> pDisplayTaskFooter(); </script> </div> <!--divContent - Sidepanedata--> </div> <!-- divMain --> </body> </html>
The header of the Enterprise Team Builder file provides some very important pointers to related files with needed functionality. The first script file is Enterprise Team Builder.js, which has the JavaScript functions necessary to implement behaviors for the Enterprise Team Builder goal task. The next file, Util.js, is a Project Guide file that provides several functions, such as displaying the task header and setting up the side pane. This file is included as part of the download for the Microsoft article “Customizing the Microsoft Project Guide” if you’d like to study this file in more detail. The final part of the header is a link to the ProjIE.css style sheet, which gives the Project Guide a consistent appearance.
The body section begins with an important call in the onLoad event. Call the <body onLoad="handleResize()"> event first in every Project Guide HTML file, as it handles any size changes to the Project Guide side pane. The call after handleResize() is setupView(), a function I created to change the view to the Resource Sheet. I cover this function call in the Enterprise Team Builder.js file. If you want code to run before the Web page loads, such as a customized data retrieval task, you put these function calls in the <body onLoad= event as well. The next call is pDisplayTaskHeader();, which displays the title and forward/backward buttons in the side pane header. The final function call in the top of the body section is pSetupSidePane();, which updates the Goal Bar based on the new content. The pDisplayTaskHeader(); function call should always be called before the pSetupSidePane(); function.
The divMain section of the HTML page applies to content in the main area of Microsoft Project. You put content in this section if you want to modify the content on the right or call a Web page in the main area. As I am primarily working with the side pane, I don’t have any calls in the divMain section.
The divContent section represents all of the information to be shown in the side pane for the goal task. For this example, I have several paragraphs with text, but the most important section is the link represented by <a href="#" onClick="EnterpriseTeamBuilder()">Build Team from Enterprise...</a>. When this link is clicked, it calls the EnterpriseTeamBuilder() function that I created in the Enterprise Team Builder.js file (I cover this later in this example). The <a title="Done" href="#" onClick="parent.navigate(2,-1,'GoBack')">Done</a> link puts a Done link at the bottom of the goal task page. The parent.navigate call in this instance returns to the Resources goal area (2) main menu (–1). At the bottom of the divContent section is the function call pDisplayTaskFooter(); that sets up the task footer and establishes a task help link if specified.
The code in Listing 18-7 represents the HTML page for the goal task help. In this example, the page is very similar to the Enterprise Team Builder.htm page I covered in the previous section. There are three primary differences between this page and the goal task page. The first difference is the call to pDisplayTaskHelpHeader(); instead of pDisplayTaskHeader();. A second variation is that the Done link navigates back to the goal task (11) instead of the goal area menu (–1). The final distinction between the two pages is that the pDisplayTaskFooter(); shouldn’t be called because I don’t want a help link on the help page.
Listing 18.7: Enterprise Team Builder_Help.htm
<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="MSThemeCompatible" content="Yes"> <title> Microsoft Project </title> <script src="/books/2/89/1/html/2/gbui://util.js" language="JScript"></script> <link rel="stylesheet" href="gbui://ProjIE.css" type="text/css" /> </head> <!-- The body should always have a onLoad call to handleResize() --> <body onLoad="handleResize()" onContextMenu="return false" tabIndex=1> <script language="JScript"> // pDisplayTaskHeader should always be called before pSetupSidepane pDisplayTaskHeader(); pSetupSidepane(); </script> <div id=divMain onResize="handleResize();"> <div > <div > <p> Generic Resources </p> </div> <p> You should use generic resources when possible as they have several benefits: <li> act as placeholders for resource assignments </li> <li> all task assignments are replaced when a resource is assigned using <b>Replace</b> </li> <li> allow preliminary reporting before the project plan is complete </li> </p> <p > <!-- pNavigate(goalAreaID, taskID, elementID) --> <!-- * goalAreaID - goal area to go back to --> <!-- * taskID - task ID to go back to (-1 for goal area menu) --> <!-- * elementID - 'GoBack' takes you back to the previous location --> <!-- In this instance we are going back to the calling page Goal Area 2 and TaskID 11 --> <a title="Done" href="#" onClick="pNavigate(2,11,'GoBack')"> Done </a> </p> <!-- Don't put a setup footer because we don't want to include a More Information link on the help page --> </div> <!-- SidepaneData --> </div> <!-- divMain --> </body> </html>
The code in Listing 18-8 shows the Enterprise Team Builder.js page with the JavaScript functions necessary to give the goal area task added functionality. The first function, setupView(), changes Microsoft Project to the Resource Sheet if it isn’t already the current view. The EnterpriseTeamBuilder function gets an object link to the Microsoft Project application using var application = window.external.Application; and then it calls the Microsoft Project EnterpriseTeamBuilder function. You can find the command for this feature by looking in the Microsoft Project VBA help file, VBAPJ10.CHM, or by recording a macro and then selecting Build Team from Enterprise from the Tools menu.
Listing 18.8: Enterprise Team Builder.js
//*********************************************************************** // This jscript file has functions needed by the EnterpriseTeamBuilder // task page htm file //*********************************************************************** var RESOURCE_SHEET = "Resource Sheet"; //*********************************************************************** // NAME: setupView // PURPOSE: This function sets the current view to the Resource Sheet // PARAMETERS: None // RETURN: None //*********************************************************************** function setupView() { try { var application = window.external.application; var script = pscript(); //Make sure Resource Sheet view applied if (application.activeproject.currentview != RESOURCE_SHEET) { script.applyNewView(RESOURCE_SHEET); } } catch(err) { alert("Error applying view!"); } } //*********************************************************************** // NAME: EnterpriseTeamBuilder // PURPOSE: This function calls the EnterpriseTeamBuilder Microsoft // Project function. // PARAMETERS: None // RETURN: None //*********************************************************************** function EnterpriseTeamBuilder() { try { // Create the application object in memory // Set the application object so we can access Microsoft Project // functions var application = window.external.Application; // Call the EnterpriseTeamBuilder function // This was found using VBAPJ10.CHM, which is an // install option for Microsoft Project application.EnterpriseTeamBuilder; } catch(exp) { alert("Error calling EnterpriseTeamBuilder function!") } }
You’ve now created a customized Project Guide that changes the standard resource selection to allow selecting resources from Microsoft Project Server only. The last step is to open up the Options dialog box (select Tools Options) and specify the Project Guide Content XML file for custom content. Then go to the Resources goal area and take a look at the customized “Specify people and equipment from Microsoft Project Server.”
Tip | When you test a custom Project Guide, press Ctrl+R to refresh updated Project Guide data in Microsoft Project. |
In this example, I create a brand-new goal area called Project, which will be the first goal in the Project Guide. This new goal area contains a simple page specified for project templates. In the following example, I add a goal task wizard to the Project goal area.
Here are the steps required to add a new goal area:
Modify the Project Guide XML content file.
Create a Web page for the goal area page.
Create scripts as needed for custom functionality.
Specify the Project Guide content file.
Once again I want to add a new goal area to the Project Guide XML content file. Listing 18-9 shows the code to add the new goal area and a new goal task.
Listing 18.9: ProjectGuideArea.xml Content for the Goal Area Page
<GoalArea> <GoalAreaID> 10 </GoalAreaID> <GoalAreaName> Project </GoalAreaName> <GoalAreaDescription> Follow the steps below to create a new project </GoalAreaDescription> <URL> file://C:\CustomPG\Project Server Book\Project Goal Area\ Project_Main.htm </URL> <RelevantViews> <ViewType> 0 </ViewType> </RelevantViews> <GoalAreaTask> <TaskID> 101 </TaskID> <Title> Project Templates </Title> <TaskName> Use project templates </TaskName> <URL> file://C:\CustomPG\Project Server Book\Project Goal Area\Project Templates\Project_Templates.htm </URL> </GoalAreaTask> </GoalArea>
Note | The URLs specified in Listing 18-9 are hard-coded to the local machine. Make sure to put the files in the same location or modify the URLs in the listing. |
I’ve already covered the details of this code. As you can see, creating a goal area is very similar to creating a goal area task entry. Be aware that the GoalAreaID for Project is 10; however, I put this section in front of the Project goal area with a GoalAreaID of 1. The Project goal area will show up first if it’s specified first in the XML file. The GoalAreaID doesn’t determine the order of goal areas, and the same applies to goal tasks. Make certain that each goal area or goal task has a unique ID within its group.
The code in Listing 18-10 shows the HTML page for the Project goal area page. There are several differences between a goal area page and a goal task page. The first difference is making the pDisplayGoalAreaTasks(); function call to display the goal area tasks. The next function call displays the goal area footer, but the pDisplayGoalAreaFooter(); function isn’t used in the Project Guide at this time. The last variation contains a link to navigate to the next goal area at the bottom of the side pane.
Listing 18.10: Project_Main.htm
<!-- This is the goal area page for the Project Goal Area --> <html> <head> <meta http-equiv="MSThemeCompatible" content="Yes"> <script src="/books/2/89/1/html/2/gbui://tasks_main.js" language="JScript"></script> <script src="/books/2/89/1/html/2/gbui://util.js" language="JScript"></script> <link rel="stylesheet" href="gbui://ProjIE.css" type="text/css" /> </head> <!-- The body should always have a onLoad call to handleResize() --> <body onLoad="handleResize();" onContextMenu="return false" tabIndex=1> <script language="JScript"> // pDisplayTaskHeader should always be called before pSetupSidepane pDisplayTaskHeader(); pSetupSidepane(); </script> <div id=divMain onResize="handleResize();"> <div > <script language="JScript"> <!-- Display the Goal Area tasks as listed in the XML file --> pDisplayGoalAreaTasks(); </script> <script language="JScript"> <!-- Display the Goal Area footer, which is not currently used --> pDisplayGoalAreaFooter(); </script> <!-- Place a link to the next Goal Area here --> <!-- Navigate to Goal Area ID 1 (Tasks area) --> <p> After completing the initial project setup, you can go to the <a title="TasksArea" href="#" onClick="pNavigate(1)"> Tasks area </a> to create tasks in your project. </p> </div> <!-- SidepaneData --> </div> <!-- divMain --> </body> </html>
I don’t cover the creation of the Project_Templates.htm file in this chapter, as the process to do so is very similar to the process to create the goal task page you created in the first example. All of the files are available for download from http://projectserverexperts.com. Once you specify the new content, you have a new goal area in your Project Guide.
In this example, you’ll focus on building a goal task wizard page that introduces some new behind-the-scene technologies. I cover these technologies briefly.
The steps required to create a new goal task wizard are as follows:
Modify the Project Guide XML content file.
Create a Web page for the goal task wizard page.
Create a script page for wizard functionality.
Specify the Project Guide content file.
Once again, you’re working with the Project Guide XML content file to add a new goal area to your Project Guide. Listing 18-11 shows the XML code to add to the Project Guide content file for the new goal task wizard.
Listing 18.11: ProjectGuideArea.xml Content for the Goal Task Wizard Page
<GoalAreaTask> <TaskID> 102 </TaskID> <Title> Project Parameters </Title> <TaskName> Enter project parameters </TaskName> <URL> file://C:\CustomPG\Project Server Book\Project Goal Area\Project Initiation Wizard\Project_Initiation.htm </URL> <RelevantViews> <ViewType> 1 </ViewType> </RelevantViews> </GoalAreaTask>
Note | The URLs specified in Listing 18-11 are hard-coded to the local machine. Make sure to put the files in the same location or modify the URLs in the listing. |
Listing 18-12 shows the HTML page for the goal task wizard page. Although the overall structure is very similar to customizations you made to the goal task and goal area pages, there are several new items to explore in detail. The first is the new set of calls in the body onLoad and onUnload events. A second major difference is that I’ve introduced SidepaneData sections for each wizard step. Finally, the wizard footer navigation allows the goal task to move between the different steps that make up the wizard page.
Listing 18.12: Project_Initiation.htm
<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="MSThemeCompatible" content="Yes"> <title> Microsoft Project </title> <script src="/books/2/89/1/html/2/file://C:\CustomPG\Project Server Book\Project Goal Area\Project Initiation Wizard\Project_Initiation.js" language="JScript"></script> <script src="/books/2/89/1/html/2/file://C:\CustomPG\Project Server Book\Project Goal Area\Project Initiation Wizard\Project_Initiation_Wizard.js" language="JScript"></script> <script src="/books/2/89/1/html/2/file://C:\CustomPG\Project Server Book\Project Goal Area\Project Initiation Wizard\PDS_SOAP.js" language="JScript"></script> <script src="/books/2/89/1/html/2/file://C:\CustomPG\Project Server Book\Project Goal Area\Project Initiation Wizard\XML_OutlineCodes.js" language="JScript"></script> <script src="/books/2/89/1/html/2/gbui://util.js" language="JScript"></script> <link rel="stylesheet" href="gbui://ProjIE.css" type="text/css" /> </head> <body onLoad="handleResize(); initWizardScripts(); ProjectInitiation_Main();" onUnload="cleanupWizardScripts();" onContextMenu="return false" tabIndex=1> <script language="JScript"> // pDisplayTaskHeader should always be called before pSetupSidepane pDisplayTaskHeader(); pSetupSidepane(); </script> <div id=divMain onResize="handleResize();"> <!-------------------------------------> <!---First wizard step--> <!-------------------------------------> <div style="display:none"> <div > <p> Project ID </p> </div> <div> <p> Contact the Project Management Office to receive your Project ID. The Project ID allows reports to include data from Microsoft Project Server and the accounting system. </p> <p> Project ID: <input type="text" name="ProjectID"> </p> </div> </div> <!-------------------------------------> <!--Second wizard step--> <!-------------------------------------> <div style="display:none"> <div > <p> Sponsor Organization </p> </div> <div> <p> Select the sponsor organization for this project from the list below. </p> <p> <select ></select> </p> </div> </div> </div> <!-- divMain --> <!------------------------------------------------------------> <!-- Wizard footer navigation --------------------------------> <!-- The functions below sets up the Wizard footer --> <!-- navigation as "Step i of n". There should be one --> <!-- write_WizardFooter for each wizard step. --> <!-- write_WizardFooter(A, B, C, D) --> <!-- A - is the step number --> <!-- B - is the number of steps --> <!-- C - is the previous step number --> <!-- D - is the next step number --> <!------------------------------------------------------------> <div > <script language="JScript"> try { var script = pscript(); script.write_WizardFooter(1, 2, 0, 2); script.write_WizardFooter(2, 2, 1, 0); } catch(exp) {} </script> </div> </body> </html>
Note the two calls in the <body> section of the HTML page: onLoad="initWizardScripts();" and onUnload="cleanupWizardScripts();". The initWizardScripts(); function initializes the wizard environment and sets up environment items such as putting the Project Guide into wizard mode and setting up the wizard footer. onUnload="cleanupWizardScripts(); resets the Project Guide from wizard mode and cleans up any resources the wizard was using.
Wizard content is found in each of the wizard steps, which are specified by the SidepaneData groups for each step. Notice the ID for each SidepaneData divisor is Step#, which tells the Project Guide to get content for the current step. There is a SidepaneData grouping for each wizard step.
The final item is the WizardFooter navigation function call. There is a WizardFooter call for each wizard step. The format for the function call is pscript.write_WizardFooter(step#, # of steps, prevStep, nextStep);.
The content in Listing 18-13 shows some functions that I added to make data validation easier to implement. Most of the code for this wizard script page isn’t shown here. You can download the full code sample from http://www.projectserverexeperts.com.
Listing 18.13: Project_Initiation_Wizard.js
var stepCount = 2; // Here's the total number of steps in the wizard. var goalAreaID = 10; // Project Goal Area ID of the parent goal area //*********************************************************************** // NAME: stepValidation // PURPOSE: This handler validates data in the step we are leaving. // This event will be ignored if the next step is not prevStep + 1. // This event also ignores the initial entry with prevStep = 0. // PARAMETERS: // prevStep -- ID number of the step we're leaving // nextStep -- ID number of the step we're going to // RETURN: None //*********************************************************************** function stepValidation(prevStep,nextStep) { try { // Validate when going to the next step only if ((nextStep == prevStep + 1) && (prevStep != 0)) { // Select the step to validate switch(prevStep) { case 1: // Make sure a value was entered for ProjectID if (ProjectID.value.length ==0) { alert("Please enter a valid Project ID!"); return false; } case 2: // Enter validation code here } } } catch(err) { alert("Error in wizard stepValidation at step#: " + prevStep); } } //*********************************************************************** // NAME: wizardCompleteSuccess // PURPOSE: This handler will fire when the wizard is completed // successfully. This will usually be used to store wizard data values. // PARAMETERS: None // RETURN: None //*********************************************************************** function wizardCompleteSuccess() { // Store the Project ID and Outline Code entries storeValues(); }
Besides the Project Guide XML content, the two main requirements are a goal task wizard HTML page and a goal task wizard JavaScript page. I mention JavaScript, but VBScript is also an option. I chose JavaScript for these examples, however, because it’s the primary language Microsoft used in the creation of the Microsoft Project Server Web content. Although I’ve covered the requirements for a goal task wizard, this example won’t work without several other files. I go over these files and the technologies used in the next section.
I’ve covered the main requirements in creating a goal task wizard page, but I haven’t addressed all of the files included with the Project Initiation Wizard example. Several new technologies are incorporated into this example: PDS, SOAP, XML, and several Microsoft Project intrinsic functions. I cover each of these items in the following sections.
To successfully run the Project Initiation Wizard, you must ensure the following requirements are met:
The Project Initiation Wizard example requires Microsoft Project Professional and Microsoft Project Server.
You must be able to connect to Microsoft Project Server for this example to work.
Note | Microsoft Project will display a message box asking whether you want to run ActiveX controls on the current page. This message is created by the ActiveX SOAP client connecting to Microsoft Project Server to communicate with the PDS. Click Yes to allow the Project Initiation Wizard to work correctly. If you click No or if your security settings disallow the running of ActiveX controls, the Project Initiation Wizard won’t work. |
The Project Initiation Wizard uses the Enterprise Project Text1 and Enterprise Project Outline Code1 custom fields. You must define both of these in the enterprise global template. To set up Enterprise Project Text1, rename it to ProjectID. To set up the Enterprise Project Outline Code1, you name it, specify a code mask, and input a list of valid values. For this example I named the outline code Sponsor Organization, specified a character code mask, and inserted the following lookup values: HR, Engineering, Finance, and IT.
You may need to resize the side pane if the outline code data is too wide.
Most of the magic behind the scenes of the Project Initiation Wizard example is organized by the Project_Initiation.js file. This file has three functions, ProjectInitiation_Main(), FillOutlineCodeList(), and storeValues(), as shown in Listing 18-14. The ProjectInitiation_Main() function marshals calls to other functions to connect to Microsoft Project Server, get a login cookie, set up an XML request string, make the PDS SOAP call, get the XML response, and pull out the outline code values. The FillOutlineCodeList() function takes an arrayed list of outline values and uses them to populate a list box. The storeValues() function takes the values entered into the wizard and assigns them to the active project.
Listing 18.14: Project_Initiation.js
//*********************************************************************** // This jscript file is the main jscript file for the Project // Initiation task page. This page stores the variables that need // to be changed for the PDS calls to function correctly. //*********************************************************************** //*********************************************************************** // Set the variables below //*********************************************************************** var intUserType = 1; //1 for Project Server and 2 for Windows Authenticated users var strPServer_url = "http://pserver/projectserver/"; //Project Server address var strUID = "PM"; //Provide a username and password for Project Server users var strPWD = "PM"; //Provide a username and password for Project Server users // Stores the XML XPath search string for nodes to return var strXML_XPath = "Reply/OutlineCodes/OutlineCode/Values/Value/ValueFull"; //*********************************************************************** // NAME: ProjectInitiation_Main // PURPOSE: This is the main function for the Project Initiation that // calls other functions to connect to Project Server, get a cookie, // make the PDS SOAP call, get the XML response, and get the Outline // Code values. // PARAMETERS: None // RETURN: None //*********************************************************************** function ProjectInitiation_Main() { var strPServerLogin_url; // Stores the complete Project Server Login URL var strPServerPDS_url; // Stores the Project Server PDS URL var strCookie; // Stores the login cookie from Project Server var strXMLRequest; // Stores the XML request for PDS var strXMLResponse; // Stores the XML response for PDS var astrValues = new Array(); // Stores the Outline Code values returned from Project Server // Check the Project Server url for a / (slash) at the end strPServer_url = CheckPServer_url(strPServer_url); // Get the Project Server login url based on the user authentication type strPServerLogin_url = PServerLogin_url(intUserType, strPServer_url, strUID, strPWD); // Get the Project Server PDS url strPServerPDS_url = PServerPDS_url(strPServer_url); // Get the Project Server login cookie strCookie = GetPServerCookie(strPServerLogin_url); // Setup the PDS SOAP request for Enterprise Project Outline Code 1 // CODETYPE 0 corresponds to project enterprise outline codes // CONV_VALUE 188744589 for Enterprise Project Outline Code 1 // found in MSP_CONVERSIONS database table: // STRING_TYPE_ID 105 // CONV_VALUE 188744589 // CONV_LANG_ID 1033 // CONV_STRING Task Enterprise Project Outline Code1 strXMLRequest = EnterpriseOutlineCodes_XMLRequest(0, 188744589); // Make the SOAP call to Project Server strXMLResponse = SoapCall(strPServerPDS_url, strCookie, strXMLRequest); // Get the list of values from the last SOAP call // Pass in the XML Response string and the XML XPath search string astrValues = GetXMLValues(strXMLResponse, strXML_XPath) // Sort the array of values astrValues.sort(); // Fill the Outline Code list FillOutlineCodeList(lstOutlineCodes, astrValues); } //*********************************************************************** // NAME: FillOutlineCodeList // PURPOSE: This function fills the list object with the list of valid // outline code values. // PARAMETERS: // lstOutlineCodes - A link to the list object on the html page // astrValues - The array of valid outline code values // RETURN: None //*********************************************************************** function FillOutlineCodeList(lstOutlineCodes, astrValues) { try { var objOption; // New option to add to the list // Loop through the array and add an option in the pulldown for each for (i = 0; i < astrValues.length; i++) { // Create a new option object objOption = document.createElement("option"); // Set the option text value from the array objOption.text = astrValues[i]; // Add the option to the list lstOutlineCodes.options.add(objOption); } lstOutlineCodes.selectedIndex = 0; lstOutlineCodes.style.display = ""; } catch(err) { alert("Error in FillOutlineCodeList!"); } } //*********************************************************************** // NAME: storeValues // PURPOSE: This stores the values given in the Project Initiation wizard. // PARAMETERS: None // RETURN: None //*********************************************************************** function storeValues() { try { var application = window.external.Application; var strProjectIDValue; var strOutlineCodeValue; // Get the ProjectID and Outline Code values from the text and list boxes strProjectIDValue = ProjectID.value; strOutlineCodeValue = lstOutlineCodes.options[lstOutlineCodes.selectedIndex].text; // Set the Enterprise Project Outline Code1 value // See above for information on how to find the code value application.ActiveProject.ProjectSummaryTask.SetField(188744729, strProjectIDValue); // Set the Enterprise Project Outline Code1 value // See above for information on how to find the code value application.ActiveProject.ProjectSummaryTask.SetField(188744589, strOutlineCodeValue); } catch(err) { alert("Error trying to store values!"); } }
The first section of the ProjectInitiation_Main() function has constant variables that you must set accurately for the Project Initiation Wizard to work properly. These variables include the authentication type for Project Server users, either Project Server or Windows Authentication. You must specify the URL for the Microsoft Project Server. For Project Server authenticated users, you specify a username and password to use. Finally, you input a valid XPath search path for the desired XML element. The XPath specified by default will return the ValueFull parameter from the enterprise outline codes.
I recommend you look at each function called by the ProjectInitiation_Main() function to better understand how the PDS function call handles getting the outline code values. PDS_SOAP.js and XML_OutineCodes.js are the main files used by the ProjectInitiation_Main() function. The primary steps in a PDS call are as follows:
Get the Project Server URL with the correct authentication type and login page.
Get the Project Server PDS URL.
Connect to Microsoft Project Server and retrieve a login cookie.
Build an XML request string to send to the PDS.
Make the PDS SOAP call to Microsoft Project Server.
Get the XML response from the PDS SOAP call.
Manipulate the XML response as needed to get usable data.