Im hoping this is an easy answer as Im sure it must be, but my mind has gone blank!

Basically I have created a button to run some javascript code to fire a custom (manual) workflow on an item that is selected in a Document Library (or List)

I have set the ribbon button to only be active IF one item is selected in the Library but what I want now is to only activate the ribbon button if one item is selected AND IF a specific field in the item = 'Yes' (The field in this case being called 'DraftDoc' [Choice field]).

Ive tried a few methods but none seem to work and VS2012 errors on debugging.

My code to enable the button so far is:

    // Method to enable/disable the button on the ribbon. 

       function EnableSubmitDraftDocument() {

    // request number of selected items. 

       var items = SP.ListOperation.Selection.getSelectedItems();

       var count = CountDictionary(items);

    // only return true is a single item is selected. 

       return (count == 1);


Can anyone help me with the extra code I need?



Maybe I should have included the full script in my post. I was initially only thinking Id need to add something to my function that Id pasted. Sorry for that. Here is the full script I have so far:

  // This method will contain most of the code needed to request the unique url to the  document
function SubmitDraftDocument() {
    // First get the context and web
    var ctx = SP.ClientContext.get_current();
    this.web = ctx.get_web();
    // Get the current selected list, then load the list using the getById method of Web (SPWeb)
    var listId = SP.ListOperation.Selection.getSelectedList();
    var sdlist = this.web.get_lists().getById(listId);
    // Get the currently selected item of the list. This will return a dicustonary with an id field
    var items = SP.ListOperation.Selection.getSelectedItems(ctx);
    var mijnid = items[0];
    // Request the list item from the server using the getItemById method. This will load all properties.   
    // If needed, one could pre-request the fields to be loaded to preserve bandwidth.
    this.listItem = sdlist.getItemById(mijnid.id);
    // load the item in the context for batch operation.
    //Execute the actual script on the server side. Specify delegates to handle the response. 
    ctx.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));

// Delegate that is called when server operation is complete upon success.
function onQuerySucceeded(sender, args) {
    // Request the ID of the Document. 
    var DocumentID = this.listItem.get_item('ID');
    // Open the Custom Manual Workflow page with parsed metadata in URL.
    window.open('/sites/policies/_layouts/IniWrkflIP.aspx?List={ce7dcd6e-796b-491f-a6cb-6868554ce1cf}&ID=' + DocumentID + '&TemplateID={ff024ae0-071a-49a5-96d7-7bf08bc96b04}&Source=/sites/policies/PoliciesProcedures/Forms/QuickSearch.aspx', "_self");

// Delegate that is called when server operation is completed with errors.
function onQueryFailed(sender, args) {
    alert('failed ' + args.toString());

// Method to enable/disable the button on the ribbon. 
function EnableSubmitDraftDocument() {
    // request number of selected items. 
    var items = SP.ListOperation.Selection.getSelectedItems();
    var count = CountDictionary(items);
    // only return true is a single item is selected. 
    return (count == 1);

2 Answers 2


You must get selected items as you mention in your code and then on success function get the value of your field and check it. Example:

var currentItem;
function getItemById() {
    var context = new SP.ClientContext.get_current();
    var item = SP.ListOperation.Selection.getSelectedItems(context);
        currentItem = currentLib.getItemById(item[0].id);
        context.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
function onQuerySucceeded() {
    var draftDocValue = currentItem.get_item('DraftDoc'));
        if(draftDocValue == 'True'){
    //run your workflow code    
function onQueryFailed(sender, args) {
    alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());

When working with ribbon buttons one should be aware of RefreshCommandUI method. This function causes the Ribbon to refresh and EnableScript functions get called on the ribbon buttons. Because of the asynchronous behavior of ECMA script, the first time the code in the onQuerySucceeded() method exeutes, it may not have intended results in it. As far as your issue is concerned, following code may be of help to you:

function enableTaskNotCompletedButton() {
    var result = false;//default return value of the function which disables the button

    var selectedItems = SP.ListOperation.Selection.getSelectedItems();
    //check if exactly one item is selected
    if (CountDictionary(selectedItems) == 1) {
        if (this.itemId != selectedItems[0]['id']) {
            this.itemId = selectedItems[0]['id'];
        else if (this.StatusValue == "Completed") {
            result = false; //can be omitted, just for readibility
        //when RefreshCommandUI() makes the EnabledScript fire again, none of the above checks are valid
        //when the Status is not equal to Completed and the stored itemId is the same as the selected item id
        else if (this.StatusValue != "Completed" && this.itemId == selectedItems[0]['id']) {
            result = true;

    return result;
function GetTaskStatus(itemId) {
    var clientContext = SP.ClientContext.get_current();
    var currentList = clientContext.get_web().get_lists().getById(SP.ListOperation.Selection.getSelectedList());
    this.singleItem = currentList.getItemById(itemId);

    clientContext.load(this.singleItem, 'Status');
    clientContext.executeQueryAsync(Function.createDelegate(this, this.OnSucceeded), Function.createDelegate(this, this.OnFailed));

function OnSucceeded() {
    this.StatusValue = this.singleItem.get_item('Status');

function OnFailed(sender, args) {
    alert('Error occurred: ' + args.get_message());

Please see below link for more detail:


  • Thanks Nadeem. I think I should have added all of my code though when I wrote the question. I think you have got what I need, I just need to work out how to incorporate it into what I already have! If you could check again and help me out a little? Commented Jan 6, 2014 at 16:42
  • Using your code I can get the ribbon item to highlight when the correct item is selected, but my command doesnt execute! Commented Jan 7, 2014 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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