Any way to avoid Postback when using 2 DDL fields tied to each other?

Dear All:

I have two DDL controls, state and city. The user needs to choose state and then the appropriate city (which appears once they've selected a state). Then I have a go button that simply sends the values of the two DDL to an ASP page. Here's my problem. There is a HUGE "blink" when the page posts back. Since I'm a beginning ASP.NET programmer and have probably programmed this in THE MOST INEFFICIENT way possible, can anybody suggest better code? Is it just the Access database that makes the postback so slow? We're moving to SQL Server soon but I just don't have the cycles to do it now.

Thanks a million.

Here's is the URL:

http://www.spa-addicts.com/gifts/default.aspx

And here's the code:


<%@ Page Language="VB" Debug="true" %>
<%@ Import Namespace="System.Data.OleDb" %>

<Script Runat="Server">

Sub Page_Load
  If Not IsPostBack Then
    Dim conAdv As OleDbConnection
    Dim cmdSelect As OleDbCommand
    Dim dtrAdv As OleDbDataReader

    conAdv = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\wwwroot\spa-addicts.com\database\spaadd.mdb")
    conAdv.Open()
    cmdSelect = New OleDbCommand( "SELECT state FROM advertiser WHERE advertiser.spa_id Is Not Null GROUP BY state;", conAdv )
    dtrAdv = cmdSelect.ExecuteReader()

    dropStates.DataSource = dtrAdv
    dropStates.DataTextField = "state"
    dropStates.DataBind()
      dropStates.Items.Insert(0, "Select a State")
      dropStates.SelectedIndex = 0
      
      dropCities.Items.Insert(0, "Select a City")
      dropCities.SelectedIndex = 0
      
    dtrAdv.Close()
    conAdv.Close()
  End If
End Sub

Sub fillDropCities_SelectedIndexChanged(s as Object, e as Eventargs)
    Dim conCity As OleDbConnection
    Dim cmdSelect As OleDbCommand
    Dim dtrCity As OleDbDataReader
    Dim selstate

    selstate = DropStates.SelectedValue
    conCity = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=d:\wwwroot\spa-addicts.com\database\spaadd.mdb")
    conCity.Open()
      
    cmdSelect = New OleDbCommand( "SELECT citysort FROM advertiser WHERE state = '" & selstate & "' group by citysort;", conCity )
    dtrCity = cmdSelect.ExecuteReader()

      dropCities.DataSource = dtrCity
      dropCities.DataTextField = "citysort"
      dropCities.DataBind()
      dropCities.Items.Insert(0, "Select a City")
      dropCities.SelectedIndex = 0
            
    dtrCity.Close()
    conCity.Close()
End Sub

Sub ImageButton_Click( s as Object, e as ImageClickEventArgs)
      Dim finalstate, finalcity
      finalstate = DropStates.SelectedValue
      finalcity = DropCities.SelectedValue
      Response.Redirect("/ScriptLibrary/accept_certs.asp?state=" & finalstate & "&city=" & finalcity & "")
End Sub
</Script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<!--#include virtual="/includes/meta.txt"-->
<link rel="stylesheet" type="text/css" href="/includes/master.css"></link>
</head>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
<!--#include virtual="/includes/top.txt"-->
<br style="line-height:8pt;">
<table width="98%" border="0" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top" bgcolor="#6180a5" style="color:#ffffff"><img src="/gifts/header.gif" width="585" height="131" hspace="0" vspace="0" border="0">      

<div class="indent">
Spa-Addicts Gift Certificates offer the perfect way to luxuriously pamper and de-stress a friend, colleague or loved one! Now you can purchase Spa-Addicts Gift Certificates and use them at your favorite spas across the United States. Enjoy the benefits of giving a gift you'd love to receive yourself!
<br>
<br>
<img src="/gifts/purchase.gif" width="535" height="93" hspace="0" vspace="0" border="0" usemap="#purchase">      
<map name="purchase"><area shape="rect" coords="284,0,479,90" href="/gifts/purchase.asp">
</map>
<br>
<br>

<table width=550 cellpadding="0" cellspacing="0">
<tr><td width="400" valign="top" bgcolor="#6180a5" style="color:#ffffff">
<strong style="font-size:13pt;">Find spas that accept spa-addicts gift certificates:</strong>
<br>
<table width=400 cellpadding="0" cellspacing="0">
<tr>
<td width="40"></td>
<td valign="top" bgcolor="#6180a5" style="color:#ffffff" width="170">
<img src="/gifts/select_state.gif" width="129" height="25" hspace="0" vspace="10" border="0"><div style="padding:8px; background-color:#A8B9CE; width:130px;">
<form Runat="Server">
<asp:DropDownList
  ID="dropStates"
  AutoPostBack="true"
  Runat="server" OnSelectedIndexChanged="fillDropCities_SelectedIndexChanged"  />
</div>
</td>
<td valign="top" bgcolor="#6180a5" style="color:#ffffff" width="170">
<img src="/gifts/select_city.gif" width="129" height="25" hspace="0" vspace="10" border="0"><div style="padding:8px; background-color:#A8B9CE; width:130px;">
<asp:DropDownList
  ID="dropCities"
  Runat="Server" />
</div>
</td>
<td width="63" valign="bottom" bgcolor="#6180a5">
<asp:ImageButton
  ImageUrl="/gifts/listspas_button.gif"
  OnClick="ImageButton_Click"
  Runat="Server" />
  </form>
</td>

</tr>
</table>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="fulllist.asp" style="color:#ffffcc">Click here</a> for a full list of participating spas.

</td><td bgcolor="#6180a5" width="150">
<img src="/gifts/illustration.gif" width="145" height="132" hspace="0" vspace="0" border="0">
</td></tr>
</table>


<br>

<strong style="font-size:13pt;"><font color="#FFFFFF">When redeeming Gift Certificates, the following rules apply:</font></strong><br>
    <br>
 
  <img src="/images/star_red.gif" align="left" width="14" height="14" border="0"> <strong><font color="#FFCCFF">Gift certificates may  NOT be applied towards ANY SPA-ADDICTS.COM SPECIALS, SPA DISCOUNTS OR PROMOTIONAL OFFERS (they may be used for full price services only). </font></strong><br>
    <br>
 
  <img src="/images/star_red.gif" align="left" width="14" height="14" border="0"> <font color="#FFCCFF"><strong>Gift certificates must be mentioned at the time of booking, presented at time of redemption, and be used within one-year expiration period. </strong></font></p>
<p><font color="#FFCCFF"><strong><img src="/images/star_red.gif" align="left" width="14" height="14" border="0">In states where expiration dates do not apply, certificates may be redeemed for merchandise indefinitely here. Please see Terms & Conditions below for details. </strong></font><br>
      <br><a href="#"><img src="/gifts/redeem_button.gif" vspace="8" hspace="8" align="right" border="0"></a>
      <strong><font color="#FFCCFF">Click here for the <a href="/gifts/tandc.asp">full terms and conditions</a>.
   
      </font></strong><br>
    <br>
   

</p>
</div>
</div>
</td>
  </tr>
</table>
<!--#include virtual="/includes/bottom.txt"-->
</body>
</html>
LVL 1
birsteinAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ihenryCommented:
Hello birstein,

You can use client javascript when populating the city dropdownlist. one example how to handle related data between two dropdownlist controls. copy the following code to aspx and aspx.vb, respectively. then run the page.

'--- aspx
<HTML>
     <HEAD>
          <title></title>
          <script language="javascript">
               var models = new Array (
                    new Array(
                              "http://www.thegioimobi.com/image/sanpham/bnokia-7600-1.gif",
                              "http://www.thegioimobi.com/image/sanpham/bnokia-7610.gif",
                              "http://www.thegioimobi.com/image/sanpham/bnokia-7650-1.gif"),
                    new Array(
                              "http://www.thegioimobi.com/image/sanpham/bmotorola-v600.gif",
                              "http://www.thegioimobi.com/image/sanpham/bmotorola-v60i.gif",
                              "http://www.thegioimobi.com/image/sanpham/bmotorola-v690.gif"),
                    new Array(
                              "http://www.thegioimobi.com/image/sanpham/bsiemens-sl45.gif",
                              "http://www.thegioimobi.com/image/sanpham/bsiemens-sl45i.gif",
                              "http://www.thegioimobi.com/image/sanpham/bsiemens-sl65.gif")
               )
          </script>
     </HEAD>
     <body>
          <form runat="server">
               <p align="center">
                    <asp:dropdownlist id="DropDownList1" runat="server" onchange="brand_onchange1(this);">
                         <asp:ListItem Value="0">Select one item...</asp:ListItem>
                         <asp:ListItem Value="1">Nokia</asp:ListItem>
                         <asp:ListItem Value="2">Motorolla</asp:ListItem>
                         <asp:ListItem Value="3">Siemens</asp:ListItem>
                    </asp:dropdownlist><br>
                    <br>
                    <asp:dropdownlist id="DropDownList2" runat="server" onchange="model_onchange();" />
                    <br>
                    <br>
                    <asp:Image id="Image1" runat="server"></asp:Image>
               </p>
          </form>
     </body>
</HTML>

'-- aspx.vb
Imports System.Text

Public Class WebForm2
    Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents DropDownList1 As System.Web.UI.WebControls.DropDownList
    Protected WithEvents DropDownList2 As System.Web.UI.WebControls.DropDownList
    Protected WithEvents JSPlaceHolder As System.Web.UI.WebControls.Literal
    Protected WithEvents Image1 As System.Web.UI.WebControls.Image

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        RegisterBrandModels()

        RegisterClientJS()

    End Sub

    Private Sub RegisterBrandModels()

        Dim js As New StringBuilder
        js.Append("<script language=""javascript"">").Append(Environment.NewLine)
        js.Append("<!--").Append(Environment.NewLine)
        js.Append("     var brandModels = new Array(3);").Append(Environment.NewLine)
        js.Append("     brandModels[0] = new Array(1);").Append(Environment.NewLine)
        js.Append("     brandModels[0][0] = new Option(""No brand is selected"", ""0"");").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.Append("     brandModels[1] = new Array(3);").Append(Environment.NewLine)
        js.Append("     brandModels[1][0] = new Option(""7600"", ""1"");").Append(Environment.NewLine)
        js.Append("     brandModels[1][1] = new Option(""7610"", ""2"");").Append(Environment.NewLine)
        js.Append("     brandModels[1][2] = new Option(""7650"", ""3"");").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.Append("     brandModels[2] = new Array(3);").Append(Environment.NewLine)
        js.Append("     brandModels[2][0] = new Option(""v600"", ""1"");").Append(Environment.NewLine)
        js.Append("     brandModels[2][1] = new Option(""v-60i"", ""2"");").Append(Environment.NewLine)
        js.Append("     brandModels[2][2] = new Option(""v-690"", ""3"");").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.Append("     brandModels[3] = new Array(3);").Append(Environment.NewLine)
        js.Append("     brandModels[3][0] = new Option(""SL-45"", ""1"");").Append(Environment.NewLine)
        js.Append("     brandModels[3][1] = new Option(""SL-45i"", ""2"");").Append(Environment.NewLine)
        js.Append("     brandModels[3][2] = new Option(""SL65"", ""3"");").Append(Environment.NewLine)
        js.Append("//-->").Append(Environment.NewLine)
        js.Append("</script>").Append(Environment.NewLine)

        RegisterClientScriptBlock("BrandModelsJS", js.ToString())
    End Sub

    Private Sub RegisterClientJS()

        Dim js As New StringBuilder
        js.Append("<script language=""javascript"">").Append(Environment.NewLine)
        js.Append("<!--").Append(Environment.NewLine)

        js.Append("function brand_onchange1( bid, mid ) {").Append(Environment.NewLine)
        js.AppendFormat("   var bddl = document.getElementById('{0}');", DropDownList1.ClientID).Append(Environment.NewLine)
        js.AppendFormat("   var mddl = document.getElementById('{0}');", DropDownList2.ClientID).Append(Environment.NewLine)
        js.Append("     if ( bid == null && mid == null)").Append(Environment.NewLine)
        js.Append("         return;").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.Append("     if ( bid!=null && mid==null ) {").Append(Environment.NewLine)
        js.Append("         bid=bddl.selectedIndex;").Append(Environment.NewLine)
        js.Append("     }").Append(Environment.NewLine)
        js.Append("     else if ( bid!=null && mid!=null) {").Append(Environment.NewLine)
        js.Append("         bddl.selectedIndex=bid;").Append(Environment.NewLine)
        js.Append("     }").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.Append("     var i").Append(Environment.NewLine)
        js.Append("     for (i=mddl.options.length; i>0; i--)").Append(Environment.NewLine)
        js.Append("         mddl.options[i] = null;").Append(Environment.NewLine)
        js.Append("     for (i=0; i<brandModels[bid].length; i++) {").Append(Environment.NewLine)
        js.Append("         mddl.options[i] = brandModels[bid][i];").Append(Environment.NewLine)
        js.Append("     }").Append(Environment.NewLine)
        js.Append("     if ( mid<=0 || mid>brandModels[bid].length )").Append(Environment.NewLine)
        js.Append("         mddl.options[0] = brandModels[0][0];").Append(Environment.NewLine)
        js.Append("     if ( mid==null) ").Append(Environment.NewLine)
        js.Append("         mid = 1;").Append(Environment.NewLine)
        js.Append("     else if ( mid<=0 || mid>brandModels[bid].length )").Append(Environment.NewLine)
        js.Append("         mddl.options[0] = brandModels[0][0];").Append(Environment.NewLine)
        js.Append("     else ").Append(Environment.NewLine)
        js.Append("         mddl.selectedIndex = mid -1;").Append(Environment.NewLine)
        js.Append(Environment.NewLine)
        js.AppendFormat("   var mimg = document.getElementById('{0}');", Image1.ClientID).Append(Environment.NewLine)
        js.Append("     if ( bid>0 && mid>0) ").Append(Environment.NewLine)
        js.AppendFormat("   mimg.src = models[bid-1][mid-1]").Append(Environment.NewLine)
        js.Append("     else ").Append(Environment.NewLine)
        js.Append("         mimg.src = null;").Append(Environment.NewLine)
        js.Append("}")

        js.Append(Environment.NewLine)

        js.Append("function model_onchange() {").Append(Environment.NewLine)
        js.AppendFormat("     window.navigate(""WebForm2.aspx?bid="" + document.getElementById(""{0}"").value + ""&mid="" + document.getElementById(""{1}"").value );", DropDownList1.ClientID, DropDownList2.ClientID).Append(Environment.NewLine)
        js.Append("}")

        js.Append(Environment.NewLine)

        If Not IsNothing(Request.Params("bid")) And Not IsNothing(Request.Params("mid")) Then
            js.AppendFormat("       brand_onchange1( {0}, {1});", Request.Params("bid"), Request.Params("mid")).Append(Environment.NewLine)
        End If

        js.Append("//-->").Append(Environment.NewLine)
        js.Append("</script>").Append(Environment.NewLine)

        RegisterStartupScript("ClientJS", js.ToString())
    End Sub

End Class

0
mureshanCommented:
Hi!
Another solution that comes to my mind is using multiple layers. For each state you create a layer that contains a dropdown list with all the cities in that state. When the user changes the selected state you simply show the layer containing all the cities that correspond to your new selected state.
You should use the server side programming for generating all the states' layers and Javascript on the client side in order to switch the visible layer according to the user's changes. This way you avoid all the round trip that is done during the postback.

The dimension of the page will grow significally but the flickering part will be avoided.

Regards,
Bogdan
0
birsteinAuthor Commented:
Dear Mureshan:

Good suggestion! Could you give me more details about how to implement your solution?
0
mureshanCommented:
Ok.. Let's see..
In the Page_Load method you bind your data source to your drop down list with all the states.
You can put in the design page a PlaceHolder control.
<asp:placeholder runat="server" id="theCities" />
For each state you add in the Page_Load method another PlaceHolder control with an Id that will be related to the value of the selected state.
For example for the state "AZ" you will have another PlaceHolder with the id "AZ".
In each PlaceHolder you will add dynamically a DropDownList Control that will contain all the cities for that state.
Also you need to add a JavaScript function that will handle the OnChange event on the client side. This JavaScript function will hide the old layer (corresponding to a PlaceHolder) and show the new one.

I hope that this is helping you out somehow.

Regards,
Bogdan
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
nsebastianCommented:
  Using a great deal of Web Controls makes your application running slow and is far to be the most efficient solutions for your problem. I think the best way you can handle the 2 DDL is to use XML, XSL and asp.net  caching techniques, considering that informations about states and  cities belongs to are rarely changed. So, you don’t have to make an access to DB for every request, you can get information from ASP.NET cache, send it to the client browser in XML format and than, using XSL techniques you can handle the DDL problem without making any post back actions

If there is a better technique somebody tell me!

Regards
Nicu
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.