Submit SharePoint 2013 form with custom Save button in Typescript
-
29-01-2021 - |
문제
I've been searching on this issue for a few days now. We use JSLink to add an extra Save button to a New or Edit form. So each form has 3 buttons:
- Cancel -> cancel the form
- Save -> (Temporary) Save the form without validation
- Submit -> Validate the form and save it
The submit button allows async validation. The validation itself works without issues, but when everything is valid, I want the form to submit. That's when the troubles start. I've done alot of research and tried different approaches:
// original code
export function saveAndCloseForm(): any {
const saveButton = (FormHelper.getSPOriginalSaveButton() as HTMLButtonElement);
if (!PreSaveItem()) { return false; }
if (SPClientForms.ClientFormManager.SubmitClientForm("WPQ2")) { return false; }
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(saveButton.name, "", true, "", "", false, true));
}
Chrome
Works as intended
Internet Explorer
When clicking the Submit button, the Save button is set disabled. This because SubmitClientForm returns false which stops the saveAndCloseForm function. If I remove the return like this:
//modified code
export function saveAndCloseForm(): any {
const saveButton = (FormHelper.getSPOriginalSaveButton() as HTMLButtonElement);
// if (!PreSaveItem()) { return false; }
SPClientForms.ClientFormManager.SubmitClientForm("WPQ2");
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions(saveButton.name, "", true, "", "", false, true));
}
Internet Explorer throws the following error:
Accessing the 'caller' property of a function or arguments object is not allowed in strict mode
FireFox
Basicly the same error:
access to strict mode caller function is censored
I want to try to avoid using .click() and purely do it through code. Is there anyone that got this to work with TypeScript for all browsers? Thanks in advance
해결책
Seems I was looking in the wrong place. It looks like there is a problem in Microsoft Ajax not working with 'use strict' mode. I had to use a _doPostBack hack in order for it to work, based on this question: SharePoint 2013: Access to strict mode caller function is censored
I had to adjust it a bit for our case use and I don't have the PreSaveItem() working yet, but atleast it is submitting/saving in all browsers now.
Snippet:
export function hackEventWithinDoPostBack() {
const originalEventDescriptor = Object.getOwnPropertyDescriptor(Window.prototype, "event");
let hackEventVariable = false;
let eventPropertyHolder: any;
Object.defineProperty(window, "event", {
configurable: true,
get: function get() {
hackEventVariable = true; // override the hack boolean
const result = originalEventDescriptor ? originalEventDescriptor.get!.apply(this, arguments) : eventPropertyHolder;
if (result || !hackEventVariable) {
return result;
}
return {};
},
set: function set(value) {
if (originalEventDescriptor) {
originalEventDescriptor.set!.apply(this, arguments);
} else {
eventPropertyHolder = value;
}
},
});
// below is probably obsolete in this use case
const originalDoPostBack = window.__doPostBack;
window.__doPostBack = function hackedDoPostBack() {
hackEventVariable = true;
originalDoPostBack.apply(this, arguments);
hackEventVariable = false;
};
}