TL;DR
I need a way to prevent the edit form dialog (iframe) from navigating the top window when I click delete on an edit form.
I found this thread the answer given (also detailed in this blog post) relies on adding some code to the masterpage that runs all the time.
I'm looking for a client-side javascript version that doesn't change the behavior for every list, but is able to be applied just to either a specific edit form (via csr or a content/script web part) or added the page that launches the edit form.
Below is more information and a few things I've tried.
Details
I have a list that I'm retrieving items from and displaying using REST api. From my custom interface I'm adding a link that will open the list edit form in a modal window using code like this:
SP.UI.ModalDialog.showModalDialog({
title: 'Edit item',
url: <site url>/_layouts/15/listform.aspx?PageType=6&ID=<itemId>&ListId={<list guid>},
height:550,
dialogReturnValueCallback: function(dialogResult){
if(dialogResult === SP.UI.DialogResult.OK){
// Make a rest call to get the updated values and show them
... and so on
This is working great for updates or if the user clicks cancel, that is to say the modal dialog closes and the calls the callback function where I can check if they clicked save or cancel.
However if the user clicks delete (which they need to do from time to time) the modal dialog closes with no callback and redirects the original (top) page to the default AllItems view for the list. I notice that even in a regular list the same thing happens -- deleting an item doesn't return you to where you were, but rather the default view.
I want to prevent this from happening. I found this post which requires adding the following code to every page via the master page.
var ref = document.referrer; // Stores URL of previous page.
var url = window.location.pathname; // Stores URL of current page.
// The following code will run if the user edits a list item or properties of
// a document.
if (url.indexOf("EditForm.aspx") > -1) {
sessionStorage.setItem("page", ref);
}
if (url.indexOf("AllItems.aspx") > -1
&& ref.indexOf("EditForm.aspx") > -1) {
window.location = sessionStorage.getItem("page");
}
I'd prefer not to have to have to create a custom masterpage. I'd also prefer to not have to have the solution on every page, I'm trying to find a solution that I can perhaps put into a jslink/client-side rendering and have it only on the forms that I want to behave differently than the default. There are many other users of our site who might not want it to change.
I'm specifically annoyed with this behavior when using the modal dialogs -- whether directly from a list that has `List settings>Advanced settings>Launch forms in a dialog?>Yes' or ShowModal as above. Because the modeal/dialog is presented in an iframe that got me thinking about iframe sandboxing and found this thread. I don't know how to change the sandbox properties on the iframe so the accepted solution probably isn't the best.
I also found this solution which uses a custom onbeforeunload
handler to prevent the iframe from navigating the parent. However I don't know what to put for this line which is what prevents the navigation:
console.log("About to navigate that we should stop!");
window.top.location = 'http://server-which-responds-with-204.com/';
If I leave that line out I can see in my debugger that the code around that runs, but the top frame still navigates. If I put something like
window.top.location = window.top.location
I at least stay on the same page, but it reloads. I would like to find a way to not reload the page if I can.
Does anyone know what I should replace the location value with?
Does anybody have a different solution that would work better and only need to be on either the calling page or the specific form that I want to behave this way?