Javascript SharePoint 2013-功能区中的“保存”按钮-如果表单无效,则取消保存

Javascript SharePoint 2013-功能区中的“保存”按钮-如果表单无效,则取消保存,javascript,jquery,forms,sharepoint,sharepoint-2013,Javascript,Jquery,Forms,Sharepoint,Sharepoint 2013,我想在用户单击SharePoint功能区上的“保存”按钮时执行一些验证,如果表单无效,则取消表单提交 我正在SharePoint 2013中使用页面布局。这些字段来自页面布局内容类型 按钮的id是Ribbon.EditingTools.CPEditTab.EditAndCheckout.SaveEdit SelectedItem 我试过但没有成功: 在按钮上添加onclick处理程序 var saveButton = function () { return document.getE

我想在用户单击SharePoint功能区上的“保存”按钮时执行一些验证,如果表单无效,则取消表单提交

我正在SharePoint 2013中使用页面布局。这些字段来自页面布局内容类型

按钮的id是Ribbon.EditingTools.CPEditTab.EditAndCheckout.SaveEdit SelectedItem

我试过但没有成功:

  • 在按钮上添加onclick处理程序

    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;
        }
    );
    
  • 替换表单的onsubmit属性

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

sp2013很高兴地忽略了这两个代码

为了取消该事件,我没有瞄准链接,而是瞄准了链接内的img。然后,我的javascript代码在SharePoint javascript之前被激发

$("#Ribbon\\.EditingTools\\.CPEditTab\\.EditAndCheckout\\.SaveEdit-SelectedItem img").click(function(){
    console.log("saveButton clicked");
    return false;
});
双重反斜杠的意思是告诉jquery这不是类名,而是id中的一个点

出现了另一个问题:save按钮可能需要几秒钟的时间来加载,因此我们必须等待,然后才能附加click处理程序。最后,代码如下所示:

//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);

为了取消活动,我没有瞄准链接,而是瞄准了链接内的img。然后,我的javascript代码在SharePoint javascript之前被激发

$("#Ribbon\\.EditingTools\\.CPEditTab\\.EditAndCheckout\\.SaveEdit-SelectedItem img").click(function(){
    console.log("saveButton clicked");
    return false;
});
双重反斜杠的意思是告诉jquery这不是类名,而是id中的一个点

出现了另一个问题:save按钮可能需要几秒钟的时间来加载,因此我们必须等待,然后才能附加click处理程序。最后,代码如下所示:

//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);

要替代功能区中的按钮,必须确保:

  • 按钮已加载

    在这个问题上,Sharepoint 2013和2010需要稍微不同的代码。 根据博客文章,您需要触发事件并在代码中处理它。对于Sharepoint 2010,请检查

  • 所有附加到按钮的事件都被截获

    我注意到Sharepoint不仅使用了
    单击
    事件,甚至还使用了
    鼠标向下
    ,因此最好在新的事件处理程序中同时包含这两个事件。您可以添加一个类以避免附加多个处理程序。我建议使用容器,因为如果用户在周围区域单击,则会触发标准事件处理程序。 实际上,唯一安全的方法是克隆元素并用其克隆替换它

  • 这就是我最终汇编的代码:

    // 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;
            });
        }
      }
    });
    

    要替代功能区中的按钮,必须确保:

  • 按钮已加载

    在这个问题上,Sharepoint 2013和2010需要稍微不同的代码。 根据博客文章,您需要触发事件并在代码中处理它。对于Sharepoint 2010,请检查

  • 所有附加到按钮的事件都被截获

    我注意到Sharepoint不仅使用了
    单击
    事件,甚至还使用了
    鼠标向下
    ,因此最好在新的事件处理程序中同时包含这两个事件。您可以添加一个类以避免附加多个处理程序。我建议使用容器,因为如果用户在周围区域单击,则会触发标准事件处理程序。 实际上,唯一安全的方法是克隆元素并用其克隆替换它

  • 这就是我最终汇编的代码:

    // 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;
            });
        }
      }
    });
    

    如果我们谈论的是标准的SharePoint列表表单,那么就有内置的预保存功能。检查这篇文章,如果我们谈论的是标准的SharePoint列表表单,那么就有内置的预保存功能。查看此帖子