如何创建一个动态列表框(根据需求从数据库中读取相应的项)(2)?

发表于:2007-06-30来源:作者:点击数: 标签:
The get_list.asp Page The only remaining part of the task is to create the page get_list.asp, which queries the database to get the matching list of values, and copies these values into the appropriate list box on the main page. The way we
The get_list.asp Page
The only remaining part of the task is to create the page get_list.asp, which queries the database to get the matching list of values, and copies these values into the appropriate list box on the main page. The way we do this combines both client-side JavaScript and server-side ASP VBScript into one page.
Probably the simplest and most cross browser compatible way to cache information in a client-side page is through a JavaScript array. We can create this array using server-side ASP code, then read the contents of the array on the client using JavaScript. To see this more clearly, examine the code for the get_list.asp page ?shown and described in the sections below.
Creating a JavaScript Array on the Server
The first part of the page creates a JavaScript SCRIPT section, and within it a function named copyOptions. The first line of this function declares a new array named arrOptions:
<%@LANGUAGE="VBScript"%><HTML><HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!--
function copyOptions() {
var arrOptions = new Array;
...
The Server-Side ASP Code
Next comes a section of ASP code that runs on the server. It uses the parameters sent in the query string when the page is loaded to build up a SQL statement like those we discussed earlier on. Then it creates a connection to the pubs database and executes this SQL statement to populate an ADO recordset on the server (remember that you have to change the connection string to specify your SQL Server name):
...
<%
‘’get the parameters sent in the query string
strFieldName = Request.QueryString("field_name")
strMatchField = Request.QueryString("match_field")
strMatchValue = Request.QueryString("match_value")
‘’create a connection and a recordset
Set oConn = Server.CreateObject("ADODB.Connection")
Set oRs = Server.CreateObject("ADODB.Recordset")

‘’** edit the server name and connection details as required **
oConn.Open "SERVER=yourmachine;DATABASE=pubs;DRIVER={SQL Server};UID=sa;PWD=;"
‘’build up an appropriate SQL statement from the parameter values
strSQL = "SELECT DISTINCT " & strFieldName & " FROM authors"
If Len(strMatchField) Then
   strSQL = strSQL & " WHERE " & strMatchField & "=‘’" & strMatchValue & "‘’"
End If
strSQL = strSQL & " ORDER BY " & strFieldName

intIndex = 1   ‘’to count the number of values found

‘’execute the SQL statement and create the JavaScript code lines
Set oRs = oConn.Execute(strSQL)
...
Now comes the clever bit, where we transfer the data from server to client. All we have to do is dynamically create the JavaScript statements that add the data to the array we declared earlier. This JavaScript code will be executed on the client, and so the array and its values will be available there:

...
Do While Not oRs.EOF
  Response.Write "arrOptions[" & intIndex & "] = ‘’" & oRs.Fields(0) & "‘’;" & vbCrlf
  intIndex = intIndex + 1
  oRs.MoveNext
Loop
Set oRs = Nothing
Set oConn = Nothing
%>
...
The Remaining Client-Side JavaScript Code
The rest of the JavaScript code that runs on the client now has to copy the values from the array into the appropriate list box. You‘’ll see that there are a couple of ASP statements embedded in this code to fill in the other values required - such as the number of items in the array and the name of the list box where they are to be placed:
...
// set number of items in array, plus 1 for empty first item
intCount = <% = intIndex %>;   

// get a reference to the list box
var objForm = parent.frames[‘’main‘’].document.forms[‘’frmMain‘’]
var objList = objForm.elements[‘’sel_<% = strFieldName %>‘’];
// change current selection to first element
objList.selectedIndex = 0;

// change length of options list to new required length
objList.options.length = intCount;
// make the first option item empty so that the onchange
// event will fire for a selection in the list
objList.options[0].text = ‘’‘’;
// loop through the array of values putting them in the list
for (intLoop = 1; intLoop < intCount; intLoop++) {
  objList.options[intLoop].text = arrOptions[intLoop];
  }
}
//-->
</SCRIPT>
...
You can see how this section of code creates the values in the list box by changing the length property of the options array to the appropriate size, and by assigning the values to the text property of each of the SELECT elements‘’ options objects. The text property of an option element is the text that the user sees in the list.

The Client Side Page that is Created
When this page is viewed after loading into the browser, when ASP has worked its magic on it, it will look something like this:

<HTML>
<HEAD>

<SCRIPT LANGUAGE="JavaScript">
<!--
function copyOptions() {
var arrOptions = new Array;
arrOptions[1] = ‘’CA‘’;
arrOptions[2] = ‘’IN‘’;
arrOptions[3] = ‘’KS‘’;
arrOptions[4] = ‘’MD‘’;
arrOptions[5] = ‘’MI‘’;
arrOptions[6] = ‘’NY‘’;
arrOptions[7] = ‘’OR‘’;
arrOptions[8] = ‘’TN‘’;
arrOptions[9] = ‘’UT‘’;
intCount = 10;
var objList = parent.frames[‘’main‘’].document.forms[‘’frmMain‘’]
var objList = objList.elements[‘’sel_state‘’].options;
objList.selectedIndex = 0;
objList.length = intCount;
objList[0].text = ‘’‘’;
for (intLoop = 1; intLoop < intCount; intLoop++)
   objList[intLoop].text = arrOptions[intLoop];
}
//-->
</SCRIPT>

</HEAD>
<BODY ONLOAD="copyOptions()">
</BODY>
</HTML>
Executing the copyOptions Function
Now we can finish off the page with the closing HEAD tag and the BODY section. Because we want the state list box to be populated when the page has loaded, we call the copyOptions function in the onload event of this page:

...
</HEAD>
<BODY ONLOAD="copyOptions()">
</BODY>
</HTML>
This works because when we loaded this page initially, as part of the frameset in default.htm, we specified the field name ‘’state‘’ in the query string for this frame‘’s SRC attribute:

...
<FRAME NAME="getvalues" SRC="get_list.asp?field_name=state" FRAMEBORDER="0">
...
The Final Result
The state list box has the value ‘’ Loading, please wait... ‘’ specified in the HTML code that creates it (in list_authors.htm). However, once the get_list.asp page has executed on the server and loaded on the client, the state list is populated automatically:



After selecting a state, the city list box is populated automatically as the get_list.asp page is reloaded:
We have what we want. Unfortunately, even though we‘’ve chosen the most generic route, things are not quite so simple. For example, if we load the page into Navigator 4.61 the lists are populated okay, but the list boxes fail to resize properly. Instead, you have to force the screen to redraw by resizing the browser window. You may like to experiment with whatever browsers you have to hand to see the effects with these.
A Multiple Frame Solution
So, it looks like the only really compatible solution is to use a separate frame for each list box (or even consider reloading the complete page each time from the server). This would work on non杝cript enabled browsers as well, and solves the problem of the resizing of the list boxes. For the multiple frame solution, all we need is a frameset containing a frame for each list box:
<HTML>
<HEAD>
<TITLE>Selecting an Author</TITLE>
</HEAD>
<FRAMESET ROWS="150,75,*">
   <FRAME NAME="state" SRC="get_state.asp" FRAMEBORDER="0">
   <FRAME NAME="city" SRC="get_city.asp" FRAMEBORDER="0">
   <FRAME NAME="address" SRC="get_address.asp " FRAMEBORDER="0">
</FRAMESET>
</HTML>
The get_state.asp page will always contain a list of all the states; so can be created like this:
...
<SCRIPT LANGUAGE="JavaScript">
<!--
function getCityList(strState) {
   // reload the ‘’city‘’ page with a list of matching cities
   var strPageURL = ‘’get_city.asp?match_value=‘’ + strState
   parent.frames[‘’city‘’].location.href = strPageURL
}

//-->
</SCRIPT>
...
<FORM NAME="frmState">
Select a State:
<SELECT SIZE="1" NAME="sel_state"
   ONCHANGE="getCityList(this.options[this.selectedIndex].text)">
   <OPTION></OPTION>
   <%
      ‘’create a connection and a recordset
      Set oConn = Server.CreateObject("ADODB.Connection")
      Set oRs = Server.CreateObject("ADODB.Recordset")

      ‘’** edit the server name and connection details as required **
      oConn.Open "SERVER=yourserver;DATABASE=pubs;" _
               & "DRIVER={SQL Server};UID=sa;PWD=;"

      ‘’build up an appropriate SQL statement from the parameter values
      strSQL = "SELECT DISTINCT state FROM authors ORDER BY state
      Set oRs = oConn.Execute(strSQL)
      Do While Not oRs.EOF
         Response.Write "<OPTION>" & oRs.Fields("state") & "</OPTION>" & _
            vbCrlf
         oRs.MoveNext
      Loop
      Set oRs = Nothing
      Set oConn = Nothing
   %>
</SELECT>
</FORM>
...
The get_city.asp page can now show just the cities in this state using code very similar to that shown above for the get_state.asp page, but with a different SQL statement:

  ...
   ‘’build up an appropriate SQL statement from the parameter values
   strMatchValue = Request.QueryString("match_value")
   strSQL = "SELECT DISTINCT city FROM authors WHERE state=‘’" & _
      strMatchValue & "‘’ ORDER BY city"
   ...
Moreover, the same technique could be used to populate the ‘’ address ‘’ list box when the user selects an item in the ‘’ city ‘’ list box. Of course, this solution is nowhere near as smooth in operation as the first method we looked at. As they make each selection, the viewer will see the page containing the next list box reloading rather than the values just appearing as they did when we copied them into the existing list box. However, for maximum compatibility, you may choose to go down this route instead.
Conclusion
We have looked at the methods for dynamically populating a dropdown list box as a result of user selections, and chosen the method compatible with the greatest number of browsers. Depending upon the size of the database, however, using one of the cached options described near the top of the article may be a better solution.
Click here to download this article‘’s support material.

原文转自:http://www.ltesting.net