分享
 
 
 

创建服务器端的ASP搜索组件(二)

王朝asp·作者佚名  2006-12-16
窄屏简体版  字體: |||超大  

ShowSearchFrame 方法

ShowSearchFrame是唯一一个声明为Public 的主方法。它不接收自变量,动态生成搜索-输入域、导航条和标题列表。这是通过调用4个支持性Private 方法实现的。

在ShowSearchFrame 方法中要声明多个变量,是为了引用我们的支持性Private 方法时进行传递。在应用它们的Private 方法的上下文中进行解释。

调用的第一个Private 方法是 SearchInputField 函数。这个函数返回一个字符串,在我们这个例子中,字符串由HTML标记和文本填充,以产生一个文本输入区和搜索按钮。

我们将这个HTML代码存储在字符串变量strHTML中:

Public Function ShowSearchFrame() As String

"~~~~~ Local variables

Dim strHTML As String

"===== Search input field

strHTML = SearchInputField

End Function

SearchInputField 函数 SearchInputField 函数不接收自变量。但是它动态地设置一个由页面访问者决定的变量。它还设置源文件名和画面名,与在SearchFrameSet.htm 文件中使用的FRAME 标记名相匹配,这是与决定我们站点的画面特征的SearchFrameSet.htm 相同的文件。

首先看看将要返回的HTML代码:

< FORM NAME="SearchForm" METHOD="GET" ACTION="SearchPage.asp" TARGET="SearchFrame" >

< INPUT TYPE="TEXT" NAME="Src" MAXLENGTH="50" SIZE=15 VALUE="" >

< INPUT TYPE=SUBMIT VALUE="Search" >

< /FORM >

表单的NAME标记设置为 SearchForm。ACTION标记设置为SearchPage.asp, 这是mstrSearchFrameURL变量的默认值。

任何从这个表单的输入域中输入的文本都将传送到源文件(SearchPage.asp )。我们的情况是,这个源文件自引用完全相同的asp 文件,其中容纳着包含SearchInputField 方法的组件。实质上,这个表单调用了它自己,这是设置默认的结构。

在浏览器中,这个HTML代码生成下面的文本输入控件:

现在当访问者在输入域中键入文本并且点击Search 按钮时,文本就会被附在SearchPage.asp URL结尾处。这是因为FORM标记内的METHOD被设置为GET,而不是POST。

POST当然是这两种方法中较好的一个,因为它在HTTP 头文件中隐藏了输入的文本并且允许更长的值。但是我们的例子中,是一个短的文本值,? T 也能允许通过将一个查询字符串附在任何URL的结尾来调用方法。它还有一个好处就是允许浏览器缓存查询结果,因为在进行GET 时,缓存在完整的URL上工作。这样就可以快速访问每个搜索页面,并且在后来离线浏览。

当访问者输入"component" 作为他们的文本输入时,我们的表单发送下面的URL和查询字符串:

SearchPage.asp?Src=component

你还可以从任何站点将这一声明作为一个连接包含在一个HREF标记内--SearchPage.asp 文件不需FORM标记就能工作。

以下是完整的SearchInputField 函数,它生成以上的HTML 代码和浏览器输入控制:

Private Function SearchInputField() As String

Dim strHTML As String

"~~~~ Search input form start

strHTML = strHTML & "< FORM NAME=""SearchForm"" METHOD=""GET"" ACTION=""" _

& mstrSearchFrameURL & """ TARGET=""" & mstrSearchFrameName & """ >"

"~~~~ Search input field

strHTML = strHTML & "< INPUT TYPE=""TEXT"" NAME=""Src"" MAXLENGTH=""50""" _

& "SIZE=15 VALUE=""" & mobjRequest.QueryString("Src") & """ >"

"~~~~ Search input button

strHTML = strHTML & "< INPUT TYPE=SUBMIT VALUE=""Search"" >"

"~~~~ Search input form end

strHTML = strHTML & "< /FORM >"

SearchInputField = strHTML

End Function

请注意我们是如何在HTML代码的连接片段内连接属性程序变量来使用它们的。还要注意HTML标记内要求的单引号(") 是如何被双引号("") 引用的,这样就可以避免VB把它作为一个字符串常量的开头或结尾而产生错误。

还有一个需要注意的是,在INPUT标记内被设置为VALUE的变量。它从查询字符串mobjRequest.QueryString("Src") 中得到它的值,聪明的读者会认出它就是标记本身的名字:

VALUE=""" & mobjRequest.QueryString("Src")

这个自引用查询字符串将在它的文本域内显示发送时在域中键入的任何文本。由于在文本输入域中键入"component" 将把?Src=component附在URL的结尾,INPUT 标记的值将在输入文本框中显示Src的值。

假设在文本输入域内键入的是"component" ,则发送的URL是?/P >

SearchPage.asp?Src=component

而下面的VB代码< INPUT TYPE=""TEXT"" NAME=""Src"" VALUE=""" & _

mobjRequest.QueryString("Src") & """ >

将生成

< INPUT TYPE="TEXT" NAME="Src" VALUE="component" >

而且将显示:

现在用户可以输入一个查询字符串,并将其发送到我们的组件看看查询字符串完成一次搜索。

||||||回到ShowSearchFrame 方法第二部分

回到我们的ShowSearchFrame 方法,它是在SearchInputField 方法中被调用的,我们将返回的HTML代码存储在strHTML变量中。但是在我们将它发送给浏览器之前,必须要确定访问者是否已经输入了一个搜索查询文本让我们在搜索数据库过程中使用。

这是通过校验Src 查询字符串变量是否为空实现的。如果为空,就通知访问者现在他们可以输入查询字符串了。当访问者进入一个搜索站点,连接到一个没有Src 查询字符串的网页时通常就会看到这样的提示。

ShowSearchFrame 调用 SearchInputField 方法并将HTML输入控制代码存储到strHTML 变量后,我们要查看一下这是不是一个新用户或查询请求:

"===== Search input field

strHTML = SearchInputField

If mobjRequest.QueryString("Src") = "" Then

"~~~~~ No query was entered

strHTML = strHTML & "Enter a query"

Else

"[Search code here]

End If

如果没有名为Src的查询字符串,连接来自我们的组件以外,我们可以将一个介绍性的信息附在strHTML 代码上(从这个组件发送一个空查询也会产生同样效果):

strHTML = strHTML & "Enter a query"

现在我们的第一个HTML代码已经完整了,我们将它发送给 IIS在访问者的浏览器上显示:

Else

"[Search code here]

End If

"~~~~~ Send html code to IIS for delivery to visitors browse r

mobjResponse.Write (strHTML )

产生下面的显示:

访问者输入了要组件搜索的文本以后,以上的条件If 语句就会发现VBmobjRequest.QueryString("Src") 变量不为空,分支控制逻辑就会流向选择的Else 部分。然后连接到数据库并在数据库中搜索匹配的Title 和 Text 域。

因为我们要搜索一个Access Memo 型域,或者说是SQL 服务器文本型域,我们不在SQL声明内使用LIKE 语句。相反,我们通过以下的SQL字符串返回一个记录集:

SELECT Title, Text, URL FROM SearchTable

可以用一个帐号群ID、一个典型范围或者在过滤表中有相关内容的任何类别来限制初始查询。

由于SQL声明恢复每个记录,我们就很快地搜索Title和 Text 域寻找与我们的访问者所提交的文本查询字符串相匹配的内容。这个字符串的搜索用VB InStr声明来实现。如果找到了匹配,并且我们在导航分界线的范围之内,就将标题和URL放置在动态字符串数列里。

查看导航分界线限制实质上是从记录的子集中选择一个标题和UR列表L。然后,用户就可以用"next"来访问标题的下一个列表或用"back" 来访问已经看过的列表中的前一个。实际上就是在向浏览器进行显示时,限制从数据库搜索返回的文本数量。

现在我们的数据库中充满了从SQL声明中提取出来的记录(如果你在SQL 声明中使用了WHERE 过滤器的话就可能是一个有限数量的记录)。然后用InStr 声明在每一个返回记录中搜索一个匹配。这就在SQL声明返回的数据库记录中创建了一个虚拟子集。如果这个子集比我们将要显示的大的话,就不将它存储在VB变量中。相反我们选择我们子集的另一个子集在web 页面上显示。我们将数据库域的变量分配限制在最后的子集中,从而节省系统资源并提高运行速度。

为了收集与搜索查询相匹配的web 站点标题和URL,需要创建两个字符串数列。一个保存标题,另一个保存URL。因为我们不知道字符串数列最终将保存多少条目,所以将它们设置为动态数列,每次增加一个新条目时调整它的大小。我们还在不止一个方法中需要这些数列。我们在初始的包装方法ShowSearchFrame 中创建它们,而不是将它们设置为全局变量。然后就将其作为自变量向每个需要的方法传递。我们还需要创建另外两个整形变量,与字符串变量一起传递。

Public Function ShowSearchFrame() As String

"~~~~~ Local variables

Dim strHTML As String

Dim astrTitleArray() As String

Dim astrURLarray() As String

Dim intRecordsDisplayed As Integer

Dim intRecordsMatched As Integer

声明了两个动态字符串变量和两个整形变量之后,就可以将它们传递给第二个方法。GetRecords 函数用数据库中的标题和URL的值来填充字符串数列。用数列中条目的个数设置intRecordsDisplayed 变量。intRecordsMatched 变量中保存与访问者查询字符串相匹配的记录数。我们使mintRecordsSearched 成为一个属性程序,可从ASP主机文件中读取。尽管我们不在这个组件中使用它,用户可能想知道共搜索到多少条记录。

这是ShowSearchFrame 方法中的方法调用。记住,GetRecords函数是有条件地被调用的,当有来自用户的搜索查询,并且在SearchInputField方法之后:

If mobjRequest.QueryString("Src") = "" Then

"~~~~~ No query was entered

strHTML = strHTML & "Enter a query"

Else

"[Search code here]

mintRecordsSearched = GetRecords(astrTitleArray(),astrURLarray(), _

intRecordsDisplayed, intRecordsMatched)

End If

||||||GetRecords 函数

现在我认为对声明和传递方法变量的特殊方法的细节已经介绍得够多了。对于GetRecords方法的解释将主要是此方法的一般功能方面。

如果你使用的是VB5的话,就需要安装Service Pack 3 以获得对ADO 的引用来使这些代码工作。

首先要注意在声明之后,代码有一个错误控制声明。

Private Function GetRecords(astrTitleArray() As String, astrURLarray() As _

String, intRecordsDisplayed As Integer, intRecordsMatched As _

Integer) As Integer

"~~~~~ LOCAL VARIABLES

Dim intCount As Integer

Dim intRecordsSearched As Integer

Dim strHTML As String

Dim strSearchHold As String

Dim strTitleHold As String

Dim strTextHold As String

Dim strURLhold As String

Dim recSearch As New ADODB.Recordset

Dim objCmd As New ADODB.Command

Dim objConn As New ADODB.Connection

Dim strSQL As String

On Error GoTo ErrorCode

如果在使用数据库时发生了错误,控制就在函数结尾处传递一个ErrorCode 标志。

下面的6个声明用Data Source Name(数据源名)打开到数据库的连接、启动一个处理、设置SQL字符串、将SQL 字符串分配给ADO命令对象、告诉命令对象等待一个SQL字符串、设置到命令对象的连接。

在这里我使用的处理是为了示范,而且因为它在转入命令之前用二进制存储代码,这样可以提高数据库处理的速度:

"~~~~~ Open the connection with a data source name

objConn.Open "SearchExampleDSN"

"~~~~~ Begin the transaction (only for speed in this case)

objConn.BeginTrans

"~~~~~ Store the SQL command in a string

strSQL = "SELECT Title, Text, URL FROM SearchTable"

"~~~~~ Set the Command object to the SQL string

objCmd.CommandText = strSQL

"~~~~~ indicate that the command is a SQL string (for speed)

objCmd.CommandType = adCmdText

"~~~~~ Set the Connection object to the Command object

Set objCmd.ActiveConnection = objConn

一旦我们用命令对象得到了所需要的打开记录集的连接,我们就设置:

"~~~~~Open Recordset with the above Command settings

recSearch.Open objCmd

在继续进行搜索之前,需要验证我们确实向搜索返回了一些记录。如果没有返回记录,记录集就既是在开头也是在结尾:

If recSearch.EOF And recSearch.BOF Then

"~~~~No records were returned by the SQL

GetRecords = 0

但是,如果SQL声明返回了一些记录,就需要设置一些变量确保记录集处在开头:

Else

"~~~~Initialize Procedural Variables

intRecordsMatched = 0

intRecordsDisplayed = 0

intRecordsSearched = 0

mintSearchStart = CInt(mobjRequest.QueryString("Start"))

If mintSearchStart = 0 Then mintSearchStart = 1

recSearch.MoveFirst

随着不同的整数计数器的增加,我们在记录集中循环,并将数据库中的标题、文本、URL数据存储在本地字符串变量中:

"~~~~Loop through the recordset

Do While Not recSearch.EOF

"Increment the total number of records to be searched

intRecordsSearched = intRecordsSearched + 1

"~~~~~ Store the database field data in temparary strings

strTitleHold = recSearch.Fields("Title")

strTextHold = recSearch.Fields("Text")

strURLhold = recSearch.Fields("URL")

连接文本和标题字符串后,从头至尾搜索字符串,首先将字符串变成大写字母,然后把我们的查询字符串片段也变成大写字母进行搜索:

"~~~~Concatenate the Title and URL into a String to Search

strSearchHold = strTitleHold & strTextHold

"~~~~~ Determine if the database record meets the visitors query

If InStr(UCase(strSearchHold), _

UCase(mobjRequest.QueryString("Src"))) Then

"~~~~Increment the number of records that match the visitor"s query

intRecordsMatched = intRecordsMatched + 1

如果我们的记录数据包含了查询字符串,就必须要确定它是否在导航列表界限范围内。这是一点技巧,

"Determine if records are within Start/Stop display range

If intRecordsMatched >= mintSearchStart And _

intRecordsDisplayed < mintMaxSearchReturn Then

这个声明使用了mintSearchStart 变量,导航条把它作为一个查询字符串来获取,然后查看一下列表页是否达到了它的最大容量,而这个最大容量是由mintMaxSearchReturn变量决定的。如果通过了测试,就将控制传递给动态数列声明。

每次传递动态数列保存内容之后,调整其大小。

"~~~~Increment number of records to display

intRecordsDisplayed = intRecordsDisplayed + 1

"~~~~Store Title in title array

ReDim Preserve astrTitleArray(intRecordsDisplayed)

astrTitleArray(intRecordsDisplayed) = strTitleHold

"~~~~Store URL in URL array

Redim Preserve astrURLArray(intRecordsDisplayed)

astrURLArray(intRecordsDisplayed) = strURLHold

End If

End If

下面我们移到下一个记录,重新开始:

"~~~~Move to next record

recSear

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有