Approve or reject list items

I have previously posted a JavaScript solution for approving multiple documents or list items. This is an updated version that adds two buttons in the ribbon: one for “Approve” and one for “Reject”. Refer the original solution for details, but please note that the variables for controlling the text values have changed.

Use this code to load the solution in a list view
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="/Scripts/ApproveOrRejectSelected.js"></script>
Change the default text values

If you are happy with the default, English text, you can skip this next step.

To override the default text, add this to the CEWP below the script reference to “ApproveOrRejectSelected.js”,and change the text as you like:

<script type="text/javascript">
spjs.contentApproval.text = {
	"approveBtn":"Approve selected",
	"rejectBtn":"Reject selected",
	"groupLabel":"Approve or Reject",
	"working":"Processing items...",
	"done":"{0} items processed"
};
</script>

You can wrap it like this to switch based on the logged in users language (in MUI environments):

switch(_spPageContextInfo.currentLanguage){
	case 1044:
		// Add Norwegian values
		spjs.contentApproval.text = {
			"approveBtn":"Approve selected",
			"rejectBtn":"Reject selected",
			"groupLabel":"Approve or Reject",
			"working":"Processing items...",
			"done":"{0} items processed"
		};
	break;
	case 1031:
		// Add German values
		spjs.contentApproval.text = {
			"approveBtn":"Approve selected",
			"rejectBtn":"Reject selected",
			"groupLabel":"Approve or Reject",
			"working":"Processing items...",
			"done":"{0} items processed"
		};
	break;
}
Download ApproveOrRejectSelected.js

Get the file here.

Alexander

20 Comments on “Approve or reject list items

    1. Yes, use this for approve:

      <input type="button" onclick="spjs.contentApproval.toggleApprovelStatus(0);return false;" value="Approve">

      and this for reject:

      <input type="button" onclick="spjs.contentApproval.toggleApprovelStatus(1);return false;" value="Reject">

      You need to add the script file “ApproveOrRejectSelected.js” to the page to be able to use these functions.
      Alexander

      1. Hi Alexander,
        I tried them and it worked great; then I did something that caused it to stop working permanently. I went and changed the column type to a single line of text and then it broke. I have tried to create a new column name and it doesn’t appear to work. I only see a message that says processing items. I also try to put the command in the console and receive no errors. Do you have any idea what could be going on?

        Side note, I have modified the code from the ‘_ModerationStatus’ to ‘_BEStatus’ which is my status column and it is a choice type of column.

        Thanks,
        Eduardo.

    1. My guess is that your _BEStatus field is empty (null), and the script does not check this as the “__ModerationStatus” field would never be empty.

      Go into the code and add a check to see if the value is null – you should see the line number in the dev console.

      Alexander

      1. Hi Alexander,
        I was able to figure out the problem, it appears that if you remove the ‘Title with menu’ column from the view the script will just stay frozen on processing item.

        Thanks,
        Eduardo.

  1. Hi Alex,
    God Morning!

    I need your help!. i think you may know noteboard webpart in sharepoint 2013.it is used for article pages to post the comments.
    now my requirement is to retrive the comments in the page.
    Is it possible to retrive the noteboard webpart comments from the page using javscript/jquery/REST. becuase these comments are stored in contentDB

  2. Great solution! I noticed when you display items in batches, items approved in the first batch will cause the page to refresh. If the user go to the second batch the process runs, but the page does not refresh. Is there a way to force it refresh, so the user will see the changes?

  3. Hi,
    I don’t have this solution installed at the moment so I cannot check it, but I would suspect that the issue is caused by a # in the url preventing the refresh of the page – change this part of the code:

    if(spjs.contentApproval.data.approvedOrRejectedCounter>0){
      // Remove this line
      // location.href = location.href;
      // And replace it with this one
      location.reload();
    }

    Alexander

  4. Greetings Alex,

    Can we make the two individual button with colors ? Approve with Green Code , and Red code for Reject ?

    Appreciated your always help.

  5. I don’t have this solution in use anywhere and haven’t really looked at it since 2015, but I took a look at the js and you should be able to add some styling to the buttons if you look at the code in the file ApproveSelected.js.

    Just locate the approve or reject button code and experiment by adding this to the a-tag or the span-tag of the approve button:

    style='background-color:green;'

    Alexander

    1. thank you Alex for your reply. However, i’m not familiar with coding and i don’t have SP designer. what is the suatblbe script that should i add in the web part for two button ( Approve ) – Reject using this code , since i add it but not working

  6. Thank you Alex I changed what you wrote. Please have a look on it and feed back if its okay to be added in web part editor.

    Thanks.

    var spjs = spjs || {};

    spjs.contentApproval = {
    “localize”:function(){
    if(spjs.contentApproval.text === undefined){
    spjs.contentApproval.text = {
    “approveBtn”:”Approve selected”,
    “rejectBtn”:”Reject selected”,
    “groupLabel”:”Approve or Reject”,
    “working”:”Processing items…”,
    “done”:”{0} items processed”
    };
    }
    },
    “data”:{
    “notifyTimeout”:0,
    “approvedOrRejectedCounter”:0,
    “notifyId”:””
    },
    “init”:function(){
    spjs.contentApproval.localize();
    setTimeout(function(){
    var defaultWP = document.getElementById(“MSOZoneCell_WebPartWPQ1”);
    WpClick({target:defaultWP,srcElement:defaultWP});
    },100);
    setInterval(function(){
    if($(“#RibbonContainer_activeTabId”).val()===’Ribbon.Document’ || $(“#RibbonContainer_activeTabId”).val()===’Ribbon.ListItem’){
    spjs.contentApproval.btn();
    }
    },1000);
    },
    “btn”:function(){
    if($(“#ribbonApproveOrReject”).length===0){
    var b = [];
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    // Approve
    b.push(“”);
    b.push(““);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“” +spjs.contentApproval.text.approveBtn+””);
    b.push(“
    “);
    // Reject
    b.push(““);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“” +spjs.contentApproval.text.rejectBtn+””);
    b.push(“
    “);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    b.push(“”+spjs.contentApproval.text.groupLabel+””);
    b.push(“”);
    b.push(“”);
    b.push(“”);
    setTimeout(function(){
    if($(“#Ribbon\\.Document”).length===1){
    $(“#Ribbon\\.Document”).append(b.join(”));
    }else if($(“#Ribbon\\.ListItem”).length===1){
    $(“#Ribbon\\.ListItem”).append(b.join(”));
    }
    },100);
    }
    setTimeout(function(){
    if(SP.ListOperation.Selection.getSelectedItems().length>0){
    $(“#approveAllButton, #rejectAllButton”).removeClass(‘ms-cui-disabled’);
    }else{
    $(“#approveAllButton, #rejectAllButton”).addClass(‘ms-cui-disabled’);
    }
    },1000);
    },
    “toggleApprovelStatus”:function(val){
    if($(“#approveAllButton”).hasClass(‘ms-cui-disabled’)){
    return;
    }
    spjs.contentApproval.data.approvedOrRejectedCounter = 0;
    spjs.contentApproval.data.notifyId = SP.UI.Notify.addNotification(spjs.contentApproval.text.working, true);
    var cc, web, currLib, selectedItems, index;
    cc = new SP.ClientContext.get_current();
    web = cc.get_web();
    cc.load(web);
    currLib = web.get_lists().getById(SP.ListOperation.Selection.getSelectedList());
    selectedItems = SP.ListOperation.Selection.getSelectedItems();
    if(selectedItems.length>0){
    for(index in selectedItems){
    if(selectedItems[index].fsObjType === ‘0’){
    spjs.contentApproval.checkAndUpdate(cc,currLib,selectedItems[index].id,val);
    }
    }
    }
    },
    “notifyMe”:function(){
    clearTimeout(spjs.contentApproval.data.notifyTimeout);
    spjs.contentApproval.data.notifyTimeout = setTimeout(function(){
    SP.UI.Notify.removeNotification(spjs.contentApproval.data.notifyId);
    spjs.contentApproval.data.notifyId = SP.UI.Notify.addNotification(spjs.contentApproval.text.done.replace(/\{0\}/,spjs.contentApproval.data.approvedOrRejectedCounter), true);
    setTimeout(function(){
    SP.UI.Notify.removeNotification(spjs.contentApproval.data.notifyId);
    if(spjs.contentApproval.data.approvedOrRejectedCounter>0){
    location.href = location.href;
    }
    },1500);
    },1000);
    },
    “checkAndUpdate”:function(cc,currLib,id,val){
    var qb, camlQuery, collListItem;
    qb = [];
    qb.push(“”);
    qb.push(“”+id+””);
    qb.push(“”);
    camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(qb.join(”));
    collListItem = currLib.getItems(camlQuery);
    cc.load(collListItem, “Include(ID,_ModerationStatus)”);
    cc.executeQueryAsync(
    function(sender, args){
    var listEnumerator, curr, status;
    listEnumerator = collListItem.getEnumerator();
    while(listEnumerator.moveNext()){
    curr = listEnumerator.get_current();
    status = curr.get_item(‘_ModerationStatus’);
    if(status !== val){
    spjs.contentApproval.data.approvedOrRejectedCounter ++;
    curr.set_item(‘_ModerationStatus’,val);
    curr.update();
    cc.executeQueryAsync(
    function(sender, args){
    //notifyMe();
    },
    function (sender, args) {
    alert(args.get_message());
    }
    );
    }
    }
    spjs.contentApproval.notifyMe();
    },
    function(sender, args){
    alert(“Error:\n”+args.get_message());
    }
    );
    }
    };

    ExecuteOrDelayUntilScriptLoaded(spjs.contentApproval.init, “sp.ribbon.js”);

  7. The code must be added like described here to work: https://spjsblog.com/2010/01/08/how-to-post-code-in-comments/

    Here is how it should look in your code:

    /* Approve or reject selected items
     * ---------------------------------------------
     * Created by Alexander Bautz
     * alexander.bautz@gmail.com
     * http://sharepointjavascript.wordpress.com
     * Copyright (c) 2012-2015 Alexander Bautz (Licensed under the MIT X11 License)
     * ---------------------------------------------
     * Include reference to:
     *  jquery - http://jquery.com
     * ---------------------------------------------
     * v2.0 - 18.05.2015
    */
    
    /*
    JSLint
    var $, setTimeout, WpClick, setInterval, SP, document, clearTimeout, location, alert, ExecuteOrDelayUntilScriptLoaded;
    */
    
    var spjs = spjs || {};
    
    spjs.contentApproval = {
        "localize": function () {
            if (spjs.contentApproval.text === undefined) {
                spjs.contentApproval.text = {
                    "approveBtn": "Approve selected",
                    "rejectBtn": "Reject selected",
                    "groupLabel": "Approve or Reject",
                    "working": "Processing items...",
                    "done": "{0} items processed"
                };
            }
        },
        "data": {
            "notifyTimeout": 0,
            "approvedOrRejectedCounter": 0,
            "notifyId": ""
        },
        "init": function () {
            spjs.contentApproval.localize();
            setTimeout(function () {
                var defaultWP = document.getElementById("MSOZoneCell_WebPartWPQ1");
                WpClick({ target: defaultWP, srcElement: defaultWP });
            }, 100);
            setInterval(function () {
                if ($("#RibbonContainer_activeTabId").val() === 'Ribbon.Document' || $("#RibbonContainer_activeTabId").val() === 'Ribbon.ListItem') {
                    spjs.contentApproval.btn();
                }
            }, 1000);
        },
        "btn": function () {
            if ($("#ribbonApproveOrReject").length === 0) {
                var b = [];
                b.push("<li id='ribbonApproveOrReject' class=ms-cui-group unselectable='on'>");
                b.push("<SPAN class='ms-cui-groupContainer' unselectable='on'>");
                b.push("<SPAN class='ms-cui-groupBody' unselectable='on'>");
                b.push("<SPAN class='ms-cui-layout' unselectable='on'>");
                b.push("<SPAN class=ms-cui-section unselectable='on'>");
                // Approve
                b.push("<SPAN class=ms-cui-row-onerow unselectable='on'>");
                b.push("<A id='approveAllButton' class='ms-cui-ctl-large ms-cui-disabled' style='background-color: green;' role=button onclick='spjs.contentApproval.toggleApprovelStatus(0);return false;' href='javascript:;' unselectable='on' mscui:controltype='Button'>");
                b.push("<SPAN class='ms-cui-ctl-largeIconContainer' unselectable='on'>");
                b.push("<SPAN class='ms-cui-img-32by32 ms-cui-img-cont-float' unselectable='on'>");
                b.push("<IMG style='TOP: -129px; LEFT: -255px' alt='' src='/_layouts/1033/images/formatmap32x32.png' unselectable='on'>");
                b.push("</SPAN>");
                b.push("</SPAN>");
                b.push("<SPAN class=ms-cui-ctl-largelabel unselectable='on' style='color: white;'>" + spjs.contentApproval.text.approveBtn + "</SPAN>");
                b.push("</A>");
                // Reject
                b.push("<A id='rejectAllButton' class='ms-cui-ctl-large ms-cui-disabled' style='background-color: red;' role=button onclick='spjs.contentApproval.toggleApprovelStatus(1);return false;' href='javascript:;' unselectable='on' mscui:controltype='Button'>");
                b.push("<SPAN class='ms-cui-ctl-largeIconContainer' unselectable='on'>");
                b.push("<SPAN class='ms-cui-img-32by32 ms-cui-img-cont-float' unselectable='on'>");
                b.push("<IMG style='TOP: -0px; LEFT: -0px' alt='' src='/_layouts/1033/images/formatmap32x32.png' unselectable='on'>");
                b.push("</SPAN>");
                b.push("</SPAN>");
                b.push("<SPAN class=ms-cui-ctl-largelabel unselectable='on' style='color: white;'>" + spjs.contentApproval.text.rejectBtn + "</SPAN>");
                b.push("</A>");
                b.push("</SPAN>");
                b.push("</SPAN>");
                b.push("</SPAN>");
                b.push("</SPAN>");
                b.push("<SPAN class='ms-cui-groupTitle' unselectable='on'>" + spjs.contentApproval.text.groupLabel + "</SPAN>");
                b.push("</SPAN>");
                b.push("<SPAN class='ms-cui-groupSeparator' unselectable='on'></SPAN>");
                b.push("</li>");
                setTimeout(function () {
                    if ($("#Ribbon\\.Document").length === 1) {
                        $("#Ribbon\\.Document").append(b.join(''));
                    } else if ($("#Ribbon\\.ListItem").length === 1) {
                        $("#Ribbon\\.ListItem").append(b.join(''));
                    }
                }, 100);
            }
            setTimeout(function () {
                if (SP.ListOperation.Selection.getSelectedItems().length > 0) {
                    $("#approveAllButton, #rejectAllButton").removeClass('ms-cui-disabled');
                } else {
                    $("#approveAllButton, #rejectAllButton").addClass('ms-cui-disabled');
                }
            }, 1000);
        },
        "toggleApprovelStatus": function (val) {
            if ($("#approveAllButton").hasClass('ms-cui-disabled')) {
                return;
            }
            spjs.contentApproval.data.approvedOrRejectedCounter = 0;
            spjs.contentApproval.data.notifyId = SP.UI.Notify.addNotification(spjs.contentApproval.text.working, true);
            var cc, web, currLib, selectedItems, index;
            cc = new SP.ClientContext.get_current();
            web = cc.get_web();
            cc.load(web);
            currLib = web.get_lists().getById(SP.ListOperation.Selection.getSelectedList());
            selectedItems = SP.ListOperation.Selection.getSelectedItems();
            if (selectedItems.length > 0) {
                for (index in selectedItems) {
                    if (selectedItems[index].fsObjType === '0') {
                        spjs.contentApproval.checkAndUpdate(cc, currLib, selectedItems[index].id, val);
                    }
                }
            }
        },
        "notifyMe": function () {
            clearTimeout(spjs.contentApproval.data.notifyTimeout);
            spjs.contentApproval.data.notifyTimeout = setTimeout(function () {
                SP.UI.Notify.removeNotification(spjs.contentApproval.data.notifyId);
                spjs.contentApproval.data.notifyId = SP.UI.Notify.addNotification(spjs.contentApproval.text.done.replace(/\{0\}/, spjs.contentApproval.data.approvedOrRejectedCounter), true);
                setTimeout(function () {
                    SP.UI.Notify.removeNotification(spjs.contentApproval.data.notifyId);
                    if (spjs.contentApproval.data.approvedOrRejectedCounter > 0) {
                        location.href = location.href;
                    }
                }, 1500);
            }, 1000);
        },
        "checkAndUpdate": function (cc, currLib, id, val) {
            var qb, camlQuery, collListItem;
            qb = [];
            qb.push("<View><Query>");
            qb.push("<Where><Eq><FieldRef Name='ID' /><Value Type='Text'>" + id + "</Value></Eq></Where>");
            qb.push("</Query></View>");
            camlQuery = new SP.CamlQuery();
            camlQuery.set_viewXml(qb.join(''));
            collListItem = currLib.getItems(camlQuery);
            cc.load(collListItem, "Include(ID,_ModerationStatus)");
            cc.executeQueryAsync(
                function (sender, args) {
                    var listEnumerator, curr, status;
                    listEnumerator = collListItem.getEnumerator();
                    while (listEnumerator.moveNext()) {
                        curr = listEnumerator.get_current();
                        status = curr.get_item('_ModerationStatus');
                        if (status !== val) {
                            spjs.contentApproval.data.approvedOrRejectedCounter++;
                            curr.set_item('_ModerationStatus', val);
                            curr.update();
                            cc.executeQueryAsync(
                                function (sender, args) {
                                    //notifyMe();
                                },
                                function (sender, args) {
                                    alert(args.get_message());
                                }
                            );
                        }
                    }
                    spjs.contentApproval.notifyMe();
                },
                function (sender, args) {
                    alert("Error:\n" + args.get_message());
                }
            );
        }
    };
    
    ExecuteOrDelayUntilScriptLoaded(spjs.contentApproval.init, "sp.ribbon.js");
      1. Greetings Alex,

        i’ve added the JS file to the SiteAsset, however what should i add in the content editor or Snippet to call this file.

        Thanks.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.