推薦:小議程序員的信仰老婆經常夸我有想法,得益于老婆大人的鼓勵,我才打算將自己平時所想,所總結的東西寫下來。人是需要不斷總結的,有總結才會有進步。所謂總結,并不一定是多么高深的道理,多么復雜的推論,也并不一定要長篇大論。有時,一句話,或是一個瞬間,會讓你明白很
在寫這篇文章之前我也在Google上找到了很多有關多附件上傳的文章,有用ASP.NET實現的,也有用JSP、PHP等其它技術實現的,但基本前提都是事先通過js腳本來動態創建DOM,然后上傳的時候在服務端做一下處理,有點類似于163的郵件系統。文件上傳需要通過頁面的POST方法進行提交,這個我在一次MOSS開發中iFrame表單提交的古怪問題解決一問中已經闡述過,其中包括了如何使用頁面隱藏的iFrame來提交表單從而避免整個頁面提交到服務器而導致頁面的刷新。多附件上傳的原理與之類似,只不過需要事先通過腳本在頁面上動態創建多個input type='file'的標簽,當然,如果要想功能更加完美,你可能還需要通過腳本動態添加一些按鈕事件以讓用戶可以刪除他所添加的文件。下面是一個應用效果的截圖。

其中紅色方框內的內容是通過腳本在頁面上動態創建的,將用戶在客戶端所選文件的文件名動態添加到一個div里,同時在這個div中放一個隱藏的input type=’file’的標簽,它的value為用戶所選文件的路徑,然后在div中放置一個img,添加onmouseover和onmouseout事件為圖片增加了一些鼠標滑動時的效果,onclick事件用來響應用戶點擊img時刪除對應的文件。看一下代碼中的具體實現。
| 以下為引用的內容: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="MultiAffix.js" type="text/javascript"></script> <script type="text/javascript"> var controlName = 1; // This variable is for the dynamic file controls's name. function addImg(targetElement, savestatsElement, oldimgElement) { var browseimgElement = $get("browseimg"); var arr = browseimgElement.getElementsByTagName('input'); if (arr.length == 0 || arr[0].value.length == 0) { alert('No file inputs.'); return; } var oldbrowser = arr[0]; var filename = getfilename(oldbrowser.value); if (!validateimgtype(oldbrowser.value)) return; if (!validateimgcount(targetElement, 3)) return; var imgtitles = savestatsElement.value + oldimgElement.value; if (validateimgexist(filename, imgtitles)) { alert('You have already added this image!'); return; } if (oldbrowser != undefined) { var newbrowser = oldbrowser.cloneNode(true); newbrowser.value = ''; var newfile = document.createElement('div'); newfile.innerHTML = filename + ' '; // Create a button element for delete the image. var newfileimgbutton = document.createElement('img'); newfileimgbutton.src = 'ShoutOut_Close.gif'; newfileimgbutton.alt = 'Delete'; newfileimgbutton.onclick = function() { this.parentNode.parentNode.removeChild(this.parentNode); savestatsElement.value = updatehiddenimgs(filename, savestatsElement.value); } newfileimgbutton.onmouseover = function() { this.src = 'ShoutOut_Close_rollover.gif'; } newfileimgbutton.onmouseout = function() { this.src = 'ShoutOut_Close.gif'; } browseimgElement.replaceChild(newbrowser, oldbrowser); oldbrowser.name = ++controlName; oldbrowser.style.display = 'none'; newfile.appendChild(oldbrowser); newfile.appendChild(newfileimgbutton); targetElement.appendChild(newfile); $get("chkAgree").checked = false; $get("btAdd").disabled = true; savestatsElement.value += filename + '|'; } } </script> </head> <body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div> <div> Description: <asp:TextBox ID="tbDescription" MaxLength="2000" runat="server" TextMode="MultiLine"></asp:TextBox> </div> <div> Location: <asp:DropDownList ID="ddlLocation" runat="server"> </asp:DropDownList> </div> <div> Display Posted By User: <asp:CheckBox ID="chkPostedByUser" Checked="true" runat="server" /> </div> <div> Notify Shout out User: <asp:CheckBox ID="chkNotifyUser" runat="server" /> </div> <div> Notify Shout out to Email: <asp:TextBox ID="tbShoutoutToEmail" MaxLength="25" runat="server"></asp:TextBox> </div> <div> Images: <div id="saveshoutoutimgs" runat="server"> </div> <input id="btAddImage" type="button" onclick="$get('saveshoutoutaddimgs').style.display='block';this.disabled=true;" value="Click here to Add Image" /> </div> <div id="saveshoutoutdetailshowimg"> <div id="saveshoutoutaddimgs" style="display: none;"> <div> Add Image:</div> <div id="browseimg"> <input type="file" /> </div> <div> Size limit of the images is 100kb. Hieght and Width of the images should not exceed 200px.</div> <div> <input id="chkAgree" type="checkbox" onclick="$get('btAdd').disabled=!this.checked;" />I agree .legal signoff text to be defined. </div> <div> <input id="btAdd" disabled="disabled" type="button" value="Add" runat="server" /> </div> </div> </div> </div> <asp:TextBox ID="tbImgs" runat="server" Text="|" Style="display: none;"></asp:TextBox> <asp:TextBox ID="tbOldImgs" runat="server" Text="|" Style="display: none;"></asp:TextBox> </form> </body> </html> |
| 以下為引用的內容: protected void Page_Load(object sender, EventArgs e) { string script = string.Format("addImg($get('{0}'), $get('{1}'), $get('{2}'));", this.saveshoutoutimgs.ClientID, this.tbImgs.ClientID, this.tbOldImgs.ClientID); this.btAdd.Attributes.Add("onclick", script); } |
代碼建立在Ajax.net基礎之上,環境是Visual Studio 2008 + Windows 2003,測試通過!
簡單做一下說明:
1. <div id="saveshoutoutimg" runat="server"/>用來存放動態添加的文件相關標簽。
2. btAddImage被點擊后自身將被disabled掉,然后顯示saveshoutoutaddimgs整個div。
3. 在saveshoutoutaddimgs中用戶可以完成文件的選取和確認操作,chkAgree用來enable btAdd按鈕。
4. 當用戶點擊btAdd時,觸發onclick事件,該事件在code-behind的Page_Load方法中注冊,因為腳本中涉及到使用服務端控件的ClientID屬性,這樣寫比較方便。
5. 客戶端函數addImg用來完成動態DOM的添加操作,它接收三個參數,第一個參數targetElement表示存放動態DOM的宿主DIV,第二個參數savestatsElement表示用于保存已添加文件信息的隱藏文本框,第三個參數oldimgElement表示用于保存在編輯狀態下用戶上一次上傳的文件信息隱藏文本框。基本思路是復制browseimg下的input type="file"標簽,然后將動態生成的DOM添加到saveshoutoutimgs下,并同時附加了一些事件。
6. tbImgs隱藏文本框用來保存用戶已選文件的信息,以"|文件名1|文件名2|文件名3|..."的格式存放;tbOldImgs隱藏文本框中的值在編輯狀態下才會得到,其中保存了用戶上一次所上傳文件的信息,存儲格式與tbImgs相同。
7. 在編輯狀態下,在服務端向saveshoutoutimgs標簽添加與addImg腳本函數所生成的動態DOM相同的標簽,并同時往tbOldImgs隱藏文本框中寫入文件信息。我在這里寫了一個示例,讀者可以自己完善代碼用以驗證。在顯示文件時我在文件的名稱上添加了一個鏈接,這個鏈接所指向的頁面用于輸出圖片,如通過得到的圖片ID在數據庫中檢索圖片的二進制數據然后Write到頁面上。ImageEntity為自定義Image對象的實體類,用以存儲圖片文件的相關信息。
| 以下為引用的內容: public void SetImages(List<ImageEntity> images) { if (images.Count > 0) { this.tbOldImgs.Text = "|"; foreach (ImageEntity image in images) { HtmlGenericControl imgDiv = new HtmlGenericControl("Div"); HtmlAnchor imgAnchor = new HtmlAnchor(); imgAnchor.HRef = string.Format("Thumbnail.aspx?isthumbnail=false&basecommentid={0}&imagetitle={1}", image.ID.ToString(), image.Title); imgAnchor.Target = "_blank"; imgAnchor.Title = image.Title; imgAnchor.InnerHtml = image.Title + " "; HtmlImage imgButton = new HtmlImage(); imgButton.Src = "ShoutOut_Close.gif"; imgButton.Alt = "Delete"; imgButton.Attributes["onclick"] = string.Format("this.parentNode.parentNode.removeChild(this.parentNode);$get('{0}').value = updatehiddenimgs('{1}',$get('{0}').value);", this.tbOldImgs.ClientID, image.Title); imgButton.Attributes["onmouseover"] = "this.src='ShoutOut_Close_rollover.gif'"; imgButton.Attributes["onmouseout"] = "this.src='ShoutOut_Close.gif'"; imgDiv.Controls.Add(imgAnchor); imgDiv.Controls.Add(imgButton); this.saveshoutoutimgs.Controls.Add(imgDiv); this.tbOldImgs.Text += image.Title + "|"; } } } public class ImageEntity { public ImageEntity() { } public ImageEntity(int id, string title, Byte[] imageBlob, string type) { ID = id; Title = title; ImageBlob = imageBlob; Type = type; } public int ID { get; set; } public string Title { get; set; } public string Type { get; set; } public Byte[] ImageBlob { get; set; } }
主站蜘蛛池模板:
五大连池市|
木兰县|
油尖旺区|
宜丰县|
南靖县|
潍坊市|
盐津县|
云和县|
阿坝|
岑巩县|
涿州市|
南丹县|
嘉黎县|
鹿邑县|
繁昌县|
滨海县|
宜兴市|
宁晋县|
顺昌县|
潮州市|
寻甸|
忻城县|
台中县|
溧水县|
汉川市|
馆陶县|
茌平县|
天柱县|
兰坪|
塘沽区|
凉城县|
溧阳市|
霸州市|
历史|
拉萨市|
涟源市|
中宁县|
乌拉特后旗|
靖远县|
平定县|
金华市|
|