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 %>">
    <ItemTemplate>
        <SalesLogix:PickListControl PickListName="Price Description" runat="server" ID="pklProgramDisplay"
            style='white-space:nowrap;' OnPickListValueChanged='pklProductProgram_PickListValueChanged'
            AutoPostBack="false" DisplayMode="AsText" PickListValue='<%# Eval("Program") %>' />
    </ItemTemplate>
    <EditItemTemplate>
        <SalesLogix:PickListControl PickListName="Price Description" runat="server" ID="pklProgram"
            style='white-space:nowrap;' OnPickListValueChanged='pklProductProgram_PickListValueChanged'
            AutoPostBack="true" DisplayMode="AsHyperlink" PickListValue='<%# Bind("Program") %>' />
    </EditItemTemplate>
</asp:TemplateField>

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 %>' >
    <ItemTemplate>
        <%# Eval("Program") %>
    </ItemTemplate>
    <EditItemTemplate>
        <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"  />
    </EditItemTemplate>
</asp:TemplateField>
 

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:TemplateField>
                            <ItemTemplate>
                                <asp:Label ID="lblProdID" runat="server" Text='<%# Eval("Product.Id") %>' Visible="false" />
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:HiddenField ID="hidProductId" runat="server" Value='<%#Eval("Product.Id") %>' />
                            </EditItemTemplate>
                        </asp:TemplateField>

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>();
        if(ProductId!=null)
        {
            Sage.Platform.RepositoryHelper<Sage.Entity.Interfaces.IProductProgram> repository =
            Sage.Platform.EntityFactory.GetRepositoryHelper<Sage.Entity.Interfaces.IProductProgram>();
            Sage.Platform.Repository.ICriteria criteria = repository.CreateCriteria();
            criteria.Add(repository.EF.Eq("Product.Id",ProductId.ToString()));
            criteria.AddOrder(repository.EF.Asc("Program"));
            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;
                        Sage.SalesLogix.Opportunity.Rules.CalcPriceFromProgramPrice(op);
                        break;
                }
              }   
    }

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
   Error Attempting to Save an Entity: "E_FAIL(0x80004005)" in the Infor CRM (Saleslogix) Web Client
We recently had a client that was running into an issue when attempting to create one particular entity i
Posted on Sep 30, 2014 by Kris Halsrud to Kris Halsrud's Blog
 
   Video: Demystifying Infor CRM (Saleslogix) Updates
Watch it now! If you missed yesterdays demo, "Demystifying Infor CRM (Saleslogix) Updates" ,
Posted on Sep 26, 2014 by Brianna Ojard to The Inbox
 
   Official Infor CRM Acquisition FAQ
What to expect now that Saleslogix is Infor CRM. Like many of you, it will take some time (probably a
Posted on Sep 18, 2014 by Brianna Ojard to The Inbox
 
   Problem with the Clean Build Folders option in Application Architect
On occasion, it becomes necessary to clean out the build folders and deployed website prior to a build/de
Posted on Sep 16, 2014 by Jason Buss to Jason Buss' Blog
 
   Restricting Adding Opportunity Contacts to Contacts at the Opportunity's Account
 One thing that clients have asked for is how to restrict the selection of the Opportunity Contacts
Posted on Sep 09, 2014 by Kris Halsrud to Kris Halsrud's Blog
 
Comments

 

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

(required)  
(optional)
(required)  
Add
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