0

So i have created a new button called "Closed" using SPD 2013, and using "Communaction site", inside this site i have a list of type Default experience. The button location is "View Ribbon" and i manage a workflow to this button to update the status column to closed.

The problem is when i select more then 1 item, the button disappear from the ribbon so i can only select 1 item, so how can i enable the multiple selection for this button ?

Button Action

Thank you !

1

Add the code below to a text file and rename it myScript.html and save it. Upload this file to SiteAssets library. Now go to list view page and click edit page. Add a web part called "Content Editor Web Part". Now put the link to the file in the link property in edit web part. Now perform your actions. It worked as expected for me.

<script language="javascript" type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>  
<script language="javascript" type="text/javascript">  
_spBodyOnLoadFunctionNames.push("AddCustomUserActionToRibbon");

function AddCustomUserActionToRibbon(){
    SP.SOD.executeOrDelayUntilScriptLoaded(AddCustomUserAction, "sp.js"); 
} 
var oListItem;  
function AddCustomUserAction() {  
    //Get the client context and list object  
    var context = new SP.ClientContext.get_current();  
    var list = context.get_web().get_lists().getByTitle("Clients");  
    list.get_userCustomActions().clear();
    //Get the custom user action collection and add the user action  
    var customUserAction = list.get_userCustomActions().add();  
    //Set the location of the user action  
    customUserAction.set_location('CommandUI.Ribbon.ListView');  
    //Add the properties for the custom action  
    var userActionExtension = '<CommandUIExtension xmlns="http://schemas.microsoft.com/sharepoint/">' + '<CommandUIDefinitions>' + '<CommandUIDefinition Location="Ribbon.ListItem.Actions.Controls._children">' + '<Button Id="DannyJessee.MarkItemsFinishedButton" ' + 'Command="cmdMarkItemsFinished" ' + 'Sequence="0" ' + 'Image16by16="/_layouts/images/kpinormallarge-0.gif" ' + 'Image32by32="/_layouts/images/kpinormallarge-0.gif" ' + 'Description="Mark as Finished" ' + 'LabelText="Mark as Finished" ' + 'TemplateAlias="o2"/>' + '</CommandUIDefinition>' + '</CommandUIDefinitions>' + '<CommandUIHandlers>' + '<CommandUIHandler Command="cmdMarkItemsFinished" ' + 'CommandAction="javascript:MarkItemsFinished();" EnabledScript="javascript:EnableFinishedButton();" />' + '</CommandUIHandlers>' + '</CommandUIExtension>';  
    //Add the command UI extension and update the custom user action  
    customUserAction.set_commandUIExtension(userActionExtension)  
    customUserAction.update();  
    //Load the client context and execute the batch  
    context.load(list, 'UserCustomActions');  
    context.executeQueryAsync(function() {  
        console.log("Custom User Action added successfully to ribbon.");  
    }, function(sender, args) {  
        console.log(args.get_message());  
    });  
}

function EnableFinishedButton() {
    var context = SP.ClientContext.get_current();
    var list;
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
    var totalSelectedItems = selectedItems.length;

    if (totalSelectedItems > 0) {
        var web = context.get_web();
        context.load(web);
        var listId = SP.ListOperation.Selection.getSelectedList();
        list = web.get_lists().getById(listId);

        // We will use this variable to determine whether EnableFinishedButton() is being called directly or by RefreshCommandUI()
        var hadToMakeCall = false;

        if (typeof this.itemRows == "undefined" || this.itemRows.length != totalSelectedItems) {
            // This will be true if this is the first time an item has been selected in the list OR if the selected items have changed, forcing the need to check again
            hadToMakeCall = true;
            GetItemsStatus();
        }

        // If we just issued the async call, do not enable the button yet
        if (hadToMakeCall) {
            return false;
        }
        else {
            // Once the call has returned, set the enabled status based on the returned value
            return this._can_be_enabled;
        }
    }
    else {
        this.itemRows = undefined;
        return false;
    }
    function GetItemsStatus() {
        // Store the selected list items in an array where their values can be checked
        itemRows = [];

        for (i in selectedItems) {
            itemRows[i] = list.getItemById(selectedItems[i].id);
            context.load(itemRows[i]);
        }

        context.executeQueryAsync(Function.createDelegate(this, onGetItemsSuccess), Function.createDelegate(this, onGetItemsQueryFailed));
    }

    function onGetItemsSuccess() {
        this._can_be_enabled = true;

        // Iterate through all selected items. If one is false, the value of _can_be_enabled will be false and the button will not be enabled
        for (i in itemRows) {
            //this._can_be_enabled = this._can_be_enabled && itemRows[i].get_item("Status") == "In Progress";

            if((this._can_be_enabled && itemRows[i].get_item("Status") == "Pending") || (this._can_be_enabled && itemRows[i].get_item("Status") == "Approved")){
                this._can_be_enabled = true; 
            }
            else{
                this._can_be_enabled = false;
            }
        }

        // Now we can call the EnabledScript function again
        RefreshCommandUI();
    }

    function onGetItemsQueryFailed(sender, args) {
        alert(args.get_message());
    }
}
function MarkItemsFinished() {
    var context = SP.ClientContext.get_current();
    var web = context.get_web();
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
    var listId = SP.ListOperation.Selection.getSelectedList();
    var list = web.get_lists().getById(listId);
    var i;
    for (i in selectedItems) {
        // Update the "Status" field of each selected item to have a value of "Finished"
        var listItem = list.getItemById(selectedItems[i].id);
        listItem.set_item("Status", "Finished");
        listItem.update();
    }
    context.executeQueryAsync(Function.createDelegate(this, onUpdateItemsSuccess), Function.createDelegate(this, onUpdateItemsFailed));

    function onUpdateItemsSuccess() {
        alert("Items updated!");
    }

    function onUpdateItemsFailed(sender, args) {
        alert(args.get_message());
    }
}   
</script>

Check the screenshot below. the button will be activated only if status column has a value "In Progress" enter image description here

As far as I know, running workflows using custom actions is possile for 1 item only. You can check this article and try adding the script.

  • Doesn't work i replace it with var totalSelectedItems = selectedItems.length; In my console i get 2 errors: VM176:1 Uncaught ReferenceError: EnableFinishedButton is not defined and MarkItemsFinished is not defined @harshal gite – SmithBZ Sep 5 at 16:05
  • Put a breakpoint in browser debugger on the line selectedItems.length and when debugger arrives there, just write selectedItems in console and check take a scteenshot of that result and add it here please – harshal gite Sep 5 at 16:08
  • Its not a file to find it in a source to put a breakpoint because i add it by adding a web part then inside script editor i paste my code. Anyway this is my sources files: i.imgur.com/K970BlI.png @harshal gite – SmithBZ Sep 5 at 16:20
  • 1
    Try the updated code – harshal gite Sep 9 at 19:02
  • 1
    Put else below it and make it false – harshal gite Sep 9 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.