Setting DropDown Options Dynamically Based on OnSelectedIndexChanged Value in Custom Web Part

Jeff Gibbs asked on January 22, 2017 05:02

Hi, Using Kentico 9. I am populating two DropDownLists with Custom Table data in the OnContentLoaded() method of a custom web part. This works great, but I'm struggling with updating the options of the second drop down list when the first drop down list is changed - similar to how the Country/State selector works.

This is a more simple example of what I'm trying to do. The first DropDownList has an id of "category". The second has an id of "part". So I want to be able to populate part based on the value of category, But I'm not exactly sure how to get the category.SelectedValue from within the OnContentLoaded() method.

Any Ideas?

public override void OnContentLoaded()
{
    base.OnContentLoaded();
    DataSet categoryResult = new DataQuery("Custom.CategoriesTable.selectall")
    .Columns("CategoryId", "CategoryName")
    .Execute();
    DataTable categories = categoryResult.Tables[0];
    if (this.categories.Rows.Count > 0)
    {
        category.DataSource = countries;
        category.DataTextField = "CategoryName";
        category.DataValueField = "CategoryId";
        category.DataBind();
    }

    // THIS IS WHERE I NEED TO GET THE SELECTED VALUE OF CATEGORY
    // I'VE TRIED THIS
    if (IsPostBack) 
    {
        int categoryId = Int32.Parse(category.SelectedValue); // This doesn't seem to work
        DataSet partsResult = new DataQuery("Custom.Parts.selectall")
        .Columns("partId", "partName")
        .Where("categoryId", QueryOperator.Equals, categoryId)
        .Execute();
        DataTable parts = partsResult.Tables[0];
        if (parts.Rows.Count > 0)
        {
            part.DataSource = parts;
            part.DataTextField = "partName";
            part.DataValueField = "partId";
            part.DataBind();
        }
     }   
 }

Recent Answers


Suneel Jhangiani answered on January 22, 2017 14:52

I personally think you may be trying to load the data in the wrong way and should use the 'category' OnSelectedIndexChanged event, such that when the Category is changed the 'parts' are loaded. If you look at the CountrySelector source you will see it uses the uniSelectorCountry_OnSelectionChanged() method to change the states.

The issue I believe you are experiencing is that the 'categories' are always being reloaded and hence the SelectValue is getting reset, thus you are always getting a 'categoryId' of 0.

0 votesVote for this answer Mark as a Correct answer

Roman Hutnyk answered on January 23, 2017 07:04

Populate only first (category) drop down in the OnContentLoaded method. Use SelectedIndexChanged event of the first drop down to populate second one. Make sure AutoPostBack property of the drop down is set to true.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on January 23, 2017 15:10

Agree with both Suneel and Roman. The selected value or index of the dropdown will not be available to be retrieved or set until after viewstate is loaded. So if you attempt to do it OnContentLoaded() it will fail every time. In the OnContentLoaded(), assign the selected event changed event to the dropdown and in that event, perform your actions needed. Do not check for postback in your OnContentLoaded() as this will not give you what you need.

0 votesVote for this answer Mark as a Correct answer

Jeff Gibbs answered on January 23, 2017 16:40

Thanks for the feedback. I really appreciate your time. I originally tried this approach, but I had difficulty getting the part.SelectedValue on postback when I went to save the submitted data. I figured that since the part options weren't populated in OnContentLoaded the system wasn't able to determine the part.SelectedValue in my save data postback.

Brandon, Is there a difference in how Kentico handles the onSelectionChanged event if I set it on the category drop down control in my form versus setting it programmatically in the onContentLoaded event?

I'll revisit this approach and be sure I didn't have something else in my code preventing the part.SelectedValue from working.

Thanks again.

0 votesVote for this answer Mark as a Correct answer

Suneel Jhangiani answered on January 24, 2017 15:20 (last edited on January 24, 2017 15:22)

There should be no difference in how Kentico handles the OnSelectionChanged event when set in Code-Behind or via the form. However, the Kentico Web Part lifecycle is slightly different to the ASP.Net Page Lifecycle.

I believe that your issue is being cause by the fact the OnContentLoaded event is firing before the OnSelectionChanged event and hence you are actually recreating the 'catgories' dropdown which in turn removes the selected value.

I haven't tested this but the below should work:

public override void OnContentLoaded()
{
    base.OnContentLoaded();

    if (!IsPostBack)
    {
        InitializeCategories();
    }

    // THIS IS WHERE I NEED TO GET THE SELECTED VALUE OF CATEGORY
    // I'VE TRIED THIS
    if (IsPostBack) 
    {
        int categoryId = Int32.Parse(category.SelectedValue); // This doesn't seem to work
        DataSet partsResult = new DataQuery("Custom.Parts.selectall")
        .Columns("partId", "partName")
        .Where("categoryId", QueryOperator.Equals, categoryId)
        .Execute();
        DataTable parts = partsResult.Tables[0];
        if (parts.Rows.Count > 0)
        {
            part.DataSource = parts;
            part.DataTextField = "partName";
            part.DataValueField = "partId";
            part.DataBind();
        }
     }   
 }    

 private void InitializeCategories()
 {        
    DataSet categoryResult = new DataQuery("Custom.CategoriesTable.selectall")
        .Columns("CategoryId", "CategoryName")
        .Execute();
    DataTable categories = categoryResult.Tables[0];
    if (this.categories.Rows.Count > 0)
    {
        category.DataSource = countries;
        category.DataTextField = "CategoryName";
        category.DataValueField = "CategoryId";
        category.DataBind();
    }
}
0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.