0
votes

I want to perform some validation when a user click the save button on the SharePoint ribbon and cancel the submission of the form if it is not valid.

I am using a page layout in SharePoint 2013. The fields come from the page layout content type.

The id of the button is Ribbon.EditingTools.CPEditTab.EditAndCheckout.SaveEdit-SelectedItem

I tried without success:

  • add an onclick handler on the button

    var saveButton = function () {
        return document.getElementById("Ribbon.EditingTools.CPEditTab.EditAndCheckout.SaveEdit-SelectedItem");
    }
    $(saveButton()).removeAttr("onclick");
    $(saveButton()).click(
        function(ev){
            ev.preventDefault();
            ev.returnvalue=false; // for IE only
            return false;
        }
    );
    
  • replace the onsubmit attribute of the form

    $("form").attr("onsubmit","javascript: return false;")
    

Both codes are happily ignored by sp2013!

2
If we are talking about standard SharePoint list forms then there is built in PreSaveAction function. Check this post hannanazam.blogspot.com/2013/04/…Yevgeniy.Chernobrivets

2 Answers

1
votes

To cancel the event, instead of targeting the link, I have targeted the img inside the link. My javascript code is then fired before the SharePoint javascript.

$("#Ribbon\\.EditingTools\\.CPEditTab\\.EditAndCheckout\\.SaveEdit-SelectedItem img").click(function(){
    console.log("saveButton clicked");
    return false;
});

The double antislashes are meant to tell jquery this is no class name but a dot in the id.

Another problem arised: the save button can take a few seconds to load, so we have to wait before attaching the click handler. Finally the code is like this:

//namespace
var qp = {}
// attaching a click handler to the save button image
qp.registerSaveButtonEvent = function() {
    var b = "#Ribbon\\.EditingTools\\.CPEditTab\\.EditAndCheckout\\.SaveEdit-SelectedItem img";
    // if the button exists
    if ($(b).length > 0) {
        // we attach the click handler to it
        $(b).click(function(){
            console.log("saveButton clicked");
            return false;
        });
        // we stop the future calls of this function
        clearInterval(qp.interval);
    }
}
// Running the function every 500 ms
qp.interval = setInterval(qp.registerSaveButtonEvent, 500);
1
votes

In order to override a button in the ribbon you must be sure that:

  1. The button is loaded

    On this matter Sharepoint 2013 and 2010 require a slight different code. According to the blog post SharePoint 2013: Trigger Event With Ribbon Tab Changes you need to fire an event and process it in your code. For Sharepoint 2010 check Trigger an event whenever the SharePoint 2010 ribbon changes .

  2. All the events attached to the button are intercepted.

    I noticed that not only click event is used by Sharepoint but even the mousedown, so it's better to include both in the new event handler. You would add a class to avoid multiple handlers to be attached. I suggest to use the container because otherwise if user click in the surrounding area the standard event handler is fired. Indeed the only safe way to remove all the handlers is to clone the element and replace it with its clone.

So this is the code I finally assembled:

// 1) Fires 'ribbontabselected' every time the ribbon selection changes
ExecuteOrDelayUntilScriptLoaded(function () {

  // Sometime this function is called twice on IE, don't ask why...
  // So better safe than sorry.
  if (typeof CUI.Ribbon.prototype.$1q_0_old == 'undefined') {
    CUI.Ribbon.prototype.$1q_0_old = CUI.Ribbon.prototype.$1q_0;
  }
  
  CUI.Ribbon.prototype.$1q_0 = function () {
    this.$1q_0_old();
    $(document).trigger('ribbontabselected', [this.get_selectedTabCommand()]);
  };
}, 'cui.js');

// 2) Fires 'ribbontabselected' after the ribbon has been initialized after load
ExecuteOrDelayUntilScriptLoaded(function () {
  var pm = SP.Ribbon.PageManager.get_instance();
  pm.add_ribbonInited(function () {
    $(document).trigger('ribbontabselected', [SP.Ribbon.PageManager.get_instance().get_ribbon().get_selectedTabCommand()]);
  });
}, 'sp.ribbon.js');

// Identify the button (use the container as selector)
// Double antislashes to tell jquery this is no class name but a dot in the id
var sharepointExcelButtonHandler = 'a#Ribbon\\.List\\.Actions\\.ExportToSpreadsheet-Large';

// 3. Modify command button
$(document).on('ribbontabselected', function (e, selectedTabCommand) {

  if (selectedTabCommand == 'ListTab' && $(sharepointExcelButtonHandler).length > 0) {
    if (! $(sharepointExcelButtonHandler).hasClass("DIST-excel-download-processed")) {

      // The only safe way to remove all previous handlers is to replece the element with a clone
      $(sharepointExcelButtonHandler)
       .replaceWith($(sharepointExcelButtonHandler).clone());

      // Add new handlers
      $(sharepointExcelButtonHandler)
        .addClass("DIST-excel-download-processed")
        .on("mousedown click", function(e) {
          console.log("Do your stuff");
          return false;
        });
    }
  }
});