1. 程式人生 > >bootstrap File Input 多檔案上傳外掛使用記錄(二)刪除原檔案

bootstrap File Input 多檔案上傳外掛使用記錄(二)刪除原檔案

在上一篇文章中,主要介紹了file input外掛的初始化和多檔案同步上傳到伺服器的相關配置等。這篇主要介紹file input外掛的編輯等。

使用場景:

在後臺管理框架中,一條資料中包含不固定的多張圖片屬性,然後需要同其他資料一起做增刪改查。多檔案同時新增上一篇已經做過了,需要的請點選開啟連結,但是編輯的時候,就需要吧原來上傳的圖片展示出來,然後可以進行刪除和重新上傳,,這就是我現在要做的功能。


直接上程式碼吧。。

1.HTML

    <form>
         .......//其他資料
         <div class="form-group" style="width:99%">
             <input id="update_bachPic" name="commoPicArr" type="file" multiple >
         </div>
    </form>

2.JS程式碼 當點選資料的編輯按鈕,則通過後臺返回的資料初始化編輯頁面,並初始化檔案上傳外掛。

$("#update_bachPic").fileinput({
		language: 'zh',                                        //語言
		uploadUrl:'<%=basePath%>/commodity/addCommodityPic',   //上傳地址
		showPreview: true,				//展前預覽
		showUpload: false,				//顯示上傳按鈕
		showCaption: false,				//顯示文字表述
		uploadAsync:false,                             //false 同步上傳,後臺用陣列接收,true 非同步上傳,每次上傳一個file,會呼叫多次介面
		removeFromPreviewOnError:true, //當選擇的檔案不符合規則時,例如不是指定字尾檔案、大小超出配置等,選擇的檔案不會出現在預覽框中,只會顯示錯誤資訊
		maxFileCount: 5,
		maxFileSize: 1024*10,			//單位為kb,如果為0表示不限制檔案大小
		allowedFileExtensions: ["jpg", "jpeg", "gif", "png","bmp"],
								
		previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
		overwriteInitial: false,
		initialPreviewAsData: true,
		initialPreview: [        //這裡配置需要初始展示的圖片連線陣列,字串型別的,通常是通過後臺獲取後然後組裝成陣列直接賦給initialPreview就行了
                        "http://......img",
                        "http://......img",
                        ],
        initialPreviewConfig: [ //配置預覽中的一些引數 
                                {caption: "transport-1.jpg", size: 329892, width: "120px", url: "deletePic", key: 1},
                                {caption: "transport-2.jpg", size: 872378, width: "120px", url: "deletePic", key: 2}
                              ]
        }).on('filepredelete', function(event, key, jqXHR, data) {
                    console.log('Key = ' + key);
                    console.log(jqXHR);
                    console.log(data); 
        });
注意:
配置initialPreview:[ ] 配置的是陣列,也就是需要初始展示圖片的地址陣列,字串型別,當然通常是通過ajax從後臺獲取到連結後再組裝成陣列直接賦給他就行了。
配置initialPreviewConfig:[ ]也是一個數組,他主要是配置預覽圖片的相關顯示引數,名字啊、大小啊。但是最重要的配置是url,他是你在點選圖中的刪除按鈕後,會呼叫的地址,然後通過ajax去後臺刪除原圖片。配置key,表示刪除的時候向後臺傳遞的引數,看圖:

       很神奇,你會發現,在url中我只配置了deletePic,但是通過除錯發現,刪除請求的url竟然自動拼接了前面的一段url,我猜測可能是從上面的配置updateUrl而來,或者是從請求頭中的Referer而來。

        配置的key是請求傳遞的引數,實測發現名字key不能改成自己的其他名字,而且傳遞的值不能是物件,這就有個問題了,萬一我想傳多個值怎麼辦?那就自己動手豐衣足食,改造原始碼吧。。

 3.更改fileinput.js原始碼

  需求一:將key傳遞的引數改為: key: "{'id':'1','name':'name1'}"
  注意:既然直接傳遞物件不行,那就傳遞json字串吧,然後在原始碼中轉換成json不就行了?


       更改原始碼中2379行左右,當點選刪除按鈕時,會呼叫settings,裡面就是已經配置好的引數,我們獲取key值,然後將單引號替換成雙引號,然後轉換為json物件,替換data引數。

       這裡為什麼要替換單引號為雙引號,為什麼不直接在key配置的時候就寫雙引號呢?別問,我試了,不行,轉換會出錯,要不就是傳遞不過來,不然我也不會使用這個多此一舉的辦法啊。。。你直接傳遞json字串到後臺,用後臺程式碼解析為json也可以。。然後我們的除錯請求發現傳遞的值就變成我們想要的了。。


       好,傳值的問題解決了。就可以點選按鈕的時候去後臺刪除此圖片了,並傳遞我們其他的引數。新選擇的圖片並不會呼叫後臺方法,會直接刪除的。

  需求二:當用戶點選刪除按鈕的時候,提示他這是原圖片,並問他是否確認刪除,確認後才去後臺呼叫刪除,取消則不刪除。這是為了避免使用者點錯,而導致刪除了原圖片,那麼久需要在後臺呼叫ajax之前執行一段我們的提示程式碼。

 解決:檢視API,發現了這麼幾個事件可以呼叫。
    $('#input-id').on('filepreremove', function(event, id, index) {       //只是你刪除重新選擇的圖片才會觸發,而刪除原圖片不會觸發。
       console.log('id = ' + id + ', index = ' + index);
    });


   $('#input-id').on('filepredelete', function(event, key, jqXHR, data) {  //就是在刪除原圖片之前觸發,而新選擇的圖片不會觸發。能滿足我們的要求。
      console.log('Key = ' + key);
   });

  解決一:

 採用filepredelete時間監聽,在刪除之前詢問使用者是否確定,並在確定後執行後面的。如果採用一般bootstrap的詢問框,都是採用回撥的方式監聽使用者操作的,還沒等回撥結束,後面的程式碼就已經開始呼叫ajax執行刪除了。所以需要一個js執行緒的暫停機制,類似於alert,當用戶操作後再往下執行,原始的js confirm()方法可以實現詢問,然後點選確定則繼續執行,所以程式碼改為:

$("#update_bachPic").fileinput({
        language: 'zh',
        uploadUrl:'<%=basePath%>/commodity/addCommodityPic',
        showPreview: true,				//展前預覽
        showUpload: false,				//顯示上傳按鈕
        showCaption: false,				//顯示文字表述
        uploadAsync:false,
        removeFromPreviewOnError:true,
        maxFileCount: 5,
        maxFileSize: 1024*10,			//單位為kb,如果為0表示不限制檔案大小
        allowedFileExtensions: ["jpg", "jpeg", "gif", "png","bmp"],
        previewFileIcon: "<i class='glyphicon glyphicon-king'></i>",
        overwriteInitial: false,
        initialPreviewAsData: true,
        initialPreview: urlArr,
        initialPreviewConfig: [
                            {caption: "transport-1.jpg", size: 329892, width: "120px", url: "deletePic", key: "{'id':'1','name':'name1'}"},
                            {caption: "transport-2.jpg", size: 872378, width: "120px", url: "deletePic", key: "{'id':'1','name':'name1'}"},
                            ]
        }).on('filepredelete', function(event, key, jqXHR, data) {
                if(!confirm("確定刪除原檔案?刪除後不可恢復")){
                    return false;
                }
        });
當用戶點選取消,則返回false,到原始碼中去阻止事件的繼續執行。


在原始碼2323行左右,執行ajax方法中beforSend,我們在filepredelete中返回false,返回false則再return給beforSend,他就會停止執行ajax方法,從而達到我們的目的。

這種方法確實能實現我們的要求,但是使用原始的confirm難免有些難看,也不符合整個系統的UI。但是使用bootstrap其他的詢問框,則沒辦法實現執行緒暫停機制。但是我們可以在他執行ajax之前去判斷,從而阻止執行。

 解決二:

  更改原始碼2379行左右,當點選刪除按鈕時,呼叫$.ajax(setting)方法之前採用其他bootstrap詢問外掛來監聽,當然你也可以把他封裝成一個內部事件,在初始化fileinput的時候去監聽,



好了,這就是一些簡單的刪除原檔案的方法,其中不乏需要我們去更改原始碼來符合我們的需求。後面使用中還遇到什麼問題,再來研究吧。