Login / Register  search  syndication  about

          Kris Halsrud's Blog

Kris Halsrud on development and Integration with CRM and Development

SalesLogix Web Client- Add Opportunity/SalesOrder Product grid: Binding a data grid drop down column programmatically

In the standard add product screen for both an Opportunity and Sales Order, the user is able to perform in-line edits to the selected products.  One of the columns that can be edited is the Price Level column.  By default this column is a picklist column showing the “Price Description” picklist. 

 Standard Add Product screen showing picklist selection in edit mode

The problem with binding the picklist to this column is that not every product contains each price level. This can lead to confusion for a user when they are not sure which of the choices in the list are valid for the given product.   In order to filter the column’s choices we can change the column to be a drop down list and programmatically bind the list based upon the selected record’s defined price levels.  Lets take a look at how to do this.

The sales order and opportunity add screens are both custom smart parts.  Each smart part is comprised of an ascx and a corresponding cs file.  These files can be found in the Application Architect under the Portal Manager…SalesLogix Client…Support Files…Smart Parts and then either Opportunity or SalesOrder.  The Opportunity files are called “AddOpportunityProduct” and the Sales Order ones, called “AddSalesOrderProduct:”.  In this post, I will demonstrate the steps on the Opportunity version.

The first step is to alter the ascx file and change the grid’s column definitions.

In the file you want to look for the Price Program column within the asp:GridView control. In a standard 7.5.3 system the column definition is on line 129 of the file.  It should look like this:

<asp:TemplateField HeaderText="<%$ resources: grdProducts.PriceLevel.ColumnHeader %>">
        <SalesLogix:PickListControl PickListName="Price Description" runat="server" ID="pklProgramDisplay"
            style='white-space:nowrap;' OnPickListValueChanged='pklProductProgram_PickListValueChanged'
            AutoPostBack="false" DisplayMode="AsText" PickListValue='<%# Eval("Program") %>' />
        <SalesLogix:PickListControl PickListName="Price Description" runat="server" ID="pklProgram"
            style='white-space:nowrap;' OnPickListValueChanged='pklProductProgram_PickListValueChanged'
            AutoPostBack="true" DisplayMode="AsHyperlink" PickListValue='<%# Bind("Program") %>' />

Again, we are going to change this from a SalesLogix picklist control to a standard drop down.  To do this we change the entire TemplateField markup to look like this:

<asp:TemplateField HeaderText='<%$ resources: TFProgram_rsc.HeaderText %>' >
        <%# Eval("Program") %>
        <asp:DropDownList ID="dropProgram" rows="4" runat="server" style='white-space:nowrap;' AutoPostBack='true'
        OnSelectedIndexChanged="dropProgram_IndexChanged" AppendDataBoundItems="true" Text='<%# Bind("Program") %>' DataSource='<%# getPrograms(Eval("Product.Id")) %>' DataTextField="Program" DataValueField="Program"  />

You can see in our new markup we have simplified the ItemTemplate component to simply display the text corresponding to the Program property. 

In the EditItemTemplate section we have switched the control to a standard asp.net DropDownList.  A couple of notes about the attributes I have specified:

  • Rows=”4” This defines that four items will display when the drop down appears.  You can expand this as needed.
  • OnSelectedIndexChnaged=”dropProgram_IndexChanged” This defines the server side code to run when a user selects an item from the list.  This code will be placed in the corresponding cs file and will be what actually sets the price accordingly.
  • AppendDataBoundItems=”true” This must be set in order to allow the drop down to accept items added dynamically.
  • Text='<%# Bind("Program") %>' Specifies what property from the underlying datasource will display as the selected value when an item is chosen.
  • DataSource='<%# getPrograms(Eval("Product.Id")) %>' This defines how the drop down list is bound.  We are calling the getPrograms method.  This method will again be added to the cs file and is what controls the choices in the list.
  • DataTextField and DataValueField=”Program” this defines the datasource properties used to actually fill the list with entries.

 The next thing we need to do is to add a hidden field bound to the selected rows Product ID.  This is so we can use this information from the code behind.  To do this we simply add a new field within the columns markup for the grid, like so:

                                <asp:Label ID="lblProdID" runat="server" Text='<%# Eval("Product.Id") %>' Visible="false" />
                                <asp:HiddenField ID="hidProductId" runat="server" Value='<%#Eval("Product.Id") %>' />

That is all we need to do in the ascx file.  We now have changed the column to the desired drop down list instead of a SalesLogix picklist.

Onto the cs file.  In the cs file we need to add our two methods refrenced in our new ascx markup “getPrograms” and “dropProgram_IndexChanged.  In the cs file we can add this code like so:      

    protected System.Collections.Generic.IList<Sage.Entity.Interfaces.IProductProgram> getPrograms(object ProductId)
        System.Collections.Generic.IList<Sage.Entity.Interfaces.IProductProgram> programs = new List<Sage.Entity.Interfaces.IProductProgram>();
            Sage.Platform.RepositoryHelper<Sage.Entity.Interfaces.IProductProgram> repository =
            Sage.Platform.Repository.ICriteria criteria = repository.CreateCriteria();
            programs = criteria.List<Sage.Entity.Interfaces.IProductProgram>();                        
        return programs;


The getPrograms routine accepts a parmeter passing in the Product ID of the row being edited.  It then uses IRepository to find the programs associated to that Product ID.  With the programs found it returns an IList of the ProductProgram interface.

    protected void dropProgram_IndexChanged(object sender, EventArgs e)
        IOpportunity opportunity = BindingSource.Current as IOpportunity;
            string productId = ((HiddenField) grdProducts.Rows[grdProducts.EditIndex].FindControl("hidProductId")).Value;
            string program = ((DropDownList) grdProducts.Rows[grdProducts.EditIndex].FindControl("dropProgram")).SelectedValue;       
            foreach(IOpportunityProduct op in opportunity.Products)
                    if(op.Product.Id.ToString() == productId)
                        op.Program = program;

The dropProgram_Index change event looks at what the selected value is of the dropProgram column and then finds the price information for that price level and sets the current opportunity record with the newly selected price program pricing.  To do this I used a standard Opportunity entity business rule which takes care of setting the Opportunity Price, CalcPrice, and ExtendedPrice properties.


What's This?
Bookmark and Share

About Kris Halsrud

   Kris Halsrud is a Senior Analyst / Developer for Customer FX Corporation.

Related Content
   Easily Showing and Hiding Tabs at Runtime in Infor CRM (Saleslogix)
Showing and hiding tabs in the Infor CRM (Saleslogix) client should be an easy thing. It should be someth
Posted on Dec 16, 2014 by Ryan Farley to Ryan Farley's Blog
   Problem setting SLXTextbox enabled property / Setting unexposed base control properties for a custom control
I recently had an issue with a Quickform where I was attempting to set the Enabled property of a TextBox
Posted on Dec 05, 2014 by Jason Buss to Jason Buss' Blog
   Checking Infor CRM (Saleslogix) Picklists for valid data
This week I received a question about a particular picklist. One of the picklist items, when chosen, wou
Posted on Dec 05, 2014 by Dale Richter to Infor CRM Questions & Answers
   Avoiding the Dirty Data Message When Programatically Redirecting to a Record in Infor CRM (Saleslogix)
In my last post I wrote about using the OnClientClick property of a control (or button) to run JavaScript
Posted on Dec 02, 2014 by Ryan Farley to Ryan Farley's Blog
   Infor CRM (formerly Saleslogix) Web- Dependency Lookup OnChange Event Not Working Correctly
In the Saleslogix 8.1 web client the dependency lookup still has a problem with the OnChange event. 
Posted on Nov 26, 2014 by Kris Halsrud to Kris Halsrud's Blog


Fen said:

wow thanks!

Do you know, where the info is defined, which fields can be updated and why it seems to be the rule, that no new fields can't be inserted into the grid (they throw an error on update).

July 20, 2011 3:37 AM

Kris Halsrud said:

Fen, there is a method in the OpportunityProductEx.ascx.cs called OnAddEntityBindings() that defines the fields in the datasource that are available as columns.  You would need to add fields to the datasource definition in order to add them as columns.

July 25, 2011 8:34 AM

Leave a Comment

All contents Copyright © 2014 Customer FX Corporation
Customer FX Corporation
2324 University Avenue West, Suite 115
Saint Paul, Minnesota 55114
Tel: 800.728.5783

  Follow @CustomerFX on twitter
Follow the best news, tips, and articles
  Subscribe to Customer FX on youtube
Watch SalesLogix tutorial videos from Customer FX
Login / Register