Create more complex UI
Complete these steps to create a custom screen that displays Company, Person, and Opportunity entry blocks. On this screen, a user can enter details to create Company, Person, and Opportunity records and save them. The user is then redirected to the summary screen of the newly-created Company. One of the Visual Studio projects supplied with the Sage CRM .NET SDK includes the complete code for this example.
Step 1: Create C# project, add initial code
Use the basic template to create a new project in Visual Studio.
Add a new blank C# class:
a. In Solution Explorer, right-click the new project name, and then select Add | Class.
b. Select the first type on the list (C# class) and name your class.
c. Add the following references at the top of the CustomPage.cs file that was automatically created when you selected the basic template:
using Sage.CRM.Blocks; using Sage.CRM.Controls; using Sage.CRM.Data; using Sage.CRM.HTML; using Sage.CRM.Utils; using Sage.CRM.WebObject; using Sage.CRM.UI;
In the CustomPage.cs file, modify the
EntryScreen
class definition to make this class an instance of theWeb
class:class EntryScreen: Web
Now you can use Sage CRM .NET API calls to write HTML code that builds the screen. The
Web
class provides theBuildContents
method, enabling you to write HTML that displays a screen.Add the following code to the
EntryScreen
class to override the base class:public override void BuildContents() {}
Step 2: Add code to get, display, and format blocks
Add the following code between the braces in the BuildContents()
method:
Set up an HTML form to display the screens:
public override void BuildContents() { AddContent(HTML.Form()); }
Get the blocks or screens that enable the user to enter data. Then, display and format the blocks or screens and save the data entered by the user:
public override void BuildContents() { AddContent(HTML.Form()); EntryGroup screenCompanyBoxLong = new EntryGroup("CompanyBoxLong"); screenCompanyBoxLong.Title = Metadata.GetTranslation("tabnames", "company"); EntryGroup screenPersonBoxLong = new EntryGroup("PersonBoxLong"); screenPersonBoxLong.Title = Metadata.GetTranslation("tabnames", "person"); EntryGroup screenOppo = new EntryGroup("OpportunityDetailBox"); screenOppo.Title = Metadata.GetTranslation("tabnames", "opportunity"); }
Get the current mode stored in the
HiddenMode
field:string hMode = Dispatch.EitherField("HiddenMode"); if (hMode == "Save") { // Add code to save the data entered by user. } else { // Add code to display the forms. }
Step 3: Add code to if
and else
statements
Add the following code between the braces in the
if
statement.If the
HiddenMode
value isSave
, this code populates the database tables with the data the user has entered, saves the changes, and redirects the user to the summary screen of the created Company:// Populate tables with data. Record recCompany = new Record("Company"); screenCompanyBoxLong.Fill(recCompany); recCompany.SaveChanges(); Record recPerson = new Record("Person"); recPerson.SetField("pers_companyid",recCompany.GetFieldAsInt("comp_companyid")); screenPersonBoxLong.Fill(recPerson); recPerson.SaveChanges(); recCompany.SetField("comp_primarypersonid",recPerson.GetFieldAsInt("pers_personid")); recCompany.SaveChanges(); Record recOppo = new Record("Opportunity"); recOppo.SetField("oppo_primarycompanyid",recCompany.GetFieldAsInt("comp_Companyid")); screenOppo.Fill(recOppo); recOppo.SaveChanges(); // Redirect the user to the new Company summary screen. // Action key 200 stands for the Company summary screen. // Make sure to pass the Company ID for the created Company record: // split the action key URL and add the key1=CompanyId bit. string rUrl = Url("200"); string[] split = rUrl.Split(new Char[] { '&' }); string newUrl = split[0] + '&' + split[1] + "&Mode=1&CLk=T&key0=7&key1=" + recCompany.GetFieldAsInt("comp_companyid"); Dispatch.Redirect(newUrl); // Do not add any code in the else statement after the Dispatch.Redirect method. // Otherwise, system performance may be impaired.
Add the following code between the braces in the
else
statement.If the
HiddenMode
value is notSave
(for example,Edit
), this code creates a vertical panel and adds entry boxes for Company, Person, and Opportunity to it. Make sure to add theHiddenMode
field to theEntryScreen
class for the form to work properly.AddContent(HTML.InputHidden("HiddenMode", "")); VerticalPanel vpMainPanel = new VerticalPanel(); vpMainPanel.AddAttribute("width", "100%"); screenCompanyBoxLong.GetHtmlInEditMode(); screenPersonBoxLong.GetHtmlInEditMode(); screenOppo.GetHtmlInEditMode(); vpMainPanel.Add(screenCompanyBoxLong); vpMainPanel.Add(screenPersonBoxLong); vpMainPanel.Add(screenOppo); AddContent(vpMainPanel);
Step 4: Add Save, Cancel, and Help buttons
Insert this code after the else
statement you configured in the previous step.
Display a Save button. This button refreshes the screen and passes a value to the
HiddenMode
field.string sUrl ="javascript:document.EntryForm.HiddenMode.value='2';"; AddSubmitButton("Save", "Save.gif", sUrl)
Display a Cancel button. This button calls the
RunEntryScreen
method provided in your custom .NET DLL (ThisDotNetDll
). You will define theRunEntryScreen
method later.AddUrlButton("Cancel", "cancel.gif", UrlDotNet(ThisDotNetDll, "RunEntryScreen"));
Display a Help button. This button links to a help topic.
string strHelpUrl = "/Main Menu/Default_CSH.htm?href=AI_FAQs.html"; AddHelpButton(strHelpUrl);
Alternatively, you can use the following syntax. It gives you access to the list of available help files in the inline translation mode. For more information, see the System Administrator Help on the Sage CRM Help Center.
AddHelpButton ("help.htm");
Step 5: Edit Base.cs file
Open the Base.cs file that was automatically created when you selected the basic template. Rename the RunMyCustomPage()
method to RunEntryScreen()
.
As a result, the code in the Base.cs file should look as follows:
using System;
using System.Collections.Generic;
using System.Text;
using Sage.CRM.WebObject;
namespace CompoundEntryScreen
{
public static class AppFactory
{
public static void RunEntryScreen(ref Web AretVal)
{
AretVal = new EntryScreen();
}
}
}
Step 6: Build your solution and copy compiled DLL
Build your solution in Visual Studio.
Copy the compiled .NET DLL to the storage location for custom DLLs on the Sage CRM server.
Create a new tab in Sage CRM and add a reference to your custom .NET DLL. For details, see Call DLL from tab.
Sample CustomPage.cs file
Here's the complete code for the CustomPage.cs file.
using System;
using System.Collections.Generic;
using System.Text;
using Sage.CRM.Blocks;
using Sage.CRM.Controls;
using Sage.CRM.Data;
using Sage.CRM.HTML;
using Sage.CRM.Utils;
using Sage.CRM.WebObject;
using Sage.CRM.UI;
namespace CompoundEntryScreen
{
class EntryScreen : Web
{
public override void BuildContents()
{
AddContent(HTML.Form());
EntryGroup screenCompanyBoxLong = new EntryGroup("CompanyBoxLong");
screenCompanyBoxLong.Title = Metadata.GetTranslation("tabnames", "company");
EntryGroup screenPersonBoxLong = new EntryGroup("PersonBoxLong");
screenPersonBoxLong.Title = Metadata.GetTranslation("tabnames", "person");
EntryGroup screenOppo = new EntryGroup("OpportunityDetailBox");
screenOppo.Title = Metadata.GetTranslation("tabnames", "opportunity");
string hMode = Dispatch.EitherField("HiddenMode");
if (hMode == "Save")
{
Record recCompany = new Record("Company");
screenCompanyBoxLong.Fill(recCompany);
recCompany.SaveChanges();
Record recPerson = new Record("Person");
recPerson.SetField("pers_companyid", recCompany.GetFieldAsInt("comp_companyid"));
screenPersonBoxLong.Fill(recPerson);
recPerson.SaveChanges();
recCompany.SetField("comp_primarypersonid", recPerson.GetFieldAsInt("pers_personid"));
recCompany.SaveChanges();
Record recOppo = new Record("Opportunity");
recOppo.SetField("oppo_primarycompanyid", recCompany.GetFieldAsInt("comp_Companyid"));
screenOppo.Fill(recOppo);
recOppo.SaveChanges();
// Redirect to the company summary of the new company.
string rUrl = Url("200");
string[] split = rUrl.Split(new Char[] { '&' });
string newUrl = split[0] + '&' + split[1] + "&Mode=1&CLk=T&key0=7&key1=" + recCompany.GetFieldAsInt("comp_companyid");
Dispatch.Redirect(newUrl);
// Don’t add code after the redirect, as it could impact system performance.
}
else
{
AddContent(HTML.InputHidden("HiddenMode", ""));
VerticalPanel vpMainPanel = new VerticalPanel();
vpMainPanel.AddAttribute("width", "100%");
screenCompanyBoxLong.GetHtmlInEditMode();
screenPersonBoxLong.GetHtmlInEditMode();
screenOppo.GetHtmlInEditMode();
vpMainPanel.Add(screenCompanyBoxLong);
vpMainPanel.Add(screenPersonBoxLong);
vpMainPanel.Add(screenOppo);
AddContent(vpMainPanel);
// Add buttons.
string sUrl = "javascript:document.EntryForm.HiddenMode.value='Save';";
AddSubmitButton("Save", "Save.gif", sUrl);
AddUrlButton("Cancel", "cancel.gif", UrlDotNet(ThisDotNetDll, "RunEntryScreen"));
string strHelpUrl = "/Main Menu/Default_CSH.htm?href=AI_FAQs.html";
AddHelpButton(strHelpUrl);
}
}
}
}