Link to home
Start Free TrialLog in
Avatar of CJSantora
CJSantora

asked on

Problems with Dropdownlist and postback

I am populating a page with user controls dynamically. One of the control two dropdownlists. Once you make a selection in the first dropdown it populates the second. Here is the problem it only works on the second try. When you make a selection the first time it posts back, but no results are returned, if you try again, it works perfectly. I will post some code in the hopes that someone can help me find an answer.

as always I appreciate your help.
CJSantora

aspcx:

    <tr>
        <td align="left"><asp:Label ID="lblSearchManufacturers" runat="server" Text="Search By Manufacturer"></asp:Label></td>
        <td style="width: 81px" align="left"><asp:DropDownList ID="cboMakes" DataTextField="name" DataValueField="Makeid" runat="server" AutoPostBack=true Width="200px" OnSelectedIndexChanged="cboMakes_SelectedIndexChanged"></asp:DropDownList></td>
    </tr>
    <tr>
        <td align="left"><asp:Label ID="lblSearchByModel" runat="server" Text="Search By Model" Width="149px"></asp:Label></td>
        <td style="width: 81px" align="left"><asp:DropDownList ID="cboModels" DataTextField="name" DataValueField="modelid" runat="server" Width="200px"></asp:DropDownList></td>
    </tr>

code bhind:

public partial class includes__public_pubQuicktruckLocator : System.Web.UI.UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Page.SetFocus(cboMakes);
        populateMakes(0);
    }

    protected void cboMakes_SelectedIndexChanged(object sender, EventArgs e)
    {  
        int intmakeid = 0;            
        intmakeid = Convert.ToInt32(cboMakes.SelectedItem.Value);

        Response.Write(intmakeid);
        Response.Write(sender.ToString() + "<br>");
        Response.End();

        populateMakes(intmakeid);
        populateModels(intmakeid);
    }


    private void populateMakes(int intmakeid)
    {        
        cboMakes.DataSource = data.GetUniqueTrucksFromAds();
        cboMakes.DataBind();
        cboMakes.Items.Insert(0,new ListItem("All Makes","0"));
        cboMakes.Items.FindByValue(intmakeid.ToString()).Selected = true;
    }

    private void populateModels(int intmakeid)
    {
        cboModels.DataSource = data.GetUniqueTruckModelsFromAds(intmakeid);
        cboModels.DataBind();
        cboModels.Items.Insert(0, new ListItem("All Models", "0"));
    }

    protected void cmdQuickSearch_Click(object sender, ImageClickEventArgs e)
    {
        int intmakeid = 0;
        int intmodelid = 0;

        if (Convert.ToInt32(e.X) != 0 && Convert.ToInt32(e.Y) != 0)
        {

            if (cboMakes.SelectedIndex != 0)
            {
                intmakeid = Convert.ToInt32(cboMakes.SelectedItem.Value);
            }
            if (cboModels.SelectedIndex != 0)
            {
                intmodelid = Convert.ToInt32(cboModels.SelectedItem.Value);
            }
            Response.Redirect("~/default.aspx?pg=results&make=" + intmakeid + "&model=" + intmodelid);
        }
    }

}
Avatar of dstanley9
dstanley9

in this case, you don't need to DataBind() the Makes on each call.  In fact, re-binding the data will cause you to lose your SelectedItem value. try:

    protected void Page_Load(object sender, EventArgs e)
    {
        Page.SetFocus(cboMakes);
        if(!IsPostBack)
          populateMakes(0);
    }
Avatar of CJSantora

ASKER

I really appreciate your feedback dstanley9. I tried your suggestion, however the dropdownlist does not populate under this condition. The control is activated by a tabbed imagemap, so I think when you click on the tab to display the truck search it causes a postback and this is why there was no data bound to the control.


CJSantora
Can you move the code:

          populateMakes(0);

to the event hadler fired when the tab is selected?
I am not sure if that is a possibility or not, I will look into it. I have an additional question, and this may be a strech, but can you determine if the Postback was from a specific user control?

CJSantora
I've never tried it myself, but you can try this method:

http://www.eggheadcafe.com/articles/20050609.asp
I thought I would post an additional finding that may offer some new ideas. The drowdownlist is using OnSelectedIndexChanged="cboMakes_SelectedIndexChanged to trigger the population of the next dropdownlist. I have determined that this is not happening on the first post, can anyone think of any reasons that the page would not see the OnSelectedIndexChanged="cboMakes_SelectedIndexChanged?

CJSantora
IIRC, When you re-bind a control in Page_Load, it "clears" any events that would be triggered by the control (including SelectedIndexChanged).  That is one reason why you don't re-bind unless the request is not a post back.
I remmber you stating that in an earlier post and I continued trying to modify the code to eliminate that possibility. The code that is currently being executed does not do a second databind, but still does not return the proper id from the dropdownlist on the first post;

    protected void Page_Load(object sender, EventArgs e)
    {
        //Response.Write(cboMakes.Items.Count + "<br>");
        if (cboMakes.Items.Count == 0)
        {
            populateMakes();
        }
        else
        {
            populateModels();
        }

    }

    private void populateMakes()
    {        
        cboMakes.DataSource = data.GetUniqueTrucksFromAds();
        cboMakes.DataBind();
        cboMakes.Items.Insert(0, new ListItem("All Makes", "0"));
    }

    protected void cboMakes_SelectedIndexChanged(object sender, EventArgs e)  // NOT BEING CALLED AT ALL NOW
    {
        Response.Write("Index Changed");
        populateModels();
    }

    private void populateModels()
    {

        int intmakeid = 0;
        intmakeid = Convert.ToInt32(cboMakes.Selecteditem.Value);  // IS ALWAYS RETURNING ZERO ON FIRST PASS
        Response.Write(intmakeid);

        cboModels.DataSource = data.GetUniqueTruckModelsFromAds(intmakeid);
        cboModels.DataBind();
        cboModels.Items.Insert(0, new ListItem("All Models", "0"));
    }

    protected void cmdQuickSearch_Click(object sender, ImageClickEventArgs e)
    {
        int intmakeid = 0;
        int intmodelid = 0;

        if (Convert.ToInt32(e.X) != 0 && Convert.ToInt32(e.Y) != 0)
        {

            if (cboMakes.SelectedIndex != 0)
            {
                intmakeid = Convert.ToInt32(cboMakes.SelectedItem.Value);
            }
            if (cboModels.SelectedIndex != 0)
            {
                intmodelid = Convert.ToInt32(cboModels.SelectedItem.Value);
            }
            Response.Redirect("~/default.aspx?pg=results&make=" + intmakeid + "&model=" + intmodelid);
        }
    }

I really appreciate your help.
CJSantora
ASKER CERTIFIED SOLUTION
Avatar of dstanley9
dstanley9

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial