Table of Contents

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

  1. Use the basic template to create a new project in Visual Studio.

  2. 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;
    
  3. In the CustomPage.cs file, modify the EntryScreen class definition to make this class an instance of the Web 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 the BuildContents method, enabling you to write HTML that displays a screen.

  4. 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:

  1. Set up an HTML form to display the screens:

    public override void BuildContents()
    {
        AddContent(HTML.Form());
    }
    
  2. 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");
    }
    
  3. 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

  1. Add the following code between the braces in the if statement.

    If the HiddenMode value is Save, 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.
    
  2. Add the following code between the braces in the else statement.

    If the HiddenMode value is not Save (for example, Edit), this code creates a vertical panel and adds entry boxes for Company, Person, and Opportunity to it. Make sure to add the HiddenMode field to the EntryScreen 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.

  1. 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)
    
  2. Display a Cancel button. This button calls the RunEntryScreen method provided in your custom .NET DLL (ThisDotNetDll). You will define the RunEntryScreen method later.

    AddUrlButton("Cancel", "cancel.gif", UrlDotNet(ThisDotNetDll, "RunEntryScreen"));
    
  3. 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

  1. Build your solution in Visual Studio.

  2. Copy the compiled .NET DLL to the storage location for custom DLLs on the Sage CRM server.

  3. 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);
            }
        }
    }
}