This is a migrated thread and some comments may be shown as answers.

ComboBox in EditTemplate not updating OnItemsRequested while Grid in Edit mode (Insert/Add mode updates fine)

1 Answer 232 Views
ComboBox
This is a migrated thread and some comments may be shown as answers.
Jeremy
Top achievements
Rank 1
Jeremy asked on 19 Nov 2010, 02:45 AM
I am using ASP.NET AJAX v2010.2.929.35.

I have a RadGrid on a page, using EditMode=Popup. I have two separate GridTemplateColumns, both contain a separate RadComboBox (RadComboBoxSport and RadComboBoxPositionCategory). What I am trying to accomplish is this: in Edit or Insert mode, when you choose an item from RadComboBoxSport (OnSelectedIndexChanged) it will grab the SelectedValue of RadComboBoxSport, and call ItemsRequested() on RadComboBoxPositionCategory and pass in the selected value to the server side code (protected void RadComboBoxPositionCategory_ItemsRequested). Based on the value chosen in RadComboBoxSport , it will update the values in RadComboBoxPositionCategory accordingly.

This all works very well in INSERT/ADD mode, but when it comes to editing an existing record it fails update the values in RadComboBoxPositionCategory at all, it leaves the values that were there when the edit popup window appeared.  I believe the issue may be related to a mixture of this post and this post (I've tried attaching the event handler in the ItemCreated method but it did not work).

I have stepped through the code on the server side, specifically the method  and I have found that RadComboBoxPositionCategory_ItemsRequested (this is combo box # 2) has DIFFERENT RadComboBox.UniqueID's passed in to it. When in INSERT/ADD mode, the ComboBox has a UniqueID of:
ctl00$ctl00$MasterMainContent$MainContent$ucSetupPosition$RadGrid1$ctl00$ctl02$ctl03$RadComboBoxPositionCategory

but when in Edit mode the UniqueID is:
ctl00$ctl00$MasterMainContent$MainContent$ucSetupPosition$RadGrid1$ctl00$ctl11$RadComboBoxPositionCategory

So it seems like the RadComboBoxPositionCategory isn't being updated during EDIT mode because it is actually a different RadComboBox that is generated at runtime maybe? Regardless, I can't get it to update the values. The code executes just fine in the RadComboBoxPositionCategory_ItemsRequested method, and focus returns back to the second combo box, but values are not updated.

I have included some key snippets of code for you.

ASPX:
<script type="text/javascript">
    // Must hard code IDs due to Telerik quirkiness
    var radComboPosCatID = 'RadComboBoxPositionCategory';
    function RadComboBoxSport_SelectedIndexChanged(sender, eventArgs) {
        var comboSport = eventArgs.get_item();
        var comboPosCat = GetRadComboBoxFromPage(radComboPosCatID);
        if (comboPosCat != null && comboSport.get_value() > 0) {
            comboPosCat.clearSelection();
            // Fire off call to refresh Position Category dropdown
            comboPosCat.requestItems(comboSport.get_value(), false); // false=clear items
        }
    }
 
    function RadComboBoxPositionCategory_ItemsRequested(sender, eventArgs) {
        //TODO: Resolve issue where, if Grid is in Edit mode (vs. insert mode), this method will not fire
        // and dropdown will not update!
        var comboPosCat = sender;
        comboPosCat.set_text(sender.get_items().getItem(0).get_text());
        if (sender.get_items().get_count() > 0) {
            comboPosCat.showDropDown();
        }
    }
</script>
<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" Skin="WebBlue" />
<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server" LoadingPanelID="RadAjaxLoadingPanel1">
    <asp:Label id="StatusMessage" runat="server" CssClass="errorText" />
    <telerik:RadGrid ID="RadGrid1" runat="server"
        AllowPaging="True"
        AllowSorting="True"
        AutoGenerateColumns="false"
        Skin="WebBlue"
        OnNeedDataSource="RadGrid1_NeedDataSource"
        OnUpdateCommand="RadGrid1_UpdateCommand"
        OnInsertCommand="RadGrid1_InsertCommand"
        OnDeleteCommand="RadGrid1_DeleteCommand"
        OnItemDataBound="RadGrid1_ItemDataBound">
        <PagerStyle
            VerticalAlign="Bottom"
            Mode="NextPrev" />
        <ClientSettings Scrolling-AllowScroll="true" />
        <MasterTableView
            EditMode="PopUp"
            DataKeyNames="PositionId,SportId,PositionCategoryId"
            CommandItemDisplay="Top">
            <EditFormSettings
                CaptionFormatString="Edit Position"
                InsertCaption="Add Position"
                PopUpSettings-Modal="false"
                EditColumn-ButtonType="ImageButton" />
                <Columns>
                    <telerik:GridEditCommandColumn ButtonType="ImageButton">
                        <HeaderStyle Width="30px" />
                        <ItemStyle Width="30px" HorizontalAlign="Center" />
                    </telerik:GridEditCommandColumn>
                    <telerik:GridButtonColumn ButtonType="ImageButton" CommandName="Delete" Text="Delete" UniqueName="DeleteColumn"
                        ConfirmDialogType="Classic" ConfirmText="Are you sure you want to delete?">
                        <HeaderStyle Width="30px" />
                        <ItemStyle Width="30px" HorizontalAlign="Center" />
                    </telerik:GridButtonColumn>
                    <telerik:GridTemplateColumn UniqueName="Sport" SortExpression="Sport.Name" HeaderText="Sport" DataField="Sport.Name">
                        <ItemTemplate>
                            <asp:Label ID="lblSport" runat="server" Text='<%# Eval("Sport.Name") %>' />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <telerik:RadComboBox runat="server" ID="RadComboBoxSport" AutoPostBack="true" OnClientSelectedIndexChanged="RadComboBoxSport_SelectedIndexChanged" />
                            <asp:RequiredFieldValidator runat="server" ID="rfvSport" ControlToValidate="RadComboBoxSport" InitialValue="Select..." Text="*" />
                        </EditItemTemplate>
                    </telerik:GridTemplateColumn>                   
                    <telerik:GridTemplateColumn UniqueName="PositionCategory" SortExpression="PositionCategory.CategoryName" HeaderText="Position Category" DataField="PositionCategory.CategoryName">
                        <ItemTemplate>
                            <asp:Label ID="lblPositionCategory" runat="server" Text='<%# Eval("PositionCategory.CategoryName") %>' />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <telerik:RadComboBox runat="server" ID="RadComboBoxPositionCategory" EmptyMessage="Select a sport first..." OnClientItemsRequested="RadComboBoxPositionCategory_ItemsRequested" OnItemsRequested="RadComboBoxPositionCategory_ItemsRequested" />
                            <asp:RequiredFieldValidator runat="server" ID="rfvPositionCategory" ControlToValidate="RadComboBoxPositionCategory" InitialValue="Select..." Text="*" />
                        </EditItemTemplate>
                    </telerik:GridTemplateColumn>                   
                    <telerik:GridTemplateColumn UniqueName="PositionName" SortExpression="Name" HeaderText="Position Name" DataField="Name">
                        <ItemTemplate>
                            <div></div>
                            <asp:Label ID="lblPositionName" runat="server" Text='<%# Eval("Name") %>' />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:TextBox runat="server" ID="txtPositionName" Text='<%# Bind("Name") %>' />
                            <asp:RequiredFieldValidator runat="server" ID="rfvPositionName" ControlToValidate="txtPositionName" Text="*" />
                        </EditItemTemplate>
                    </telerik:GridTemplateColumn>
                    <telerik:GridBoundColumn ReadOnly="true" UniqueName="LastUpdatedDate" SortExpression="LastUpdatedDate" HeaderText="Last Updated" DataField="LastUpdatedDate" DataFormatString="{0:g}" AllowSorting="false" />
                </Columns>
        </MasterTableView>
    </telerik:RadGrid>
</telerik:RadAjaxPanel>

Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
 
}
 
#region Grid Events
 
protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
    PositionCollection positions = new PositionCollection();
    positions = PositionBuilder.RetrieveList();
    RadGrid1.DataSource = positions;
}
 
protected void RadGrid1_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
    try
    {
        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            GridEditableItem item = e.Item as GridEditableItem;
 
            #region Sport Dropdown
            // Bind values to Sport dropdown list in edit/insert mode
            RadComboBox ddlSport = item.FindControl("RadComboBoxSport") as RadComboBox;
            SetSportOptions(ddlSport);
            // If in "Add" mode, ItemIndex == -1. We only want to load value in edit mode
            if (item.ItemIndex != -1)
            {
                int sportId = 0;
                Int32.TryParse(item.OwnerTableView.DataKeyValues[item.ItemIndex]["SportId"].ToString(), out sportId);
                ddlSport.SelectedValue = sportId.ToString();
 
                #region Position Category Dropdown
                // Bind values to Position Category dropdown list in edit mode ONLY if sportId is available
                if (sportId > 0)
                {
                    RadComboBox ddlPosCats = item.FindControl("RadComboBoxPositionCategory") as RadComboBox;
                    SetPositionCategoryOptions(ddlPosCats, sportId);
                    if (item.ItemIndex != -1)
                    {
                        int postCatid = 0;
                        Int32.TryParse(item.OwnerTableView.DataKeyValues[item.ItemIndex]["PositionCategoryId"].ToString(), out postCatid);
                        ddlPosCats.SelectedValue = postCatid.ToString();
                    }
                }
                #endregion
            }
            #endregion
 
        }
    }
    catch (Exception ex)
    {
        StatusMessage.Text = "Error: " + ex.Message;
        e.Canceled = true;
    }
}
 
protected void RadGrid1_UpdateCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
    try
    {
        // Clear out status message
        StatusMessage.Text = String.Empty;
 
        // Get the GridEditableItem of the RadGrid    
        GridEditableItem editedItem = e.Item as GridEditableItem;
 
        // Get the primary key value using the DataKeyValue   
        int positionId = Convert.ToInt32(editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["PositionId"]);
 
        string positionName = (editedItem.FindControl("txtPositionName") as TextBox).Text;
        int sportId = Convert.ToInt32((editedItem.FindControl("RadComboBoxSport") as RadComboBox).SelectedValue);
        int posCatId = Convert.ToInt32((editedItem.FindControl("RadComboBoxPositionCategory") as RadComboBox).SelectedValue);
 
        // Update value in table
        if (positionId > 0 && !String.IsNullOrEmpty(positionName) && sportId > 0 && posCatId > 0)
        {
            if (!PositionBuilder.Update(positionId, positionName, posCatId, sportId, DateTime.UtcNow, Page.UserId))
            {
                StatusMessage.Text = "Unable to update value. Please try again.";
                e.Canceled = true;
            }
            else
            {
                StatusMessage.Text = "Successfully updated value!";
            }
        }
 
        // Redraw grid
        RadGrid1.Rebind();
    }
    catch (Exception ex)
    {
        StatusMessage.Text = "Unable to update record. Reason: " + ex.Message;
        e.Canceled = true;
    }
}
 
protected void RadGrid1_InsertCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
    try
    {
        // Clear out status message
        StatusMessage.Text = String.Empty;
 
        GridEditFormInsertItem insertedItem = (GridEditFormInsertItem)e.Item;
 
        string positionName = (insertedItem.FindControl("txtPositionName") as TextBox).Text;
        int sportId = Convert.ToInt32((insertedItem.FindControl("RadComboBoxSport") as RadComboBox).SelectedValue);
        int posCatId = Convert.ToInt32((insertedItem.FindControl("RadComboBoxPositionCategory") as RadComboBox).SelectedValue);
 
        if (!String.IsNullOrEmpty(positionName) && sportId > 0 && posCatId > 0)
        {
            Position newPos = PositionBuilder.Add(positionName, posCatId, sportId, DateTime.Now, Page.UserId, DateTime.Now, Page.UserId);
            if (newPos.PositionId <= 0)
            {
                StatusMessage.Text = "Unable to insert record. Please try again.";
                e.Canceled = true;
            }
            else
            {
                StatusMessage.Text = "Successfully inserted record!";
            }
        }
    }
    catch (Exception ex)
    {
        StatusMessage.Text = "Unable to insert record. Reason: " + ex.Message;
        e.Canceled = true;
    }
}
 
protected void RadGrid1_DeleteCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
    try
    {
        int positionId = Convert.ToInt32(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["PositionId"]);
 
        //TODO: SOFT DELETE
    }
    catch (Exception ex)
    {
        StatusMessage.Text = "Unable to delete record. Reason: " + ex.Message;
        e.Canceled = true;
    }
}
 
#endregion
 
#region ComboBox
 
protected void RadComboBoxPositionCategory_ItemsRequested(object source, Telerik.Web.UI.RadComboBoxItemsRequestedEventArgs e)
{
    try
    {
        //e.Text returns the value of the text parameter set on the client-side
        RadComboBox combo = (RadComboBox)source;
        combo.Items.Clear();
        int sportId = Convert.ToInt32(e.Text);
 
        SetPositionCategoryOptions(combo, sportId);
    }
    catch
    {
        // Do nothing
    }
}
 
#endregion
 
#region Dropdown Helpers
 
public void SetSportOptions(RadComboBox comboBox)
{
    RadComboBoxItemCollection items = new RadComboBoxItemCollection(comboBox);
    comboBox.Items.Add(new RadComboBoxItem("Select...", 0.ToString()));
 
    try
    {
        SportCollection sports = SportBuilder.RetrieveList(String.Empty, "Name ASC");
        foreach (Sport sport in sports)
        {
            comboBox.Items.Add(new RadComboBoxItem(sport.Name, sport.SportId.ToString()));
        }
    }
    catch
    {
        // Do nothing
    }
}
 
private void SetPositionCategoryOptions(RadComboBox comboBox, int sportId)
{
    RadComboBoxItemCollection items = new RadComboBoxItemCollection(comboBox);
    comboBox.Items.Add(new RadComboBoxItem("Select...", 0.ToString()));
    comboBox.SelectedValue = 0.ToString();
 
    try
    {
        PositionCategoryCollection posCats = PositionCategoryBuilder.RetrieveList(
            String.Format("SportId={0}",sportId), "CategoryName ASC");
        foreach (PositionCategory cat in posCats)
        {
            comboBox.Items.Add(new RadComboBoxItem(cat.CategoryName, cat.PositionCategoryId.ToString()));
        }
    }
    catch
    {
        // Do nothing
    }
}
 
#endregion

Any ideas on how I can get this second combobox to update on the client side while in Edit mode?

1 Answer, 1 is accepted

Sort by
0
Kalina
Telerik team
answered on 24 Nov 2010, 07:04 PM
Hello Jeremy,

As I understand you face difficulties to obtain the RadComboBox client-side object in order to perform a request for items. You can overcome this issue by creating a global client-side variable to hold this object and initialize this variable at RadComboBox OnClientLoad event.
Additionally I will recommend you set the EnableViewState property of the second RadComboBox to "false".
Then when you change the selected index of one RadComboBox you will be able to populate with data the second RadComboBox.
<script type="text/javascript">
 
    var comboBox;
     
    function OnClientLoadHandler(sender) {
        comboBox = sender;
    }
    function OnClientSelectedIndexChangedHandler(sender, eventArgs) {
        comboBox.clearSelection();
        comboBox.requestItems(sender.get_selectedItem().get_value(), false);
        comboBox.showDropDown();
    }
                  
</script>


In order to set a preselected item at RadComboBox at RadGrid "Edit" mode - please handle the ItemDataBound event:
protected void RadGrid1_ItemDataBound(object sender, GridItemEventArgs e)
{
    if (e.Item is GridEditableItem && e.Item.IsInEditMode)
    {
        ...
        ...
        ...
 
        if (!(e.Item is IGridInsertItem))
        {
            RadComboBox combo = (RadComboBox)editedItem.FindControl("rcbCities");
            GridEditFormItem container = (GridEditFormItem)combo.NamingContainer;
            DataRowView dataItem = (DataRowView)container.DataItem;
 
            RadComboBoxItem preselectedItem = new RadComboBoxItem();
            preselectedItem.Text = dataItem["CityName"].ToString();
            preselectedItem.Value = dataItem["CityID"].ToString();
            combo.Items.Insert(0, preselectedItem);
            combo.SelectedIndex = 0;
        }
    }
     
}

Since I do not have the custom classes and database that you use - I created test page similar to yours and a simplified database. There are three related RadComboBox controls nested within a RadGrid at the sample,  and they represent a the relation between Continent, Country and City.

Please find the example attached.


Greetings,
Kalina
the Telerik team
Browse the vast support resources we have to jumpstart your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
Tags
ComboBox
Asked by
Jeremy
Top achievements
Rank 1
Answers by
Kalina
Telerik team
Share this question
or