65.9K
CodeProject 正在变化。 阅读更多。
Home

经典 ASP 多文件上传图片库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (12投票s)

2010 年 7 月 13 日

CDDL

14分钟阅读

viewsIcon

110054

downloadIcon

5304

一个基于 SimpleViewer Flash 图片画廊的 VBScript 应用程序,用于管理图片画廊。

*** 注意 ***

此应用程序的一个性能远超此版本的变体可在以下地址找到: /Articles/94893/Add-NET-thumbnailing-to-a-classic-ASP-Multi-upload。它不需要 DLL 注册,因为它使用 ASP.NET 来渲染缩略图。我强烈建议使用该版本的画廊。阅读两篇文章以了解画廊工作方式的所有细节,但请使用 ASP.NET 版本以获得最佳效果。谢谢!-- LB

简介

这是一个基于 ASP 的图片画廊,具有多图上传和自动缩略图功能。画廊使用 SimpleViewer 显示 - 一个基于 Flash 的画廊应用程序。该应用程序利用 ADO/XML 和文本文件管理画廊信息,因此无需数据库配置。

背景

此程序使用了以下开源应用程序

  • SimpleViewer - 一个功能灵活的基于 Flash 的图片画廊。
  • FreeASPUpload - 一个基于 VBScript 的 ASP 类,用于处理文件上传。
  • CXImage Control - 一个 DLL 文件,用于使用 VBScript 等 COM 语言进行图像处理。此 DLL 必须在您的 IIS 服务器上注册。我正在开发一个使用 .NET 进行缩略图处理的版本。请在后续文章中查找。
  • Prototype.js - AJAX 框架。
  • Scriptaculous - 基于 Prototype.js 的特效框架。

Using the Code

要安装代码,请将 gallery.zip 中的 gallery 文件夹拖到您的 IIS 文件夹中。将 images 子文件夹设置为允许写入访问,否则您将收到权限被拒绝的错误。浏览到您的 gallery 文件夹并开始使用该应用程序。

登录名和密码分别是“admin”和“admin”。您可以在 gallery_app.asp 中的 handle_login 函数中更改它们。

登录后,您将看到现有画廊的列表。

关注点

这段代码没有什么特别离奇的地方,但有一些有趣之处

  • 多文件上传 - 允许批量上传最多九个文件
  • ADO/XML - 使用 ADO recordsets 和 XML 将它们作为文件存储,而不是使用数据库。
  • 一个未使用的功能 - 一个基于 VB.NET 的缩略图生成器,如果您进行一些代码重写,可以使用它在 godaddy 等托管网站上工作。
  • 拖放排序 - 代码利用 Scriptaculous 的排序功能来实现图像列表的拖放排列。

多文件上传

通过结合隐藏的 IFrame 和通过 prototype.js 的 AJAX 请求,上传页面 (upload_files.asp) 允许批量上传最多九张图片。每上传一张文件,就会在当前上传旁边显示一个指示器。文件上传完成后,会在表单旁边显示一个缩略图,并且下一个文件将被处理。批量完成后,会出现一个按钮,提示点击上传更多文件。

ADO/XML

每个画廊都使用 ADO/XML recordset 来管理文件列表和排序顺序。利用这项技术,我们可以利用结构化存储,而无需进行数据库设置。使用 gallery_app.asp 中的 newid() 函数为每个图像生成唯一 ID。

一个未使用的功能

有一个文件 thumbnail.aspx 和一个对应的 thumbnail.aspx.vb 后台代码页,可用于生成缩略图。使用此页面的优点是它取消了 CXImage DLL,这对于不允许注册控件的托管环境很有益。缺点是您需要进行一些代码重写才能利用基于 .NET 的缩略图生成器。我希望在未来的文章中解决此更改。

拖放排序

“排列”链接会转到一个页面,您可以在其中拖放画廊图像以重新排列它们在画廊视图中的位置。此功能利用 Scriptaculous 的“sortables”来完成任务。

代码解释

此应用程序的大部分代码可以在 gallery_app.asp 中找到。每个页面都是一个存根,包含 HTML 内容,并调用 gallery_app.asp 中的函数。几个页面还利用 AJAX 调用“功能页面”在后台执行操作,并提供更具吸引力的用户体验。让我们逐一浏览每个页面,我将解释功能,然后深入了解代码工作原理以及 AJAX 调用发生的位置。我还会解释调用了哪些页面。首先,一些背景信息。

库和命名约定

我使用 prototype.js 作为我的 AJAX 框架,使用 scriptaculous.js 进行特效处理。我使用“代码后台”约定来分隔 JavaScript 代码和 HTML。您会发现一个给定页面的 JavaScript 代码命名为“pagename.js”。例如,如果页面名为 upload_files.asp,您会找到其 JavaScript 库名为 upload_files.js

服务器端代码的主要代码库是 gallery_app.asp

AJAX 调用约定

您会看到在我使用 AJAX 调用时,页面上出现了相同的基本结构。使用 Prototype 的 Ajax.Request 方法,该方法的通用模板如下所示:

new Ajax.Request('action_page.asp?gallery_id=' + id, {
    method: 'post', // use post method
    postBody: $('form_name').serialize(),
    onSuccess: function(transport){
        // every action page returns HTML that is inserted
        // directly into the results container. 
        $('results_container').innerHTML=transport.responseText;
    }, // end on success
    onFailure: function(transport) {
        // Append an appropriate error message to the results container
        var err = "<br/>Error creating gallery"+transport.responseText;
        $('results_container').innerHTML=$('results_container').innerHTML + err;
    } // end on fail
}); // end ajax request

'action_page.asp' 是执行指定操作的页面的名称。在大多数情况下,操作表单会重新渲染被操作的页面部分以反映结果。form_name 是包含要发布到 action_page.asp 的数据的表单的 ID;'results_container' 是用于显示请求结果的 div 标签的 ID;在大多数情况下,这是包含调用表单的容器。成功调用后,此容器的内容将被 AJAX 响应中返回的渲染内容替换。

这里是一个用于切换画廊显示/隐藏的切换画廊函数示例

function toggleGallery(id) { // all ajax calls pass the gallery id in the querystring
    new Ajax.Request('toggle_gallery.asp?gallery_id=' + id, {
        method: 'post', // all actions use the post method
        onSuccess: function(transport){ // action pages return content ready for use
            $("gallery_list").innerHTML=transport.responseText;
        }, // end on success
        onFailure: function(transport) {
            $("gallery_list").innerHTML=$("gallery_list").innerHTML + 
                    "<br/>Error creating gallery"+transport.responseText;
        } // end on fail
    }); // ajax request
    
}

在上面的示例中,我只是传递了画廊 ID;一些调用还包括来自表单的数据。如果我从表单发布数据,您还会在方法 'post' 下看到以下代码行。

postBody: $('form_name').serialize(),

其中 'form_name' 是要发布到该页面的 HTML 表单的 ID。

好的,现在让我们来看看内容页面。

gallery.asp

这是画廊的主显示页面。它调用 Flash 文件 "SimpleViewer.swf"。它还将画廊 ID 传递给页面 gallery.xml.asp,该页面会组装一个 XML 文档,SimpleViewer 使用该文档来构建图像列表。顶部会看到画廊标题菜单和一个管理链接。点击管理链接会带您到画廊列表页面。

gallery_list.asp

此页面显示现有画廊列表;您可以在此处:切换画廊的显示/隐藏状态、创建新画廊、访问信息、上传、图像(标题)以及通过 gallery.asp 查看画廊。

“创建新画廊”会向操作页面 create_gallery.asp 发出 AJAX 调用,该页面执行四项操作:通过递增 images/id.txt 中的画廊 ID 计数器获取新 ID [id]、创建一个新的画廊信息文件 [id].txt、创建一个用于保存图像列表和排序顺序的新画廊表 [id].xml,以及最后创建一个画廊图像和缩略图文件夹 [id][id]/thumb[id] 将被替换为新 ID。有关更多详细信息,请参见 gallery_app.asp 中的“CreateGallery”函数。

最右侧列中的“隐藏/显示”按钮会向 toggle_gallery.asp 发出 AJAX 调用,该页面将画廊 ID 添加/删除到 images/config.txt 中的“隐藏”列表中。画廊 ID 将通过查询字符串传递。

在“工具”列中,您会找到四个链接。信息允许您编辑/更新画廊标题。上传允许您将新图像上传到画廊。图像允许您管理图像(添加/删除)以及编辑标题。最后,查看允许您在 SimpleViewer 中查看您的更改。

edit_gallery.asp

编辑画廊信息允许您更改画廊标题和描述。描述目前没有在任何地方使用。这是一个非常简单的表单。当您单击“保存”时,会向操作页面 save_gallery.asp 发出 AJAX 调用,该页面会调用 gallery_app.asp 中的 SaveGallery() 函数。此页面上的信息将保存到文本文件“images/gallery_id.txt”中,其中 gallery_id 是通过查询字符串传递的 ID 号(参数:gallery_id)。当您从 gallery_list.asp 页面单击“信息”链接时,ID 会自动传递。

upload_files.asp

这就是整个项目开始的地方。我想找到一种使用 ASP 上传多个文件的方法,同时提供一些关于上传过程的反馈。理想情况下,这将以每个文件的进度条形式出现;然而,我找不到一种方法可以做到这一点。所以我做了次优的选择:添加一个指示器图像(如果你喜欢,可以是一个旋转器)来指示当前上传。

要上传文件,请单击“浏览...”按钮,然后从您的硬盘驱动器中找到所需的图像(取决于您的浏览器,按钮可能显示为“选择...”)。一次最多可以上传九张图片。选择完所有要上传的图片后,单击“开始上传图片”按钮。

上传进度

每上传一张文件,旋转器就会指示当前上传(请参见第三张图片)。上传完成后,将在浏览(或选择)按钮旁边放置一个缩略图,并在“最后完成上传”标题下放置一个较大的缩略图以及图像大小。这个过程会为每个图像持续进行,直到列表完成。

上传完成

当所有图像都上传完成后,会出现一个按钮,提示您如果愿意,可以上传更多图像。这个过程可以根据需要重复多次。

那么,当单击“开始上传图片”按钮时会发生什么?会调用 JavaScript 函数“uploadClick();”(位于 upload_files.js)。此函数会遍历每个表单,将其设置为禁用状态,并将缩略图设置为空。禁用表单可防止用户在上传过程中与表单进行交互。

var upload_counter = 0
// Handle Upload chain
function uploadClick() {
  $("startupload").fade();
  upload_counter = 1;
  for (x=1;x<10;x++) {
    $("uploaded_image0"+x).src="blank.gif"; // Blank thumbnail image
    $("file_upload_form0" + x).disable();   // Disable form.
  } 
  handleForm();
}

这是因为每张图像都存储在自己的 HTML 表单中。每个表单包含一个文件上传输入框、一个缩略图占位符和一个进度指示器(旋转器)占位符。每个表单及其所有元素都带有 00、01、02 等后缀命名,以便使用迭代器轻松访问它们。另外,请注意表单的“target”属性设置为 'upload_target';稍后将详细介绍。最后,请注意“action”属性是 upload.asp;这是处理上传的操作页面。

<form id='file_upload_form02' target='upload_target' method='post' 
            enctype='multipart/form-data' action='upload.asp?gallery_id=1'>
Image: 
   <input name='file' id='file02' size='40' type='file' />
   <img id='uploaded_image02' width='24' height='24' src='blank.gif'/>
   <img src='indicator.gif' id='upload_indicator02' style='display: none;' />
<br />
</form>

uploadClick 的末尾,会调用 handleForm() 函数(也位于 upload_files.js)。Handleform 会为文件递增计数器,打开相应的指示器,并通过启用、提交然后再次禁用表单来提交表单。

// handles a form update, only populated forms are submitted
function handleForm() {

  while ( ($("file0" + upload_counter )!=null) 
   && ($("file0" + upload_counter ).value != "" ) 
   && (upload_counter<10) ) 

      upload_counter++; // Increment the counter
 
      if ( upload_counter<=9 ) {
          $("upload_indicator0" + upload_counter).appear(); // Turn on the indicator
          $("file_upload_form0" + upload_counter).enable(); // enable the form
          $("file_upload_form0" + upload_counter).submit(); // Submit the form
          $("file_upload_form0" + upload_counter).disable(); // disable the form
      } else {
          batchComplete(); // if all files are processed call batch complete
  }

}

每个表单都提交到一个隐藏的 IFrame(同一个 IFrame),该 IFrame 位于表单列表下方。此 IFrame 用作上传表单的目标。这是 IFrame 的源代码:

<iframe 
   id='upload_target' 
   name='upload_target' 
   src='about:blank' 
   style='width:0;height:0;border:0px solid #fff;' >
</iframe>

由于每个表单的目标都设置为 'upload_target',并且我们的 IFrame 被命名为 'upload_target',因此提交请求被发送到 IFrame 而不是整个页面。这允许每个文件依次上传,而不会干扰主 HTML 页面 (upload_files.asp)。IFrame 还充当文件完成后返回的机制。

当所有文件上传完成后,会调用 batchComplete,该函数会简单地打开按钮,提示执行另一个批处理。

upload.asp

在继续介绍内容页面之前,我认为有必要详细介绍上传操作页面。我不会详细介绍所有操作页面,因为用一两句话就能描述清楚它们的功能。Upload.asp 是一个不同的类,所以我在这里单独介绍它。

Upload.asp 是一个操作页面,它集成了 FreeASPUpload 来实现文件上传。有趣的是,它是免费且开源的,因此您可以随意调整和修改其行为。它也是免费的,因此您可以无需注册 DLL 即可使用它。此页面使用另一个开源项目 (CXImageControl) 来生成缩略图;不幸的是,此控件需要服务器端注册。您可以轻松地将缩略图函数改编为与服务器上提供的任何图像控件一起使用。我还在撰写一篇后续文章(前提是本文能引起足够的兴趣),该文章将使用单个 .NET 页面来处理缩略图,从而使此画廊“无组件”且易于在不支持“DLL 注册友好”的主机服务上运行。

以下是 uploads.asp 的工作原理概述(下面项目符号中的 [gallery_id] 是实际的画廊 ID 在查询字符串中传递的占位符)。

  • 创建并调用 FreeASPUploads 来加载图像文件。
  • 调用 FreeASPUploads 对象将文件保存到 images/[gallery_id]/
  • 创建时间戳前缀(四位数字年份 + '.' + 一年中的第几天 + '.' + 时间)。
  • 使用时间戳重命名每个文件以防止命名冲突。
  • 生成以下格式的缩略图:32x32、64x64、96x96、120x120、240x240、480x480、640x640、800x800 和 960x960。缩略图放置在 images/[gallery_id]/thumb/ 中,并命名为 filename.WxH.jpg
  • 文件通过将其添加到 images/[gallery_id].xml 文件中进行注册;这是使用 ADO 完成的。我稍后会解释。

ProcessUpload 函数是 FreeASPUpload 包中的 upload_test.asp 文件中包含的 ProcessUpload 函数的修改版本。代码片段相当长,所以我不在此包含。我将介绍我更改的部分,并深入介绍 ProcessUpload 调用的函数。

日期戳

日期戳用于为每个文件提供唯一的名称,以避免文件名冲突。

sStamp = year(now()) & "." & datepart( "y", now() ) & "." & CLng( Timer ) & "."

上传的文件最初具有与您硬盘驱动器上的相同名称,因此我们需要使用 Scripting.FilesystemObjectMoveFile 方法来重命名它。这在下面的代码中显示为“fso.”。这段代码可以在 upload.asp 的第 63 行开始找到。

strFile = Upload.UploadedFiles(fileKey).FileName ' The file as it is named on your hdd
sOldFile = uploadsDirVar & "\" & strFile ' the path to where the file was uploaded
strFile = sStamp & strFile  ' now set the file to the new time stamp prefixed name
strFileName = uploadsDirVar & "\" & strFile ' create a path to the new file
call fso.MoveFile( sOldFile, strFileName ) ' Call fso to move the file

文件重命名后,它将使用以下代码行(upload.asp 的第 74 行)在画廊中注册:

AddGalleryImage( strFile )

AddGalleryImage 通过调用 OpenTable(filepath, rs) 加载当前画廊文件(images/gallery_id.xml),将文件完整路径和一个 recordset 对象作为参数,将新文件追加到 recordset,然后使用调用 SaveTable(filepath, rs) 将 recordset 保存为 XML,该函数将更新后的数据写回 XML 文件。以下是三个函数以及一个创建新的空画廊表的函数;这些函数在 gallery_app.asp 中找到:

''**********************************************************************
'' Function: AddGalleryImage
'' Version: 1  
'' Date: 2009/07/11
'' Author: Larry Boeldt
'' Description: Adds a new image to the current gallery. 
''**********************************************************************
function AddGalleryImage(sFileName)
    dim path
    dim rs
    dim lOrder
    path = server.mappath(".") & "\images\" & lGalleryID & ".xml"
    
    OpenTable path, rs
    
    rs.addnew
    rs("id")=newid()
    rs("dateadded")=now()
    rs("filename")=sFileName
    rs("order")= year(now)*10000+month(now)*100+day(now)
    rs.update
    SaveTable path, rs
end function

''**********************************************************************
'' Function: SaveTable
'' Version: 1  
'' Date: 2009/07/11
'' Author: Larry Boeldt
'' Description:
''**********************************************************************
function SaveTable(FullPath, rs)
    DeleteFileIfExists FullPath
    
    if not rs.bof then
        rs.movefirst
    end if
    
    rs.Save FullPath, 1 '' adPersistXML = 1
end function

''**********************************************************************
'' Function: OpenTable
'' Version: 1  
'' Date: 2009/07/11
'' Author: Larry Boeldt
'' Description: Open an ADO XML table
''**********************************************************************
function OpenTable(FullPath, rs)
    set rs=CreateObject("ADODB.Recordset")
    rs.Open FullPath, "Provider=MSPersist", , , &H0200 ''adCmdTableDirect 
end function

''**********************************************************************
'' Function: GalleryTable
'' Version: 1
'' Date: 2010-07-09
'' Author: Larry Boeldt
'' Description:
'' Create the gallery xml table file to contain a list of files
''**********************************************************************
function CreateGalleryTable(FullPath)
    dim rs
    set rs = CreateObject("ADODB.Recordset")
    rs.CursorLocation  =  3 '' adUseClient
    
    rs.Fields.Append "ID", 200, 40  '' adVarChar = 200
    rs.Fields.Append "FileName", 200, 240
    rs.Fields.Append "Caption", 200, 4096 
    rs.Fields.Append "DateAdded", 7 '' adDate = 7
    rs.Fields.Append "Size", 3 '' adInteger = 3
    rs.Fields.Append "Order", 3 ''
    rs.Open 
    SaveTable FullPath, rs
        
    set rs = nothing
end function

最后,一系列调用 Thumbnail 函数来生成每个缩略图图像。Thumbnail 接受以下参数:FilenameWidthHeightKeepAspectRatioJpegCompressionRatio。如果 KeepAspectRatio 为 0,图像将被拉伸或缩小以适应确切的尺寸;如果为 1,图像将按比例缩放到适合传递的宽度尺寸。

Call ThumbNail(strFileName, 32, 32,1,80)

这是完整的 ThumbNail 函数。您会看到我在哪里使用了 CXImageControl 来打开原始文件,调整大小,并将其保存到 thumb 文件夹。

function ThumbNail(strFileName,lWidth,lHeight,lKeepRatio,lCompression)
    '    response.Write "Call to Thumbnail"
    dim fso: set fso = createobject("scripting.filesystemobject")
    dim lH: lH=lHeight
    dim lW: lW=lWidth
    dim lRatio: lRatio = lKeepRatio
    dim strSitePath
    ''response.write strFileName
    strSitePath = fso.GetFile(strFileName).ParentFolder
    dim strHTML
    dim strSRC 
    dim strOnC ' OnClick
    dim strImgPath
    dim strThumbPath
    dim strURL
    dim bExists
    dim strThumbName
 
    strImgPath = strFileName
    rem convert to cx image
    dim pWidth
    dim pHeight
    dim FileName
    dim sRoot
    dim sFile
    dim bStretch
    dim widthTh
    dim heightTh
    dim widthOrig 
    dim heightOrig 
    dim objCxImage
    dim Quality
    dim strResult
    rem use cximage
    bStretch = (lKeepRatio = 0)
    Quality = lCompression
    sRoot = strSitePath 
    sFile = fso.getFile( strFileName ).name
    FileName = strFileName
    pWidth = lW
    pHeight = lH
    ThumbName = uploadsDirVar & "thumb\" & sFile & "." & _
                pWidth & "x" & pHeight & ".jpg"
    ' Create COM CxImage wrapper object
    Set objCxImage = CreateObject("CxImageATL.CxImage")
    Call objCxImage.Load(FileName,GetFileType(FileName))
    Call objCxImage.IncreaseBpp(24)
    ' determine thumbnail size and resample original image data
    If bStretch Then ' stretch to fit 
        widthTh = Width
        heightTh = Height
    Else ' retain aspect ratio
        widthOrig = CDbl(objCxImage.GetWidth())
        heightOrig = CDbl(objCxImage.GetHeight())
        fx = widthOrig/pWidth
        fy = heightOrig/pHeight 'subsample factors
        ' must fit in thumbnail size
        If fx>fy Then f=fx Else f=fy  ' Max(fx,fy)
        If f<1 Then f=1
        widthTh = Int(widthOrig/f)
        heightTh = Int(heightOrig/f)
    End If
    objCxImage.SetJpegQuality( Quality )
    Call objCxImage.Resample(widthTh,heightTh,2)
    call objCxImage.Save(thumbname,GetFileType("jpg"))   
    Call objCxImage.Destroy()  
    set objCxImage = nothing
    rem end convert to cx image
    Thumbnail = ThumbName
  
end function 

好的,既然我们了解了 upload.asp 的工作原理,让我们快速回顾一下其余页面。

captions.asp

Captions.asp 是您管理图像标题(随图像出现的文本)和从画廊中删除图像的地方;无论何时看到“images”链接,都可以访问此页面。每个标题框的 onChange 事件会触发 captions.js 中的 saveCaptions 函数。此函数调用操作页面 savecaption.asp,该页面获取提交的数据并将其保存到 images/[gallery_id]/[imagename].txt

function saveCaption( obj ) {
    var data = obj.innerText
    var tag = obj.id
    
    var file = $("file." + tag).value // get the value of the caption textarea
    
    if (data =="") data = " "; // ensures we don't have a zero length file error
    
    // we make a call to savecaption.asp (always passing the gallery_id in QS    
    $("indicator."+tag).show();
    new Ajax.Request( "savecaption.asp?gallery_id=" + gallery_id + "&file=" + file, {
        method: 'post',
        postBody: data,
        onSuccess: function(transport) {
            $("indicator."+tag).fade();
        }
    });
}

触发此调用的 textarea 代码如下所示:

<textarea 
    onchange='saveCaption(this);' 
    style='margin: 6px;' rows=4 cols=40 
    name='caption' 
    id='IMG_3258.JPG'></textarea>

请注意,onChange 事件设置为 'saveCaption(this)',因此您只需更改标题即可自动保存。无需单击提交。

单击“删除”按钮时,会调用 removeImage 函数,该函数通过调用操作页面 removeimage.asp 来删除图像。它的工作方式类似于调用 saveCaption,但在 onSuccess 时会淡出表单。我将让您在网站上自行研究该函数。

sort.asp

Sort.asp 是在任何看到“arrange”链接的地方访问的。它会以网格形式显示文件列表,这些文件将按此顺序在 SimpleViewer Flash 中显示。您只需将图像拖放到所需位置,即可保持其顺序。排序列表由 gallery_app.asp 中的 ShowSortList 函数生成。

''**********************************************************************
'' Function: ShowSortList
'' Version: 1  
'' Date: 2009/07/11
'' Author: Larry Boeldt
'' Description: Shows the sorting list form.
''**********************************************************************
function ShowSortList
    dim fso
    dim spath
    dim fil
    dim sExt
    dim sFile
    dim rs
    
    set fso = createobject("scripting.filesystemobject")
    sPath = server.mappath(".") & "\images\" & lGalleryID & "\"
    sFile = server.mappath(".") & "\images\" & lGalleryID & ".xml"
    
    OpenTable sFile, rs
    
    rs.sort = "order asc" ' sort the recordset in the desired sort order
    
    do until rs.eof
        response.write "<li id='item_" & rs(0).value & "'>"
        response.write "<img src='images/" & lGalleryID & "/thumb/" & _
                       rs(1).value & ".96x96.jpg'/>  " 
        'response.write rs(0).value  
        response.write "</li>"
        rs.movenext
    loop
end function

sort.asp 的底部附近,您会看到以下 JavaScript,它创建了可排序页面并将目标设置为 sort.events.asp 操作页面。

<script language="javascript">
Sortable.create("sort_list",
{
    onUpdate: function()
    {
        new Ajax.Request("sort.events.asp?gallery_id=<%=lGalleryID%>",
        {
            method: "post",
            parameters: { data: Sortable.serialize("sort_list") }
        }
        );
    }
}
);
</script>

sort.events.asp 将新顺序的图像列表作为数据接收。它按顺序读取排序项列表,并将其“order”值设置为其新的序数值。这使用了 OpenTableSaveTable 方法。请参见下面的代码,了解我是如何进行排序的。

handle_sort_list
function handle_sort_list
    ' response.write request.form & request.querystring
    ' data=list_to_sort[]=&list_to_sort[]=&list_to_sort[]=&list_to_sort[]=<? row.id; ?>
    dim sData
    dim aryData
    dim sSQL
    dim iX
    dim list
    dim sPath
    dim sFile
    dim rs
    dim str

    ' lGalleryID is a global variable set using request.querystring("gallery_id").
    sPath = server.mappath(".") & "\images\" & lGalleryID & "\"
    sFile = server.mappath(".") & "\images\" & lGalleryID & ".xml"
    sData = URLDecode( request.form("data") )
    if instr( sData, "&" ) = 0 then exit function
    
    sData = replace( sData, "sort_list[]=", "", 1, -1, 1 )
    aryData = split( sData, "&" )
    
    str = str & "GalleryID: " & lGalleryID & vbcrlf 
    str = str & vbcrlf & vbcrlf
    str = str & sData & vbcrlf & vbcrlf 
    set list = createobject("scripting.dictionary")
    
    str = str & "upper bound: " & ubound( aryData ) & vbcrlf & vbcrlf
    ' Read each file in order into a dictionary object 
    ' where filename is key and order is value
    for iX = 0 to ubound( aryData ) 
        list.add aryData( iX ), iX
        str = str & aryData( iX ) & vbtab & ix & vbcrlf
    next
    str = str & vbcrlf & vbcrlf
    ' Now open the gallery ado recordset
    OpenTable sFile, rs
    ' iterate the file list
    do until rs.eof
        str = str & rs("id") & vbtab & list( rs("id").value ) & vbcrlf
        ' set the order of the file by getting the value from the dictionary object


        rs("order")=list( rs("id").value )
        rs.update ' save changes
        rs.movenext
    loop
    str = str & vbcrlf 
    SaveTable sFile, rs ' Call Save Table to update the gallery list
    
end function

我相信这涵盖了应用程序的主要功能。如果您有任何问题,请告诉我。感谢您的阅读,并享受对图片画廊的修补!

更新:我在这里发布了本文的第二部分:为 Classic ASP 多图上传图片画廊添加 .NET 缩略图处理

© . All rights reserved.