Question

I have two dropdown ddlCountry and ddlState and one button Submit.
While ddlstate is in update panel.
On submit of button value of both dropdown store in database.
And I show the data in Repeater Control.(In HTML Table structure) ASPX CODE

<table id="tablelist" class="csstablelist" cellspacing="1" cellpadding="1">
                    <tr>
                        <td class="csstablelisttoptr">
                            ddlCountryID
                        </td>
                        <td class="csstablelisttoptr">
                            ddlCountryText
                        </td>
                        <td class="csstablelisttoptr">
                            ddlstateText
                        </td>
                    </tr>
                    <asp:Repeater ID="repeaterList" runat="server" OnItemDataBound="repeaterList_ItemDataBound">
                        <ItemTemplate>
                            <tr onclick="selectRow(this);">
                                <td class="csstablelisttd" style="display: none">
                                    <asp:Label ID="ddlCountryID" runat="server" Text='<%#Eval("ddlCountryID")%>'></asp:Label>
                                </td>
                                <td class="csstablelisttd">
                                    <asp:Label ID="ddlCountryText" runat="server" Text='<%#Eval("ddlCountryText")%>'></asp:Label>
                                </td>
                                <td class="csstablelisttd">
                                    <asp:Label ID="ddlstateText" runat="server" Text='<%#Eval("ddlstateText")%>'></asp:Label>
                                </td>
                            </tr>
                        </ItemTemplate>
                    </asp:Repeater>
                </table>
<asp:DropDownList ID="ddlCountry" runat="server" CssClass="csstextbox" Width="207px" AutoPostBack="true" OnSelectedIndexChanged="ddlCountry_SelectedIndexChanged">
</asp:DropDownList>
<asp:UpdatePanel ID="updatePanelState" runat="server">
    <ContentTemplate>
        <asp:DropDownList ID="ddlState " runat="server" CssClass="csstextbox" Width="177px">
        </asp:DropDownList>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="ddlCountry" EventName="SelectedIndexChanged" />
    </Triggers>
</asp:UpdatePanel>
<asp:Button ID="btnSave" runat="server" Width="80px" OnClientClick="return validateForm();" Text="Save" CssClass="cssbutton" OnClick="btnSave_Click" />


ddlCountryID | ddlCountryText | ddlstateText
1            | USA            | XYZ
2            |India           | PQR

Onclick of TR i write below (SelectRow(this)) function in javascript for highliting the repeater value and dropdown value match and getting selected.

<script type="text/javascript">
function selectRow(objTR)
{
 var ddlCountry =document.getElementById('<%=ddlCountry.ClientID %>');
 var ddlState =document.getElementById('<%=ddlState .ClientID %>');

    for (i = 0; i < ddlCountry .options.length; i++)
    {
        if (ddlCountry .options[i].text == objTR.cells[1].innerText.trim())
            break;
    }           
    ddlCountry .options[i].selected = true;

    __doPostBack(ddlCountry .id, objTR.cells[2].innerText.trim());    
}
</script>

I write ddlCountry SelectedIndexChangedEvent In code behind.

From Javascript I am firing __doPostBack() and passing ddlCountry as event target ddlStateText as event argument to SelectedIndexChangedEvent and getting value in event like this.

string stateDescription = Request["__EVENTARGUMENT"];
ddlState .Items.FindByText(stateDescription ).Selected = true;//for highliting the repeater value and dropdown value match and selected

Binding Country on pageLoad

 if(!Ispostback)
protected Void BindCountry()

{

strSQL = @"SELECT countryID,Country from Country_Master";
        DataTable dataTableCountry = null;
        dataTableCountry = objSqlDbComm.ExecuteDatasetQuery(strSQL).Tables[0];

        int countryID;
                string Country;     
        var dictioneryCountry = new Dictionary<int, string>();
        foreach(DataRow dr in dataTableCountry.Rows)
        {
            countryID = Convert.ToInt32(dr["countryID"]);
            Country= dr["Country"].ToString();          
            dictioneryCountry.Add(countryID,Country);
        }
        ddlCountry.Items.Clear();
        ddlCountry.DataTextField = "Value";
        ddlCountry.DataValueField = "Key";
        ddlCountry.DataSource = dictioneryCountry;
        ddlCountry.DataBind();
        ddlCountry.Items.Insert(0, new ListItem("[Select]", "-1"));
        ddlCountry.Items[0].Selected = true;
}

My problem is if I have following repeater data.

ddlCountryID | ddlCountryText | ddlstateText
1            | USA            | XYZ
2            |India           | PQR
2            |India           | MNO

When I select row number 3 that have country india and state mno then __dopostback() method is fire.

When I goes to row number 1 then __dopostback() method is fire.

When I come from row nuber 1 to 3 then method is fire correct way but when goes from row nuber 3 to 2 having country id same __dopostback() method is not fire and state is not selected from ddlstate.

Was it helpful?

Solution

If you debug your code, you will see that __doPostBack() is indeed working because the code in Page_Load is being executed (try setting a breakpoint here to check). The issue is that the index of your DropDownList is not changing, therefore the IndexChanged event is not fired and ddlCountry_SelectedIndexChanged never runs. When you call __doPostBack(), this not the same as manually calling ddlCountry_SelectedIndexChanged from the codebehind.

Is there a particular reason that you would be doing a post back other than to set this dropdown list value?

SOLUTION 1

I would advise removing the __doPostBack() line and adding the following instead:

var state = objTR.cells[2].innerText.trim();
for (var i = 0; i < ddlState.options.length; i++)
{
    if (ddlState.options[i].text == state)
    {
        ddlState.options[i].selected = true;
        break;
    }
}

SOLUTION 2

Alternatively, if you really have to post back, you could do the following:

a. Add a hidden button inside of your update panel like this:

<div style="display: none">
<asp:Button ID="btnState" OnClick="btnState_Click" runat="server" />
</div>

b. Change your javascript to do the following after selecting the country:

document.getElementById('__EVENTARGUMENT').value = objTR.cells[2].innerText.trim();
document.getElementById('<%= btnState.ClientID %>').click();

c. Create a FilterState() function and call this from your ddlcountry indexchanged event

protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e)
{
    FilterState();
}

private void FilterState()
{
// insert whatever filtering code you had here
}

d. Add your btnState_Click function (note that the way you were setting the selected item of ddlState before would throw an error if an item was already selected.):

protected void btnState_Click(object sender, EventArgs e)
{
    FilterState();
    string state = Request["__EVENTARGUMENT"];
    if (state != "")
        ddlState.SelectedValue = state;
}

SOLUTION 3

A third solution would allow you to still use __doPostBack, and scrap the SelectedIndexChanged event altogether by putting this in the Page_Load function:

if (IsPostBack && Request["__EVENTTARGET"] == ddlCountry.UniqueID)
{
    FilterState();
    string stateDescription = Request["__EVENTARGUMENT"];
    if (stateDescription != "")
        ddlState.SelectedValue = stateDescription;
}

On another note, for your BindCountry function there's no real reason to use a Dictionary, you can just bind the DataTable directly:

strSQL = @"SELECT countryID,Country from Country_Master";
DataTable dataTableCountry = objSqlDbComm.ExecuteDatasetQuery(strSQL).Tables[0];
ddlCountry.Items.Clear();
ddlCountry.DataSource = dataTableCountry;
ddlCountry.DataTextField = "Country";
ddlCountry.DataValueField = "countryID";
ddlCountry.DataBind();
ddlCountry.Items.Insert(0, new ListItem("[Select]", "-1"));
ddlCountry.Items[0].Selected = true;

OTHER TIPS

This may be because you are not binding separate Value for dropdownlist for Text = "India", thus server is not recognizing that the value is changed and thus not processing selectedindexchanged event.

Try to create a datasouce that has different value for both the India text or just use one India Text

I can clearly see that there are two duplicate reocords in listview for India with duplicate key (2)

This is not recommended. use only one record that should have unique key.

I can understand you have only one data source thus modify your code in such a way that while adding items to the ddlCountry check if that already exists or not if exists just don't add it again. replace the followign code in your Bindcontry code and it should work fine.

    foreach(DataRow dr in dataTableCountry.Rows)
    {
        countryID = Convert.ToInt32(dr["countryID"]);
        Country= dr["Country"].ToString();

        if ( ! dictioneryCountry.Contains(countryID))
        {
           dictioneryCountry.Add(countryID,Country);
        }
    }

Let me know if it works

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top