關於在SharePoint 2013(2010)中Javascript如何實現批量批准的自定義操作功能?

dosboy發表於2016-01-11

1.概述:

 SharePoint 2013(包括SharePoint 2010)提供了很方便的,多選的介面,但是很多操作還是不能批量進行,比如:批准的功能。如果您要解決方案不關心程式碼,那麼請直接聯絡作者。如果您對技術感興趣,那麼下面的組合拳就是告訴你如何在2013的Ribbon的工具欄上實現這個小功能,整個實驗必須要有SPD(SharePoint Designer 2013),要使用到Javascript的很多知識。作者完全從實際出發,應對了在這個過程中可能出現的各種各樣的"狀況",比如這個按鈕在多選時可能失效的問題,記住這是一次實戰,不是無用的DEMO。這個功能,作者已經做了可以相容SharePoint 2010的解決方案,解決方案直接可以作為Feature或是網站集功能啟用在所有的列表或是文件庫上,如果有興趣可以留言有償索取。(QQ26959368)

閒言碎語不要講,聽我講一講如何使用Javascript程式碼來實現批量批准的功能。

 

我們要實現的是這麼一個樣子滴,客官請看圖:

 

點選後系統會跳出來一個對話方塊,如下圖:

 

完成操作後,系統會再次重新整理本頁面,您會看到,都已經變成了批准,此處略去1圖。

 

2.使用SPD新增列表自定義操作的按鈕

 

這一步就是讓SharePoint上面的工具欄,多出一個批量稽核的按鈕,如何幹的呢?

1、開啟SharePoint Designer 2013 (如果你沒有安裝這個軟體,可以百度並且下載,這個軟體是免費使用的微軟元件) ,點選"開啟網站",輸入您網站集的URL,如下圖,分別點選"列表和庫"-> "銷售記錄"(可以在您任何的文件庫或是列表庫)->在自定義操作這個欄目下點選"檢視功能區"。

 

2、設定這個操作的名稱為:批量稽核,這個操作型別為:導航至URL,並且寫上這個操作為:javascript:void(0);實際上這個操作的意思就是:什麼也不執行!(因為具體的操作不通過什麼URL來執行,只想通過JS程式碼來執行)

 

其中,還有一個比較重要的屬性就是,圖示,我們做如下的設定,把它設定成SharePoint自帶一個圖示:

 

 

方便大家複製:

標題: 批量稽核
導航至URL: javascript:void(0);
32x32圖示:/_layouts/15/images/SMT_small.png

 

  

這個階段的成果就是形成這個操作選單,並且點選這個按鈕沒有反應(嘿嘿就是要形成這樣的問題)如下圖:

 

 

PS: 對於列表和文件庫, 當我們使用PSD來新增基於"檢視功能區" 的自定義的操作時,所新增的預設區域是不一樣。

看過本文的這個章節,您可以不用看其它任何的關於"自定義操作"的所有文章了。

列表: 在操作一節。(當預設多選的時候,這個按鈕不會"失效")。

文件庫:在管理一節。(當預設多選的時候,這個按鈕 一定會"失效")。

功能區位置的值,如何設定的呢,請開啟包涵功能的原始碼,看看li的屬性,下面一張圖也全搞定了:

 

 

3、修改母版頁,添JS程式

 

3.1 如何修改母版頁:新增Jquery庫

 

繼續開啟,SPD,然後進入下面的介面,選擇母版頁-> seattle.master,雙擊開啟並編輯:

 

當然了,如果你的網站已經開啟了"釋出"功能,那麼修改的就不是.master檔案而是.html檔案,但是修改的地方和程式碼是一樣一樣滴。

開啟了之後,我覺得把Jquery庫和自定義程式碼的放在哪裡好呢, 我個人建議可以放在</body>前面,如下圖:

 

上一個框,就是我們要複製進去的部分內容,下一個框是給您定位用的,您可以在你的母版頁中找得到,要複製程式碼看後面有全面程式碼。

 

3.2 新增按鈕Click事件(解決按鈕變灰不能用的問題)

 

因為在第2步的SPD自定義的操作中,SPD沒有辦法設定這個操作適用多個項還是單個項。這會造成:所有在文件庫中自定義的按鈕,當您選擇多個項時,按鈕會變得"灰"- 即是失效的狀態。

所以我們要用一個定時器函式,每1秒就把這個按鈕設定成啟用的樣子,這樣很"粗暴"地解決這個問題,當然這個問題有更好的解決辦法,您可以繼續去分析:

當單擊了專案的選擇框後,到底SharePoint內部的JS庫執行了什麼函式,然後去改進這個粗暴地設計,不過作者已經很不耐煩了,對於SharePoint你只能這樣,有時候。

這個程式碼就是這樣,加在上一個圖的2個框框之間:

 

 1 <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
 2 
 3 <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
 4 
 5 <script>
 6 
 7 $(document).ready(function (){
 8 
 9  
10 
11 //因為在自定義的操作中,SPD沒有辦法設定這個操作適用多個項還是單個項,所有在文件庫,當您選擇多個項時,按鈕會變得"灰"- 即是失效的狀態。
12 
13 //所以我們要用這個函式,每1秒就把這個按鈕設定成啟用的樣子
14 
15 setInterval(function (){
16 
17  
18 
19 //找到這個"自定義操作"的按鈕是一個包括了您剛才定義的標題的span標記的上級A標記
20 
21 var buttonModeration = $("a:has(span:contains('批量稽核'))");
22 
23  
24 
25 if(buttonModeration.length>0){
26 
27  
28 
29 buttonModeration.removeClass("ms-cui-disabled"); //取消失效的樣式設定
30 
31 buttonModeration.removeAttr("aria-disabled"); //取消失效的標誌
32 
33 buttonModeration.find(">span").attr("onclick","dosboyAllPass(this);");//把這個按鈕的 onclick事件換成我們自己定義的: dosboyAllPass()函式
34 
35 }
36 
37  
38 
39 },1000);
40 
41  
42 
43 });
44 
45 </script>

 

以上程式碼無需複製,下面有更詳細的程式碼。

 

程式碼中間,我們第33行有一個自定義函式,就是告訴瀏覽器,當使用者點選這個按鈕時,我們要執行的函式是:dosboyAllPass()。

如果你要處理的不是文件庫而是列表庫,那麼多選狀態下按鈕變灰的問題,是不存在的可以通過如下的方式把按鈕click事件新增上:

在3.1這個步驟裡,我們不輸入Javascript:void(0); 直接輸入Javascript:dosboyAllPass(); 那麼這一節的程式碼完全是不需要的羅。

 

3.3 新增批量處理JS程式

 

到現在,我們已經完成所有準備的動作, 只要完成一個實際的批量稽核的JS函式dosboyAllPass就行了,對於急於進行部署的同學其實我們只需要把如下的程式碼全部新增進當前的母版頁,就行了:

所有的程式碼,都已經加了註釋,如果您想學習就去學習吧,其中涉及了很重的內容,如何判定一個table是不是SharePoint的列表,如何判定一行是不是已經被選中。

<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
$(document).ready(function (){

    //因為在自定義的操作中,SPD沒有辦法設定這個操作適用多個項還是單個項,所有在文件庫,當您選擇多個項時,按鈕會變得“灰”- 即是失效的狀態。
    //所以我們要用這個函式,每1秒就把這個按鈕設定成啟用的樣子
    setInterval(function (){
    
    //找到這個“自定義操作”的按鈕 是一個包括了您剛才定義的標題的span標記的上級A標記
    var buttonModeration = $("a:has(span:contains('批量稽核'))"); 
    
    if(buttonModeration.length>0){
        
        buttonModeration.removeClass("ms-cui-disabled"); //取消失效的樣式設定
        buttonModeration.removeAttr("aria-disabled"); //取消失效的標誌
        
        buttonModeration.find(">span").attr("onclick","dosboyAllPass(this);");//把這個按鈕的 onclick事件換成我們自己定義的: dosboyAllPass()函式
        
    
    }
    
    
    },1000);
    
});



// 本函式是讓“未批准”,這個介面已選的新聞批量地通過稽核。
function dosboyAllPass(){
try 
{

    var listviewTable = $(".ms-listviewtable:eq(0)")[0]; //當頁面中有SharePoint的列表時,這個列表一定會使用ms-listviewtable這個類作為CSS樣式
    if(listviewTable!=undefined &&  $(listviewTable).find("tr div[aria-checked='true']").length>0){
    //當表格中的一行tr有aria-checked='true'這個div時,我們就認為這一行已經被選中拉!
    if(confirm("您選擇了" + $(listviewTable).find("tr div[aria-checked='true']").length + "個項,確認同時稽核通過嘛?")){
    
        $(listviewTable).find("tr:has(div[aria-checked='true'])").each(function () {        
                
                var itemid= $(this).attr("id").split(',')[1]; //得到當前列表專案的id值
                   var ctx = new SP.ClientContext.get_current(); //得到ClientContext
                var listTitle = $(listviewTable).attr("summary"); //從tr的summary屬性的值可以得當前列表的:名稱
                var oList = ctx.get_web().get_lists().getByTitle(listTitle);
                    this.oListItem = oList.getItemById(itemid);         
        
                var appStatus = "";
                ctx.load(this.oListItem);

                ctx.executeQueryAsync(Function.createDelegate(this, function () {  
                                           //取得審批狀態
                                                   appStatus = this.oListItem.get_item('_ModerationStatus');     //審批這個欄位在列表的內部名稱為:_ModerationStatus                                        
                                                    this.oListItem.set_item('_ModerationStatus', 0); //設定審批狀態,為0-審批 1-拒絕 2-未定
                                                       this.oListItem.update();            
                                             ctx.executeQueryAsync(function(){
                                                           setTimeout(function (){window.location.href=window.location.href;},1000); //重新整理當前列表                                                    
                                                    },function (){                                                    
                                                        setTimeout(function (){window.location.href=window.location.href;},1000); //重新整理當前列表                                                    
                                                    });                                                    
                                                    
                                                    
                                }),function(e){
                                  alert('Error:' + e.message);
                                      setTimeout(function (){window.location.href=window.location.href;},1000); //重新整理當前列表                                                    
                                }); 
        
        

    
                    

                });


    
    }

}


}



catch(eee){
     alert('Error' + eee.message);
}

}


</script>
 

3.4 總結:方案可以進行重複使用

 

各位可能已經看出來,我的程式碼裡面沒有涉及任何的特別列表和庫的名稱,或是其它什麼特定的東西。

如果各位客官已經完成上面 3.3步驟,那麼你就可以,通過不斷地給其它列表(庫)重複本文章中的第2個步驟來不斷嘀給任何一個列表新增批量稽核的功能。

對於喜歡愛學習的人,上面的程式碼,有幾個關鍵的技術需要掌握。

 

4.相關JS開發知識

 

4.1 如何使用JS來更新列表的審批狀態

 

如何使用JS來操作網站資料,我們完全看這麼一篇文章就夠了:

Complete basic operations using JavaScript library code in SharePoint 2013

https://msdn.microsoft.com/en-us/library/office/jj163201.aspx

在示例中,以下的程式碼可以更新一個列表的,標題和內容為:My New Item!和Hello World!

 

function createListItem(siteUrl) {

var clientContext = new SP.ClientContext(siteUrl);

var oList = clientContext.get_web().get_lists().getByTitle('Announcements');

 

var itemCreateInfo = new SP.ListItemCreationInformation();

this.oListItem = oList.addItem(itemCreateInfo);

oListItem.set_item('Title', 'My New Item!');

oListItem.set_item('Body', 'Hello World!');

oListItem.update();

 

clientContext.load(oListItem);

clientContext.executeQueryAsync(

Function.createDelegate(this, this.onQuerySucceeded),

Function.createDelegate(this, this.onQueryFailed)

);

}

 

function onQuerySucceeded() {

alert('Item created: ' + oListItem.get_id());

}

 

function onQueryFailed(sender, args) {

alert('Request failed. ' + args.get_message() +

'\n' + args.get_stackTrace());

}

 

我們只需要把紅色的部分換成 _ModerationStatus ,這個值設定成:

 

0 - 審批

1 - 拒絕

2 - 未定

 

4.2 如何在頁面上獲得已選項的ID、列表標題等資訊

 

那麼剩下的問題就是如何在介面上獲得已經check的那項的ID呢?

經過對程式碼的研究發現,其實每一個項就是一個<tr></tr>,即HTML元素中Table中的一行:

而且列表總是展示在,這個類名的Table下的:ms-listviewtable

Table 有一個屬性叫summary就是列表的標題,

Tr中有一個屬性叫 iid id,就是列表項的ID,所有問題如下圖,全然解決:

 

5總結:

 

本文提供了一個綜合的批量稽核的解決方案,並展示了這個批量稽核解決方案開發的所有的技術,拋磚引玉地使用了JS來完成大部分操作。

當然最終的解決方案作者提供的是相容SharePoint 2010的一鍵式解決方案,有稽核也有拒絕。

如果大家需要這個解決方案,請給本文留言,或是留下你的電子郵件,作者會把解決方案發到您的郵箱當中。

如果留言比較多,我會考慮把這個解決方案在下週的博文中公佈。

相關文章