Sage CRM 2018 R1: Adding a Pipeline Graphic to a ListPage class built using the .NET API

Hints, Tips and Tricks

Technical Hints Tips and Tricks that cover customization and development using Sage CRM. API usage and coding are covered.

Sage CRM 2018 R1: Adding a Pipeline Graphic to a ListPage class built using the .NET API

  • Comments 2
  • Likes

Below you can see that I have created a new List Page with a PipeLineGraphic for a Custom Entity.

The List Page has been created using the ListPage specialised class of the .NET API.

You can see the code below.

////////////////////Code Starts//////////////////

using Sage.CRM.WebObject;
using Sage.CRM.Blocks;
using Sage.CRM.Controls;
using Sage.CRM.Data;
using Sage.CRM.Utils;
using Sage.CRM.Graphics;
using Sage.CRM.UI;

namespace ProjectList
public class ProjectList : ListPage
/* Constructor needs EntityName, ListName, IdField, FilterByField, FilterContext and ScreenName
public ProjectList()
: base("project", "ProjectGrid", "ProjectSearchBox")
int iDomKey = Keys[(int)Sage.KeyList.DominantKey];
switch (iDomKey)
case 1:
FilterByField = "proj_companyid";
FilterByContextId = (int)Sage.KeyList.CompanyId;
case 2:
FilterByField = "proj_personid";
FilterByContextId = (int)Sage.KeyList.PersonId;
case 4:
FilterByField = "proj_userid";
FilterByContextId = (int)Sage.KeyList.UserId;
case 5:
FilterByField = "proj_channelid";
FilterByContextId = (int)Sage.KeyList.ChannelId;
FilterByField = "proj_userid";
FilterByContextId = (int)Sage.KeyList.UserId;

foreach (Entry myEntry in FilterScreen)
myEntry.NewLine = true;
myEntry.DefaultValue = null;
myEntry.Required = false;

string statusArg = Dispatch.QueryField("proj_status");
if (statusArg!=null)
ResultsGrid.Filter = "proj_status=" + statusArg;
if (statusArg == "''")
ResultsGrid.Filter = "proj_status is null";

public override void AddNewButton()

public override void BuildContents()

PipelineGraphicBlock myPipe = new PipelineGraphicBlock();
int intUserID = CurrentUser.UserId;

myPipe.PipelineStyle(PipelineStyles.SelectedWidth, "1");
myPipe.PipelineStyle(PipelineStyles.SelectedHeight, "10");
myPipe.PipelineStyle(PipelineStyles.PipeWidth, "40");
myPipe.PipelineStyle(PipelineStyles.PipeHeight, "60");
myPipe.PipelineStyle("Margin", "80");
myPipe.PipelineStyle("ShowLegend", "true");

string strSQL = "select proj_status, count(*) as t from project with (nolock) where proj_userid=" + intUserID + " group by proj_status";
QuerySelect queryObj = new QuerySelect();
queryObj.SQLCommand = strSQL;
string strStage = "";
while (!queryObj.Eof())
if (queryObj.FieldValue("t") != "0")
strStage = Metadata.GetTranslation("proj_status", queryObj.FieldValue("proj_status"));
myPipe.AddPipeEntry(strStage, System.Convert.ToInt32(queryObj.FieldValue("t")), queryObj.FieldValue("t") + " " + strStage, UrlDotNet(ThisDotNetDll, "RunProjectList") + "&proj_status='" + queryObj.FieldValue("proj_status") + "'");

myPipe.Summary = "Additional Information can be displayed here.";

HTMLString htmlPipe = new HTMLString();
htmlPipe.Html = myPipe.Execute();
string strhtmlPipe = htmlPipe.ToHtml().Replace("NAME=\"EntryForm\"", "NAME=\"EntryForm1\"");


////////////////////////Code Ends/////////////////////////


  1. The project uses the ListPage to constructor create the ProjectList.
  2. The constructor class looks at the context information and the page can be called from either the My CRM or the Team menus.
  3. The pipelinegraphic will add an additional filter 'proj_status'.  When a section of the pipeline is clicked this will be added to the URL and therefore needs to be read using the Dispatch.QueryField() method.
  4. The pipelinegraphicblock needs to be built ahead of the main ListPage behaviour.  This is done by using a BuildContents() override.
  5. The pipelinegraphicblock was created using one of the snippets provided by the Sage CRM SDK.
  6. When a pipelinegraphic section is clicked the URL will be changed and the page reloaded with the additional filter information.
  7. Additional Summary Information can be included by setting the Summary property.
  8. To avoid the inclusion of the pipelinegraphic creating a duplicate HTML form tag this needs to be removed.
  9. The pipeline can then be added to the contents of the page and sent to the browser.

  • Hi Jeff, I implemented a version of this to create a custom Cases pipeline which works ok except for one minor issue - clicking on a section of the pipeline does not expand that section of the graphic like it does with the standard My CRM->Cases pipeline graphic.

    Any ideas why that might be?

    Also on a secondary question is there any way to increase the size of the icons in the legend of pipeline?



  • Mike

    To fiddle with the sections use the some script like this.

    strStage = Metadata.GetTranslation("proj_status", queryObj.FieldValue("proj_status"));

                       strSectionScript = "javascript:document.EntryForm.proj_status.options[SageCRM.webObject.GetDropDownIndexByValue(document.EntryForm.proj_status,'";

                       strSectionScript = strSectionScript + strStage + "')].selected = true;document.EntryForm.submit();";

                       //myPipe.AddPipeEntry(strStage, System.Convert.ToInt32(queryObj.FieldValue("t")), queryObj.FieldValue("t") + " " + strStage, UrlDotNet(ThisDotNetDll, "RunProjectList") + "&proj_status='" + queryObj.FieldValue("proj_status") + "'");

                       myPipe.AddPipeEntry(strStage, System.Convert.ToInt32(queryObj.FieldValue("t")), queryObj.FieldValue("t") + " " + strStage, strSectionScript);

    This requires the 'proj_status' field to be included in the filterbox.

    I don't know of a way of changing the legend icon size.